最近花点时间折腾了下Xposed框架,还挺有意思,这里记录下学习过程


0x01 Xposed介绍

Xposed是一个基于Android的Hook框架,他的基本原理大概是替换了系统的app_process,之后com.android.internal.osZygoteInit.main()被替换成了:de.robv.android.xposed.XposedBridge.main(), 以后fork出的进程都是被Hook的,后面利用XposedBridge.jar便可进行各种骚操作。

0x02 创建Xposed项目

Step 1.修改AndroidManifest.xml

创建一个空白的项目,在AndroidManifest.xml文件中增加如下代码:

    <meta-data
        android:name="xposedmodule"
        android:value="true" />
    <meta-data
        android:name="xposeddescription"
        android:value="描述" />
    <meta-data
        android:name="xposedminversion"
        android:value="82" />

Step 2. 增加xposed依赖

在dependencies内增加

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

Step 3. 自定义入口点

新建assets目录,增加xposed_init文件,内容为Xposed入口类。比如 spiders.example.com.myapplication.XposedMain
Xposed运行后会在xposed_init文件中读取Xposed入口,如上就会去寻找运行XposedMain类。

Step 4. 编写Hook主函数

在此之前,先写一个简单的MainActivity,它用Toast显示一个字符串

public class MainActivity extends Activity {
private String show = "unhooked!";
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toast.makeText(this,this.show,Toast.LENGTH_LONG).show();
}

}
之后编写XposedMain.java,思路是先Hook MainActivity类中的onCreate函数,之后再调用函数之前修改show变量为hooked!,完成hook,代码如下:

public class XposedMain implements IXposedHookLoadPackage {
@Override
public void handleLoadPackage(final XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {
    if(lpparam.packageName.equals("spiders.example.com.myapplication")){
        XposedHelpers.findAndHookMethod("spiders.example.com.myapplication.MainActivity", lpparam.classLoader, "onCreate", Bundle.class, new XC_MethodHook() {
            @Override
            protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                XposedBridge.log("before hook ");
                XposedHelpers.setObjectField(param.thisObject,"show","hooked!");
                super.beforeHookedMethod(param);
            }
        });
    }}}