前言
最近先后尝试了各种手写nativehook,开始还好,写到后面越发艰难,最后参看2011年的古河代码后无果,于是决定先使用好常用的hook框架,再针对开源的代码去研究轮子。
hook的好处十分多,如可以不修改不重打包逆向程序,而且可以避免反调试和各种壳,但hook时需要详细知道目标函数的符号等信息。
目前认准有三:
1、XPOSED 开源
优点:
1)、代码编写方便,开发速度较快。
2)、有许多现成的模块可以用,而且很多模块也是开源的,方便学习研究。
缺点:
1)、每次编写代码需要重启手机生效。
2)、不支持native的HOOK。
3)、独立性较差,需要依赖XPOSED installer,不易单独分发。
2、cydia substrate 不开源
这个Supported on versions 2.3 through 4.3的android。在ios上表现很好,android的2013年就停更了。
优点:
1)、比较擅长在native层的HOOK。
2)、独立性较好,实现的功能可以封装在单独APP里分发给用户使用,因此也是较大型外挂辅助工具的首选。
缺点:
1)、每次编写代码需要重启手机生效。
2)、开发效率较低,成本较高。
3、frida 开源
优点:
1)、无须重启手机和目标APP,这个可以节省很多时间,如果APP测试的点需要很复杂地搭建好环境,一旦重新启动就意味着很麻烦地再重新搭建环境,例如账号登录,进入特定关卡等。
2)、JS脚本编写,灵活方便,再也不用担心多参数个数和类型问题了。
3)、可以直接使用或修改对象的成员变量,非常方便。
4)、配合PC终端命令行使用,脚本编写出错也不会导致APP崩溃,只需修改后重新来过即可,有时会有问题,这个时候需要重启下APP或手机即可。
缺点:
1)、JS脚本套在python脚本里面,编写JS脚本时候不是很方便,容易出错,好在即使出错也不会导致APP崩溃掉,修改后重新来过即可。
2)、该工具配合PC终端使用,更适合专业者,不利于分发给用户使用。
接下来依次尝试之。
Xposed 原理
通过替换/system/bin/app_process程序控制zygote进程,使得app_process在启动过程中会加载XposedBridge.jar这个jar包,从而完成对Zygote进程及其创建的Dalvik虚拟机的劫持。
项目梳理:
XposedBridge.jar:XposedBridge.jar是Xposed提供的jar文件,负责在Native层与FrameWork层进行交互。/system/bin/app_process进程启动过程中会加载该jar包,其它的Modules的开发与运行都是基于该jar包的。
Xposed:Xposed的C++部分,主要是用来替换/system/bin/app_process,并为XposedBridge提供JNI方法。
XposedInstaller:Xposed的安装包,负责配置Xposed工作的环境并且提供对基于Xposed框架的Modules的管理。在安装XposedInstaller之后,app_process与XposedBridge.jar放置在了/data/data/de.robv.android.xposed.installer。
Xposed 安装
因为要修改系统文件,所以前提需要root
经实践发现supersu卡刷非常管用。
root后安装xposed installer ,进入应用,点击install安装框架(via那个是通过recovery模式安装)
到此hook框架已经安装完成。可以自己编写模块使用了
AS下的Xposed编程
创建工程
不必有activity,一个空项目就好
1导入包
俩种方式:
- 把下好的api-82.jar放到lib下,并添加到build.gradle路径中
- 由于以传至jcenter()库所以在build.gradle的dependencies下直接写compileOnly ‘de.robv.android.xposed:api:82’
注意接口包不能包含到插件项目的生成包中。
|
|
注意为compileOnly,区别:
2.x(3.x)
- (implementation):只能在内部使用此模块,会参与打包,比如我在一个libiary中使用implementation依赖了gson库,然后我的主项目依赖了libiary,那么,我的主项目就无法访问gson库中的方法。
- compile(api):使用该方式依赖的库将会参与编译和打包。 也就是全部包含进dex中。又打包又用
- provided(compileOnly):只在编译时有效,不会参与打包 。运行时寻找android平台上的,只用不打包
- apk(runtimeOnly):只在生成apk的时候参与打包,编译时不会参与。不用只打包。
- testCompile(testImplementation):testCompile 只在单元测试代码的编译以及最终打包测试apk时有效。
- debugCompile(debugImplementation):debugCompile 只在debug模式的编译和最终的debug apk打包时有效
- releaseCompile:Release compile 仅仅针对Release 模式的编译和最终的Release apk打包。
API 类真正的实现则在 Xposed FramWork中。所以选择compileOnly
jar为.class集合。
2改manifest
AndroidManifest.xml中添加
xposedmodule:代表的是Android程序作为Xposed中的一个模块,所以值为true;
xposeddescription:代表的是对本模块的功能的描述,可以自己简单叙述下就可以了;项目名是插件名,这是底下的描述
xposedminversion:代表的是本模块开发时用到的xposed的jar包的最低版本号;
3java中写类
只要新建一个实现IXposedHookLoadPackage接口的类,然后在handleLoadPackage回调方法中进行拦截操作即可,详细见下文。
4添加模块入口
告诉Xposed框架一个模块中Hook的入口
- main下建assets文件夹
- assets文件夹下建xposed_init文件
- xposed_init中写包名.类名
main文件夹下的东西都会被打包
构建安装
构建安装apk至手机中,框架即可自动识别到模块,点击启动,重启后即可生效。
注意AS的Instant Run(闪电)是加快apk安装速度的功能,可能涉及的方面有:
- 优化apk大小,可能把不用的类优化掉了(xposed时小心)
- 热更新方法内代码
- 热更新资源
- 热更新新方法
api详解
首先是api官网:
https://api.xposed.info/reference/packages.html
android.app:有关当前应用程序信息的方法。
android.content.res:包含替换资源所需的类。
de.robv.android.xposed:包含Xposed框架的主要类。
de.robv.android.xposed.callbacks:包含回调的基类。
de.robv.android.xposed.services:包含Xposed框架提供的文件访问服务。
android.app
就一个AndroidAppHelper类,用于查询当前应用程序信息的各种方法
de.robv.android.xposed
这个是主要功能包
IXposedHookLoadPackage接口:这个接口应该由模块的主类来实现。Xposed会自动注册为回叫。在每个app加载时收到通知。其唯一方法在加载时调用:void handleLoadPackage (XC_LoadPackage.LoadPackageParam lpparam)参数为de.robv.android.xposed.callbacks包中XC_LoadPackage的子类,其为包装关于正在加载的应用程序的信息的类。可返回packageName,classLoader等
里面还有:XposedHelpers静态类用于简化hook如:findAndHookMethod
XC_MethodHook钩子类,其含俩个方法用于目标方法之前与之后调用,其有俩个内部类:
MethodHookParam可获得参数(字段args数组)与返回信息(方法)
XC_MethodHook.Unhook管理hook用。可用来删除回调
具体灵活使用还是需要系统框架源码知识和xposed源码实现原理。