前提#
这里假设你已经了解 Charles、Xposed、FDex2 等工具的使用
实践#
目标:修改用户等级
手段:
-
- 抓包(Charles)
-
- Xposed
1. 抓包#
通过发编译代码获取用户等级相关信息,目的是为了 rewrite
请求返回的用户等级字段
"REGISTER" => "TREASURE"
text此方法简单易用,前提是 app 没有做 SSL Pinning
2. Xposed#
通过 jadx-gui 反编译 apk,搜索与 获取用户等级
相关代码
编写 Xposed 代码 hook 相应函数
findAndHookMethod(findClass("com.xxx.xxx.module.me.a.b", classLoader), "e", object : XC_MethodHook() {
override fun afterHookedMethod(param: MethodHookParam?) {
super.afterHookedMethod(param)
param!!.result = "TREASURE"
}
})
kotlin另外对于已经加固过的 app,需要先脱壳,这里使用 FDex2 进行脱壳
而且已经加固 app 进行 hook 的时候需要做一些额外的处理
findAndHookMethod(findClass("com.stub.StubApp", classLoader), "attachBaseContext", Context::class.java, object : XC_MethodHook() {
override fun afterHookedMethod(param: MethodHookParam?) {
super.afterHookedMethod(param)
val context = param!!.args[0] as Context
val classLoader = context.classLoader // 获取原始 classLoader
findAndHookMethod(findClass("com.xxx.xxx.module.me.a.b", classLoader), "e", object : XC_MethodHook() {
override fun afterHookedMethod(param: MethodHookParam?) {
super.afterHookedMethod(param)
param!!.result = "TREASURE"
}
})
}
})
kotlin关于混淆#
下面是各种混淆程度的对比:
不混淆:
普通混淆:
高级混淆:
加固:
所以不混淆很可怕的事情,代码一览无余;高级混淆尽量上;加固后的代码反编译看不到,只能动态 dump dex 后查看,为了增加门槛也要上。
另外推荐一下 Paranoid ↗,是做硬编码混淆的,比如 app 里配置的 domain、key 等信息都可以混淆。
关于 SSL Pinning#
证书锁定本质是对抗中间人攻击,并非用于对抗破解抓包的。
具体详细原理请移步 SSL Pinning Practice ↗
这里说一下如何对抗 SSL Pinning,用到了 JustTrustMe ↗(An xposed module that disables SSL certificate checking for the purposes of auditing an app with cert pinning)
总结#
- 混淆要上,高级混淆也要上,硬编码混淆也需要上
- 加固要上(对性能有一些影响)
- SSL Pinning 要上
道高一尺魔高一丈,攻防本来就是博弈的过程,只有不断增加门破解槛,增加破解成本。