转Android逆向之动态调试总结神乎
[转]Android 逆向之动态调试总结神乎 一、在 SO 中关键函数上下断点 刚学逆向调试时。大多都满足于在 SO 中某关键函数上下断 点。然后通过操作应用程序,去触发这个断点,然后进行调 试 详细的步骤可以参见非虫大大的《Android 软件安全与逆向 分析》 简单说:在 libsyclover.so 文件中有一个函数 jnicall1。每次 单击按钮的时候,便会调用此函数。 1.静态载入此 so 文件,找到函数的偏移地址为:0 x132C2. 执行 android_server3.端口转发 adb forward tcp:23946 tcp:23946 4.运行程序 5.IDA 附加 然后会弹出 点击 OK 之后,在弹出的列表框中选择需要附加的进程即可 6.下断点 附加完成之后,会停在 libc.so 这个模块中。此时按下 Ctrl + S,弹出模块列表框,搜索 so 文件名。 记录下基地址:0×76072000 (RX 权限) 和静态分析时得到的偏移地址 0 x132C 相加得到 0 x7607332C G 跳转到此位置 F2 下好断点! 7.触发断点 下好断点,便 F9 执行,此时状态是 runing 此时,去应用中单击按钮,程序便会断在刚刚下好的断点处 ~ ok~ 这种调试方法局限性很大,适合于比较初级的调试。这 种调试手法在现在已经满足不了需求了。 二、在 JNI_OnLoad 函数上下断点 JNI_OnLoad 函数大概功能就是在程序加载 so 的时候, 会执 行 JNI_OnLoad 函数,做一系列的准备工作。 很多时候,程序猿们会将一些重要信息放在此函数中,而不 是通过某种事件来重复触发。包括说将反调试函数放置在此 函数中。因此,调试手段发生了改变,上述调试方法基本上 被淘汰。 1.静态分析,找到 JNI_OnLoad 函数的偏移:0×1504 2.执行 android_server3.端口转发 adb forward tcp:23946 tcp:23946 4.以调试模式启动程序 adb shell am start -D -n com.example.mytestcm/.MainActivity 此时,手机界面会出现 Waiting For Debugger 页面 5.打开 ddms 或者 Eclipse (必要,为了使用 jdb 命令) 6.IDA 附加 7.设置调试选项 Debugger — Debugger Options 8.F9 运行程序 IDA 中,F9 运行程序,此时是 runing 状态。 在命令行中执行:jdb -connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8700 其中 port=8700 是从 ddms 中看到的。 此时程序会断下来 9.下断点 Ctrl + S 然后搜索到 so 文件名 记录下基地址是:0×76118000 加上 JNI_OnLoad 函数的偏移地址 0×1504 为 0×76119504 G 跳转到 0×76119504,下断点 A.触发断点 下好断点之后,直接 F9 运行吧,就能断在 JNI_OnLoad 函 数处~ 当这种调试手法出现之后,将特殊函数,或者反调试函数放 在 JNI_OnLoad 中也不是那么的安全了。此时,程序猿们通 过分析系统对 SO 文件的加载链接过程发现,JNI_OnLoad 函数并不是最开始执行的。在 JNI_OnLoad 函数执行之前, 还会执行 init 段和 init_array 中的一系列函数。 因此,现在的调试方法,都是将断点下在 init_array 中~ 至于下断点的方法,可以类比于在JNI_OnLoad 中下断点的 方法,在 init_array 的函数中下断点。还有一种方法便是通 过在 linker 模块中,通过对其中函数下断点,然后也能单步 到 init_array 中下面便详细介绍下如何给任意系统函数下断 点 三、给任意系统函数下断点 1.需要准备的有: 与你调试环境一致的系统源码,这个也可以在 root 之后的手机, 方便将系统的一些 so 文件 dump 至本地, 静态获取到系统函数的偏移地址 2.流程 执行 android_server 端口转发 adb forward tcp:23946 tcp:23946 调试模式启动程序 adb shell am start -D -n 包名/类名 IDA 附加 静态找到目标函数对应所在模块的偏移地址 Ctrl+S 找到对应模块的基地址,两个地址相加得到最终地址 G 跳转至地址,然后下断 F9 运行 执行 jdb -connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8700 断下,进行调试 四、在 dvmDexFileOpenPartial 函数下断点,dump 出明文 dex 发展至今,从去年到现在,apk 的加解密发展非常迅速。国 内出现了很多针对 apk 的加壳保护方案。主要也体现在对 dex 的保护和对 so 的保护! 针对 dex 的保护,很长一段时间,都能通过对 dvmDexFileOpenPartial 函数下断点, 从而 dump 出明文 dex 文件。 以这次 alictf 的第三题为例子,展示下如何对 dvmDexFileOpenPartial 函数下断点! 其他步骤都是一样的,这儿主要说下如何找到 dvmDexFileOpenPartial 函数位置 1.查看源码 dvmDexFileOpenPartial 函数在 rewriteDex 这个函数中被调 用。 可以看到关键字符串信息是:Unable to create DexFile 此时,从手机的/system/lib 目录下得到 libdvm.so 2. 载入 IDA,搜索字符串:Unable to create DexFile 得到偏移地址是:0 x0005AE8A 3.下断点 搜索模块 libdvm.so 基地址是 0×41492000 加上偏移地址为 0 x414ECE8A G 跳转至此位置,下好断点,即可 4.dump 明文 dex 文件 下好断点之后,F9 运行,执行 jdb -connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8700 程序断下 此时,看到寄存器窗口中的值为: R0 保存 dex 的起始地址,R1 便是 dex 的长度 直接 dump 即可! 5.后续 dump 出来的 dex 就可以进行反编。 效果如下: 五、写在最后 随着现在技术的发展,对apk 的保护是越来越好!大大增加 了逆向分析人员的分析难度。同时,在整个攻防的过程中, 对攻防两端的人都带来了非常棒体验。双方都取得了长足的 进步! 也促使了整个加固方向水平的提升! 其中,动态调试手法在整个过程中是必不可少的。