前提#
这里假设你已经了解 Charles、Xposed、FDex2 等工具的使用
实践#
目标:修改用户等级
手段:
- 
- 抓包(Charles)
 
- 
- Xposed
 
1. 抓包#
通过发编译代码获取用户等级相关信息,目的是为了 rewrite 请求返回的用户等级字段
"REGISTER" => "TREASURE"
此方法简单易用,前提是 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"
    }
})另外对于已经加固过的 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"
            }
        })
    }
})关于混淆#
下面是各种混淆程度的对比:
不混淆:

普通混淆:

高级混淆:

加固:

所以不混淆很可怕的事情,代码一览无余;高级混淆尽量上;加固后的代码反编译看不到,只能动态 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 要上
道高一尺魔高一丈,攻防本来就是博弈的过程,只有不断增加门破解槛,增加破解成本。