阅读 315

开发Xposed插件CPWechatXposed | 项目复盘

1、项目简介

Xposed框架可以在不修改APK的情况下影响程序运行,我们可以利用它对App进行Hook,以实现一些自定义的功能。CPWechatXposed 是笔者开发的一款微信插件,本文介绍的是此插件开发过程与复盘。

仓库地址:github.com/coder-pig/C…

Tips:项目早已搁置许久,原因是:每次微信更新都要耗费较多时间适配,重复体力活对逆向水平没啥提升,而且大号被封过,怕了怕了。读者有兴趣想写Xposed插件的可以参考下,弄下去广告插件啥的还是挺有意思的~

2、项目背景

一次年会上,公司领导们微信群发红包让大家抢,一边吃饭一边盯着手机蹲红包,结果饭没吃好红包也没抢到:

过年在家也是重蹈覆辙,每次打开群聊都是已抢完,还让不让人好好过节了,于是乎萌生了写一个自动抢红包工具的想法。

一开始想到的是模拟人一直监测红包信息,然后检测到有特定文本 自动点,学习了一波Android无障碍服务 AccessibilityService,肝了个工具 WechatHelper

投入使用后,在 相亲相爱一家人 类的群里都是抢第一,但在开发仔的群里经常抢不到第一,有时还抢不到。

后面了解到别人也是用了外挂,不过比我写的更快,用的Xposed抢红包插件,直接Hook微信信息的方法,监测到红包信息,直接调起抢红包,有些甚至还做到了无感拆,以及自动回复谢谢老板。

于是乎我也研究起Xposed插件开发了,也开始接触起逆向,所以也有了这个项目。

3、实践过程

① 创建一个Xposed项目

  • Step 1 → 新建Android工程,修改 AndroidManifest.xml,增加下述代码:

  • Step 2build.gradle 文件添加库依赖(provided只提供编译支持,不会写到apk里):

  • Step 3res/asserts 文件夹创建一个 xposed_init 文件,XposedBridge 会从 assets 目录中的xposed_init文件中获取入口点,比如:

  • Step 4:编写入口点类,Hook MainActivity里Textview显示的文字,渣渣辉改成贪玩蓝月:

Xposed入口类 XposedInit.java

流程解析:

  • ① 实现 IXposedHookLoadPackage 接口,重写 handleLoadPackage 函数;
  • ② 判断是否为应用包名,XposedHelpers.findAndHookMethod() 查找Hook掉 onCreate() 函数;
  • XC_MethodHook 重写 afterHookedMethod() 函数,onCreate()执行完会回调此函数;
  • ④ 在此获得TextView对象,把文字修改为“贪玩蓝月”,运行安装后,重启设备查看是否生效。

log也可以看到打印的日志信息:

注意:在运行Xposed项目前,记得把InstallRun的钩钩去掉!


② Xposed 提供的一些API

知道怎么创建运行一个Xposed项目,接着了解下都有哪些常用的API~

  • IXposedHookLoadPackage → App被加载时调用,用于App应用Hook回调的函数是:handleLoadPackage
  • XC_LoadPackage.LoadPackageParam → 包含与正在加载的应用程序相关的信息;

  • XposedHelpers.findAndHookMethod(要Hook的类,classLoader,方法名,参数,XC_MethodHook回调对象)

Hook一个函数时使用,XC_MethodHook回调对象需重写两个函数:

  • beforeHookedMethod(MethodHookParam param):方法调用前执行;
  • afterHookedMethod(MethodHookParam param):方法调用后执行;

注:可调用**param.setResult**()设置方法的返回值!

  • MethodHookParam:包含与调用方法相关的信息:

比较关注的是这里的 thisObject 代表调用此方法的对象实例,如果是静态方法,会返回null,而例子中调用OnCreate()方法的是MainActivity,获得的自然是MainActivity的实例。

接着是 获取成员,分私有与非私有,非私有直接调用下述方法即可获得成员:

Class c = lpparam.classLoader.loadClass("com.coderpig.cpwechatxposed.MainActivity");
Field field = c.getField("tv");
复制代码

