一文带你轻松入门Xposed框架,编写Xposed模块

欢迎访问姊妹篇:一文带你轻松入门Frida框架,编写Hook脚本

0x1 Xposed框架简介

Xposed框架在Hook界可谓无人不知无人不晓,是用于Android系统中,Hook App函数的一个重要框架。其原理是,通过替换/system/bin/app_process程序,控制Zygote进程,使得app_process加载XposedBridge.jar,从而可以劫持Zygote进程及其创建的虚拟机。其中比较重要的一点是,Xposed对Android系统本身的要求较高,Android系统的版本,以及国内厂商定制的版本都会影响其安装。 目前,官方支持Android 8.0及以下版本。

0x11 Xposed的安装

Xposed安装方法有多种,在这里介绍最简单的一种,即通过安装器来安装。在官网下载 Xposed Installer
在这里插入图片描述
选择图中的apk,下载到手机上即可。打开该安装器,app会自动选择一个合适的版本,下载安装即可。
在这里插入图片描述
安装完成之后,重启手机,即可完成Xposed框架的安装。

0x12 Android Studio新建一个用于Hook的Demo

假设我们的包名设为com.lys.demoapplication

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                AlertDialog.Builder alertDialog = new AlertDialog.Builder(MainActivity.this);
                alertDialog.setTitle("弹框");
                alertDialog.setMessage(getString());
                alertDialog.setCancelable(false);
                alertDialog.setPositiveButton("OK", new DialogInterface.OnClickListener()	{
                    @Override
                    public void onClick(DialogInterface	dialog, int	which)	{
                    }
                });
                alertDialog.setNegativeButton("CANCEL", new DialogInterface.OnClickListener()	{
                    @Override
                    public void onClick(DialogInterface	dialog, int	which)	{
                    }
                });
                alertDialog.show();

            }
        });
    }

    private String getString(){
        return "未被hook,我是原始函数";
    }
}

布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="弹框"/>

</LinearLayout>

我们的目标就是hook getString() 函数。
在这里插入图片描述

0x2 Xposed模块编写

编写Xposed模块,实际上就是编写一个apk,因此,需要借助于Android Studio,还需要下载一个配套的jar包,即XposedBridgeApi.jar,这是以前的做法,但是如今,只需要利用AS仓库,配置一下gradle就可以了。首先新建一个空项目,这个项目可以有Activity,也可以是一个没有MainActivity,取决于你的模块是否需要界面。新建完apk项目之后,三部曲,即可完成最终的模块编写。

0x21 修改Manifest.xml文件

在Application标签下,加入如下代码

<meta-data
    android:name="xposedmodule"
    android:value="true" />
<meta-data
    android:name="xposeddescription"
    android:value="这是一个Xposed示例" />
<meta-data
    android:name="xposedminversion"
    android:value="53" />

这段代码啥意思?我相信你在安装,并运行一下apk,再打开xposed框架,就知道什么意思了。
在这里插入图片描述

0x22 加载XposedBridgeApi.jar

早期,是需要下载该模块,并导入到项目的libs目录中的,如今,只需要简单配置下gradle即可。
在app/src/main目录中,导入jcenter(),这一步Android Studio都帮你做好了。接下来就是从这个jcenter仓库中,远程寻找 de.robv.android.xopsed:api:89。在build.gradle中加入如下代码。

compileOnly 'de.robv.android.xposed:api:82'
compileOnly 'de.robv.android.xposed:api:82:sources'

对于AS旧版本(AS3.0以下版本),则需要修改为

implementation 'de.robv.android.xposed:api:82'
implementation 'de.robv.android.xposed:api:82:sources'

0x23 编写具体hook逻辑

我们的目的是,hook在第一节编写好的demo程序中的getString()函数。

package com.lys.hook;

import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage;

public class HookTest implements IXposedHookLoadPackage {
    public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
        if (loadPackageParam.packageName.equals("com.lys.demoapplication")) {
            XposedBridge.log(" has Hooked!");
            Class clazz = loadPackageParam.classLoader.loadClass(
                    "com.lys.demoapplication.MainActivity");

            XposedHelpers.findAndHookMethod(clazz, "getString", new XC_MethodHook() {
                protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                    super.beforeHookedMethod(param);
                    XposedBridge.log(" has Hooked!");
                }

                protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                    param.setResult("我已被劫持!");
                }
            });
        }
    }
}
loadPackageParam.packageName.equals()

该方法用来寻找需要hook的包名,XposedHookLoadPackage中的handleLoadPackage方法主要用于加载应用程序包时执行用户的操作。

loadPackageParam.classLoader.loadClass()

用反射的方法来寻找需要hook的类名

XposedHelpers.findAndHookMethod()

顾名思义,使用反射的方法,来寻找需要hook的方法

beforeHookedMethod 该方法在hook目标方法执行前调用,其中,参数param指的是目标方法的相关参数、回调、方法等信息;afterHookedMethod 该方法在hook目标方法执行后调用,其中,参数param指的是目标方法的相关参数、回调、方法等信息。Xposed运行多个模块对同一个方法进行hook时,框架就会根据Xposed模块的优先级来排序。

XposedBridge类中hookAllMethods和log方法主要用于一次hook每个类的所有方法或够造函数。

hookAllMethods(
	Class<?> hookClass,//需要进行hook的类
	String methodName,//需要进行hook的方法名
	XC_MethodHook callback//回调函数
)

0x24 添加入口点

右键点击 “main ” 文件夹 , 选择new –> Folder –>Assets Folder,新建assets 文件夹:
在这里插入图片描述
右键点击 assets文件夹, new–> file,文件名为xposed_init(文件类型选text),并在其中写上入口类的完整路径(就是自己编写的那一个Hook类), Xposed框架能够从这个 xposed_init 读取信息来找到模块的入口,然后进行Hook操作了。比如这里,我们在xposed_init,添加

com.lys.hook.HookTest  // 该类就是自己编写的xposed模块类

0x25 安装模块

安装app,并在xposed框架中,激活该模块,重启手机。请注意,要想让Xposed识别出我们修改好的模块,必须要禁用Instant Run,即单击 File -> Settings -> Build, Execution, Deployment -> Instant Run,把第一个√去掉,这样再点击AS的安装,手机的Xposed框架会弹出模块已经更新,需要重启的对话框。
在这里插入图片描述
此时再运行我们之前装好的demo程序,即可看到,程序弹框已经被修改。
在这里插入图片描述

发布了23 篇原创文章 · 获赞 22 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/song_lee/article/details/103299353