Android IDA 动态调试最完善攻略,跨过各种坑
From:https://www.pianshen.com/article/3409449384/
IDA 静态分析 与 动态分析:https://zhuanlan.zhihu.com/p/38983223
新手向总结:IDA 动态调试 So 的一些坑:https://zhuanlan.zhihu.com/p/145383282
Android 逆向之旅 --- 动态方式** apk 进阶篇 ( IDA 调试 so 源码 ):https://zhuanlan.zhihu.com/p/23321571
IDA 动态调试 逆向 so 库:https://zhuanlan.zhihu.com/p/40174083
Android 未root 环境下使用 IDA 调试:https://www.pianshen.com/article/6759779793/
IDA 动态调试 android 的 so 文件 (二):https://www.pianshen.com/article/29271382106/
********************* 前提条件 和 运行环境 一定要写清楚,不然会有很多坑,坑死人。 *********************
雷电、蓝叠的 cpu 是 x86 的,ida不能正常调试,需要用 Android 编译器自带的创建模拟器。
ida模拟器动态调试,当执行到断点时会出现错误,通过百度知道是因为雷电、蓝叠模拟器的cpu都是x86的架构,所以用来调试就会出错,通过观看视频发现教程中用的是Android自带的模拟器,所以这里也是创建一个模拟器。
用 Android studio 创建模拟器会出现下面的选项,选择 Other Images 选项,这时显示出 armeabi-v7a,选择这个创建模拟器,就是 arm 的模拟器不是 x86,能正常调试。
动态启动调试(IDA 调试 Android 方法及简单的脱壳实现:https://www.pianshen.com/article/12891271497/)
Android Killer 反编译 x.apk,取出 classes.dex Dalvik文件,记录包名和启动类名。
修改 AndroidManifest.xml 文件,在 <application> 标签里添加属性 android:debuggable="true" 这一步越早修改越好,防止忘记改。可以查看一下AndroidManifest.xml 他们的对应关系,加深理解。
用 AndroidKiller 重新编译修改过的 x_fix.apk。
adb install x_fix.apk 安装到手机
将 IDA 安装目录 dbgsrv 目录下的 android_server 文件拷入手机
adb push dbgsrv\android_server /data/data/android_server
接着执行
adb shell chmod 655 /data/data/android_server 添加可执行权限
adb shell /data/data/android_server 将其运行起来
步骤:
(1) IDA 是 7.0 版本
(2) JDB 使用 Java 安装目录下的
(3) 系统是 win10, 使用命令窗口时有很大的差别
(4) 手机是4.4 以下系统
1.手机要有 Root 权限
2.复制 IDA 安装目录下 dbgsrv 文件里面的 android_server 文件到手机内存储的 /data/local/tmp 目录下
adb push dbgsrv\android_server /data/data/android_server
3.控制台输入 adb shell su 命令获取管理员权限
4.cd /data/local/tmp 进入android_server目录 ,输入chmod 777 android_server 命令获取执行权限
5. ./android_server 启动 android_server
6. 新开一个命令窗口 不用获取管理员权限,直接输入 adb forward tcp:23946 tcp:23946 命令 端口转发
7.adb shell am start -D -n 包名/activity路径 启动应用
adb shell am start -D -n com.cmxxzwy.mz/com.e4a.runtime.android.mainActivity
8.打开 IDA
9. 菜单 debugger->attach->Remote ARM Linux/android debugger
10.debug options 一定要选
11. hostname 处输入127.0.0.1
12. 点击 ok 后,在弹出的进程选择框 选择要调试的 com.cmxxzwy.mz 进程
13. 手机上的 App 开始运行后,一定要点击 IDA 的开始运行按钮。如果有反调试的话,一定要先下断点,不然一运行就崩溃了,一切重新来过。
14. 打开 DDMS,下一步要用
15. 查看 要调试的进程,发现 8700 端口被占用。可以使用 8677 端口
jdb -connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8700要改为
jdb -connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8677
用 jdb 将 app 恢复执行。
最后在命令行中输入:
jdb -connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8700
这一步的作用是使程序恢复运行。(注意这时候如果ida里还没有点击运行,程序是不会真的继续运行的)
这时候就可以正常地在IDA里下断调试了。
为了使用 jdb 恢复程序的运行,我们需要:
- APK 的 AndroidManifest.xml 中 debuggable 为 true
- 或是 根目录下 的 ro.debuggable的值为1,如下图所示:
参考:IDA调试 :https://www.pianshen.com/article/1916803437/
C:\>adb devices
List of devices attached
040ACGD7SAE2 device
C:\>adb shell
aaa@qq.com:/ $ su
aaa@qq.com:/ # exit
aaa@qq.com:/ $ exit
C:\>adb shell su
aaa@qq.com:/ # cat default.prop | grep debug
cat default.prop | grep debug
ro.debuggable=0
aaa@qq.com:/ # getprop ro.debuggable
getprop ro.debuggable
0
aaa@qq.com:/ #
16. 好了可以开始调试了 F7进入函数,F8单步调试,F9跳到下一个断点,F2下断点,G调到函数地址
17. 以某数字加固为例 给 libc.so 的 fopen 函数起始位置下断点。
然后一路F9, 直到出现
然后开始F8,一直F8执行,知道出现如下提示框
才真正进入我们要调试的 so库
18. 动态调试的时候面对的都是 Arm 汇编,理解能力要跟的上调试速度,这有点难。怎么办?
那就是动静态结合调试。我们来看动态调试窗口
1 为这句代码的动态内存地址。 2 为该so文件的动态内存基地址。 3 为内存段的大小。
静态调试窗口显示的都是代码的相对偏移地址,所以我们用 1动态内存地址 - 2内存基地址 = 静态相对偏移地址
所以 F24B4 就是静态代码的偏移地址。所以我们打开静态调试窗口就可以看到
这样,动态和静态的代码就对上了,用静态的代码来记录动态调试的位置信息,就不怕调试过程中断带来的麻烦。而且使用F5来辅助理解代码也是棒棒哒
19. 动态调试过程往往反反复复,命令有时候懒得重新输入。快捷键 ctrl +c 结束当前命令程序,按上下键输入之前输过的命令。
20. 有时候,跳转到指定地址的时候全是 DCB 数据,这怎么办
这个时候可以按 C 键识别为代码,或者按 P 键识别为函数
21.我们动态调试经常就是为了看内存,那么怎么看内存。很简单,执行下图前三步,就能在4步的视图中查看内存