私有成员要先关闭安全访问检查(setAccessible):

Class c = lpparam.classLoader.loadClass("com.coderpig.cpwechatxposed.MainActivity");
Field field = c.getDeclaredField("tv");
field.setAccessible(true);
复制代码

调用获取该对象:

TextView tv = (TextView) field.get(param.thisObject);
tv.setText("贪玩难约");
复制代码
  • IXposedHookZygoteInit → 在Zygote启动时调用,用于系统服务的Hook 回调initZygote();
  • IXposedHookInitPackageResources → 在资源布局初始化时会回被执行(inflate) 回调:handleInitPackageResources(XC_InitPackageResources.InitPackageResourcesParam resparam)

InitPackageResourcesParam包含两个参数,包名和XResource(资源相关)

有了这个 XResource 对象,就可以拿到布局资源树了,通过重写 hookLayout 方法:

LayoutInflatedParam,里面这个view就是布局资源树,可以拿到遍历,获取特定控件,做一些骚操作:

XposeHelpers提供了一些辅助方法:

  • callMethod(Object obj,String methodName, Object... args):在APP中调用特定方法,参数依次是:调用方法的所在类,调用方法名,方法参数;
  • findClass(String className,ClassLoader classLoader):获取class类实例,参数依次是类名,类加载器;
  • findMethodExact:通过反射查找类的成员方法(可setAccessible(true)设置非私有);
  • findConstructorExact:通过反射查找构造函数(同样可设置可访问下性);
  • findAndHookXXX:查找并Hook;
  • setXxx:通过反射设置对象数据成员的值;
  • setStaticXxx:通过反射设置静态变量的值;
  • XposedBridge.log("日志内容"):输入日志和写入到/data/xposed/debug.log,Xposed Installer日志那里可以看到!
  • 内部类:通过$符号链接内部类;
  • 只能Hook方法与构造方法,不能Hook接口和抽象方法;

③ 如何定位到方法调用点

知道哪些API可以耍了,接着就是如何定位到方法调用点了,方法一般有下述三种:

  • 猜测验证法:适用于特定场景,而且具有一定Android开发经验,Hook微信运动改步数,如果你写过计步类的程序,不难想到 手机传感器 那一块去:

接着就是写代码验证的过程了,完整过程可以移步至:《抱歉,Xposed真的可以为所欲为——3.微信运动占领封面出售广告位》 自行查阅~

  • ddms轨迹跟踪方法调用,比较呆的一种方法,效率较低,在没有好的入手点时可以先通过此方法模糊定位到Hook方法,不建议上来就跟,会跟晕的,完整过程可移步至:《抱歉,Xposed真的可以为所欲为——4.猜拳投骰子你能赢算我输》 自行查阅~

  • 反编译apk源代码:没加固的可以直接用jadx直接反编译,加固的需要自己脱出dex再反编译,然后去跟代码。另外直接用jadx反编译遇到大apk时容易直接卡死,笔者写了个脚本:

执行下py文件一键反编译,哈哈,至于简单加固脱壳可以见我之前写的逆向文章,完整过程可移步至:《抱歉,Xposed真的可以为所欲为——6.你的表白撤不回了》 自行查阅~

4、总结思考

在编写Xposed的过程中,让我对逆向有了写了解,相比起普通Android开发仔,在竞品分析时,我能更快的了解到实现方式,日常使用APP时,用得不爽,就写个Xposed或者脱壳修复二次打包。

不要问我能不能hook支付宝或者微信余额!!!

自己骗自己有意思吗?不足的一些地方:

  • ① 逆向没有深入学,只懂点皮毛,停留在工具使用层次;
  • ② 一些坑没有填:Xposed的完整实现原理Xposed的检测与反检测 等;

最近在准备面试,会把坑一个个填上,希望借助本文,你也能DIY出自己的Xposed插件,谢谢~


本文正在参与「掘金 2021 春招闯关活动」, 点击查看 活动详情

文章分类
Android
文章标签