1. Xpatch概述
Xpatch是一款利用重打包的方式,使得被处理的Apk启动时自动加载Xposed模块,来实现应用内Hook的工具。
项目地址:https://github.com/WindySha/Xpatch
2. Xpatch处理apk分析
Xpatch修改apk,主要有三个步骤,代码在MainCommand类的doCommandLine方法:
(1) 第一步
在Xpatch的源码中,第一步对应的是ApkModifyTask类,实现的是Runnable接口,它的任务是修改Dex文件,使得被处理的apk在启动时能够执行指定的代码。
如果反编译被Xpatch处理过的Apk,查看App中Application的子类,会发现其中多了以下的代码:
我们大胆的猜测,这就是Xpatch给注入进去的入口代码。我们回到Xpatch的源码,来看看它是如何注入的。查看ApkModifyTask类,一步步进行跟踪:
ApkModifyTask类的run方法,在任务被启动时调用,它的代码:
doTranslate方法很长,但是我们很容易就能看到了很敏感的字符串:com/wind/xposed/entry/XposedModuleEntry,这就是Xpatch插入自己初始化的代码的地方。visitMethodInsn方法用于在函数内插入一条指令,看到两处调用visitMethodInsn来插入调用 com.wind.xposed.entry.XposedModuleEntry类的init方法的指令。
convertCode函数中的visitMethodInsn,逻辑是如果要处理的Application类中存在clinit方法,即存在静态代码段,就直接插入调用 com.wind.xposed.entry.XposedModuleEntry类的init方法的指令
addMethod函数中的visitMethodInsn,如果要处理的Application类中不存在clinit方法,即不存在静态代码段,就创建一个静态代码段,并在其中插入调用 com.wind.xposed.entry.XposedModuleEntry类的init方法的指令,最后返回void
注:上面的操作码,184代表invoke-static,177代表return-void。这些操作码定义在org.objectweb.asm.Opcodes类中。
到这里,第一步我们已经搞清楚了。
(2) 第二步
对应的是SoAndDexCopyTask类,从名字可以看出它的任务是复制so和dex的,具体是怎样的,我们看代码。
SoAndDexCopyTask类,它也实现了Runnable接口,run方法在任务被启动时调用:
没什么好说的,就是删除<apk解压目录>/META-INF下的指定文件。
(3) 第三步
对应的是BuildAndSignApkTask类,从名字可以看出它的任务是构建和对apk签名的。
这个BuildAndSignApkTask类也是实现Runnable接口,我们来看run方法:
这个方法做了两件重要的事,把apk解压目录给压缩成zip,并给压缩成的文件签名,这里就不细讲了。
3. 被集成进apk中的dex分析
我们在上面提到过,Xpatch把assets目录下的classes.dex文件复制进了目标apk里,这个dex是不开源的,那么这个dex里面究竟有什么呢,我们把dex解压出来,拖进jadx中反编译。
既然Xpatch将初始化代码注入到应用的Application类,初始化代码调用com.wind.xposed.entry.XposedModuleEntry类的init方法,那么我们从init方法开始看起。
这个函数读取传进来的Xposed模块的信息,获取DexClassLoader,读取模块assets下的xposed_init文件,得到其中的类名并根据实例类型(IXposedHookZygoteInit或者IXposedHookLoadPackage)分别实例化它,是IXposedHookZygoteInit实例就callInitZygote,是IXposedHookLoadPackage实例就像上面的注释2所讲的一样调用模块的handleLoadPackage方法。
讲到这里好像并没有涉及到whale框架,我们编写模块的时候,Hook的代码都是写在handleLoadPackage方法中,比如我们在handleLoadPackage方法内,写个findAndHookMethod,最终就会调用WhaleRuntime.hookMethodNative本地方法,来实现应用内的Hook
4. 总结
Xpatch思路很好,不需要ROOT,不用担心Xposed在某些设备上的兼容性,不用每次调试Xposed模块都重启手机,很方便的就可以使用Xposed模块,实现应用内的Hook。但是在使用的过程中也发现了一个小问题,要处理的Apk如果没有手动继承Application类并在AndroidManifest.xml中指定,那么Xpatch就注入不了代码,也就无法正常使用。本文也只讲了Xpatch的基本流程,具体whale是怎么Hook的,能力有限,没能展开。
本文由看雪论坛 落叶似秋 原创
网友评论