Android逆向关键代码定位:抓包、Hook点与沙盒

0 阅读3分钟

Frida Hook技术(二)

抓包、Hook点与沙盒

加密字符串一反射,jadx 里搜关键字就断了。换思路:抓包先看数据长什么样,再用 HashMap.put、Collections.sort、Toast.show 这些公共点打调用栈,定位关键代码。Java 层最省事的是跑沙盒。

图片

图片

一、PC 客户端抓包:Fiddler + Proxifer

PC 客户端流量不一定走系统代理。做法是 Fiddler + Proxifer:用 Proxifer 做 VPN 转发,把客户端流量导到 Fiddler。Fiddler 和 Proxifer 两边都能看到抓到的数据。

图片

二、为什么静态搜索经常废

入门案例里常见卡点:Java / C 基础不够;搜索不靠谱——字符串加密了、反射调用了,关键字就搜不到;标准算法在 Java / C 里怎么实现不熟;复现时用 JS,结果加密库也不熟;Hook 代码写着烦;还有加固、抓包检测、Hook 检测、Root 检测挡路。

定位思路要换:Java 侧——Hook 系统函数,或用沙盒吐出 smali 和函数调用关系;C 侧——Hook 系统函数;写 Hook 嫌烦——Java 可用 Objection(自动化 Hook)或沙盒;so 层暂时没什么特别省事的工具,多半自己封装 Frida API。逆向 H5 的 App,还得懂 JS——那是安卓逆向和 JS 逆向混搭。

图片

图片

三、Frida 注入与打印调用栈

注入还是老命令:frida -UF -l test2.js。Frida Hook 脚本里写的是对 Java 层的调用。打印调用栈用 showStacks:android.util.Log.getStackTraceString(new java.lang.Throwable()),参数就是 Throwable 异常信息,目的是追踪程序调用流程。

代码没问题,但 App 开久了有时 Hook 不到想要的东西——重启 App,或换一个 Hook 点。jadx 的反混淆不要开,开了以后 Hook 的函数名会被改,对不上。包名以 Frida 枚举出来的为准:enumerateLoadedClassesSync。

图片

图片

四、HashMap.put:提交参数入口

HashMap.put 一般在提交参数时用。Hook put,过滤 key 等于 username,命中就 showStacks,并打出 key、value。相关家族一起盯:HashMap、LinkedHashMap、ConcurrentHashMap;HashSet、LinkedHashSet 底层走的是 HashMap、LinkedHashMap。

图片

图片

五、一批高频 Hook 定位点

TextUtils.isEmpty:常用于控件内容判空,很多开发者也会自己再包一层。不知道类全名时,在工程里敲一下代码,提示里就能看到包路径。对已知密文或关键串做 equals 过滤,命中再打栈。

Log.w:Hook 日志打印,tag 和 message 一起打出来;需要时再开 showStacks。JSONObject.put、indexOf 子串查找、getString,也是常见卡点。协议逆向做到数据加密,常会落到 Base64 相关定位。

图片

图片

六、Collections.sort:签名前排序

ArrayList 在排序时用,签名算法之前经常排序。Hook Collections.sort,两个重载都要挂:第一个 sort(List) 会调第二个 sort(List, Comparator),第二个更底层,可自定义规则。参数类型是 List 接口,实际传入多是 ArrayList 等实现类,要 Java.cast 成 ArrayList 再 toString。Arrays.sort 也是排序,别漏。

图片

七、Toast.show:强制升级弹窗

Hook Toast.show,弹 Toast 时打调用栈。做去强制升级时,对方往往会弹窗,从 Toast.show 往回追,能较快定位到升级逻辑。

图片

八、字符串定位三板斧

协议里对明文字节动手时,可能用 String.getBytes;也可以 Hook isEmpty。注意:函数调得太勤,硬 Hook 可能把程序搞崩。

别直接 Hook String 构造函数——Android 上很多构造直接抛 UnsupportedOperationException,提示 Use StringFactory instead,Hook 它没用。真正要 Hook 的是 StringFactory:newStringFromBytes、newStringFromChars、newStringFromString、newStringFromStringBuffer、newStringFromStringBuilder。

字符串定位总结:① getBytes——定位字符串转字节;② 字符串构造(走 StringFactory);③ StringBuilder——定位拼接,构造最后会 toString,toString 会 new String。StringBuffer 和 StringBuilder 的区别:StringBuffer 支持多线程,因为加了锁。

图片

九、findViewById 与控件 ID

获取控件 ID:可用 UI Automator Viewer。控件 ID 对应数值在 R 类里找,R 类在包名对应文件夹下,例如 R$id.btn_login.value。

findViewById 只在创建界面时执行,事后再 Hook 已经不跑了。手动重启 App 也不行,必须让 Frida 来拉起进程,例如:frida -U -f 包名 -l HookDemo.js -o log.txt --no-pause。-f 强制重启注入;--no-pause 不暂停主线程,程序直接跑。不恢复线程也可以,命令里带上不暂停即可。setOnClickListener 和 findViewById 一样,一开始执行过就不再执行,同样要 spawn 注入。

图片

图片

十、沙盒辅助定位(Java 层)

Java 层最好的关键代码定位,往往是跑沙盒。沙盒是直接 Hook 虚拟机解释器:不仅能打每一行 Java 相关执行信息,还能打每一行 smali,以及对应寄存器的值;同时打印函数调用关系。代码执行顺序从上到下,对着 trace 就能顺着业务走。

沙盒能跑出来的:① Java 层;② so 回调到 Java 层的。定位不到的:so 层 native 汇编,以及 H5 的 JS。H5 逆向面临的是安卓逆向和 JS 逆向混搭,要懂 JS。

图片

图片

十一、总结

1. PC 客户端抓包:Fiddler + Proxifer 做 VPN 转发,两边都能看数据          2. 加密串、反射调用导致静态搜索失效,要换 Hook / 沙盒思路          3. Java:Hook 系统函数或沙盒吐 smali 与调用关系;C:Hook 系统函数          4. Hook 嫌烦可用 Objection;H5 App 还要懂 JS          5. showStacks:Log.getStackTraceString(new Throwable) 追调用链          6. App 开久 Hook 不到:重启或换 Hook 点;jadx 反混淆别开          7. 包名以 enumerateLoadedClassesSync 枚举结果为准          8. HashMap.put 提交参数常用;过滤 username 等 key 再打栈          9. Map 家族:HashMap/LinkedHashMap/ConcurrentHashMap,Set 底层走 Map          10. TextUtils.isEmpty 控件判空;Log.w 打日志;JSONObject.put / indexOf / getString          11. Collections.sort 两重载都 Hook,List 转 ArrayList;另有 Arrays.sort          12. Toast.show 可定位强制升级弹窗逻辑          13. 协议加密常落到 Base64;getBytes 盯明文转字节          14. 别 Hook String 构造,改 Hook StringFactory 一串 newStringFrom*          15. 字符串定位:getBytes、StringFactory、StringBuilder(toString→new String)          16. StringBuffer 有锁支持多线程;StringBuilder 无          17. 控件 ID:UI Automator Viewer + R$id.xxx.value          18. findViewById / setOnClickListener 只执行一次,需 frida -f --no-pause       19. 沙盒 Hook 解释器:打调用关系 + 每行 smali 与寄存器          20. 沙盒能定位 Java 与 so→Java;定位不到 so 汇编和 H5 JS

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

如果觉得有帮助,欢迎转发!

关注公众号,输出安卓逆向与底层技术干货。

#关键代码定位 #Frida #沙盒 #Fiddler #Proxifer #HashMap #Collections.sort #StringFactory #安卓逆向 #Objection