配置环境
一台已root手机
- IDA pro6.6
- Android SDK
准备工作:
- 把Android SDK添加到环境变量中
- 把已root手机的系统中关键so拖到本地,必要时可以静态读取,获取系统函数的偏移地址。 例如把手机系统的
system/lib
的文件拖到本地debugging
文件夹中。adb pull /system/lib .\debugging\lib
- 在IDA pro6.6中找出
android_server
,并把android_server
放到手机system/bin
中。push的时候没有root权限,可以如下操作:1
2
3
4adb push android_server /data/local/tmp
adb shell
su
cp /data/local/tmp/android_server /system/lib
环境启动
由于需要调试程序启动加载的so,所以步骤比较多。
- 进入
adb shell
,在手机中执行android_server
。1
2
3adb shell
su
android_server - 进行端口转发
adb forward tcp:23946 tcp:23946
- 使用调试模式启动程序,
adb shell am start -D -n 包名/类名
,以上一篇博文的dexunshellram
为例,dexunshellram
动态加载了crackme0201
,启动命令如下:adb shell am start -D -n com.droider.dexunshellram/com.droider.crackme0201.MainActivity
- 打开IDA6.6,打开需要调试的so,然后选择
Debugger->Select debugger
,选择Remote ARM Linux/Android debugger
。
然后选择Debugger->Debugger options
,勾选所有logging
和Events
里的Suspend on thread start/exit
和Suspend on library load/unload
。
然后选择Debugger->process options
,在Hostname
中填写127.0.0.1
,端口默认为23946
。
然后选择Debugger->attach a process
,选择com.droider.dexunshellram
。
然后可能出现如下图所示,需要add map
,由于之前把手机系统的system/lib
复制到电脑中,这样可以指定到电脑的相应文件夹中,这样就可以静态调试系统so。如果你觉得你用不着调试系统函数,可以不用指定。 - 在Android SDK中找出
ddms.bat
,双击打开,为了后面执行jdb。 - 在IDA中点击运行或者按F9,然后在cmd中运行一下命令启动jdb
jdb -connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8700
- IDA在linker中停下了,然后在path中找到相应调试的
libunshellram.so
,选择函数Java_com_droider_dexunshellram_unshellram_loadDex
,这里是内存动态加载dex的地方。在else语句之前进行断点,就是loc_
前一行插入断点,按F2,然后再运行程序,按F9。
dump内存
如下图所示,R0寄存器BE8F9144-48
保存着dex文件的地址。
可以看出寄存器保存的地址为0x7653E008
查看0x7653E018
地址可以看出存储的就是dex文件,dex文件是dex.035
开头的。而0x7653E038-3B
存储着是dex文件的长度25C5BC
把以下脚本保存成dump.py
,通过在file->Script File
,选择dump.py
。然后输入0x7653E018
,输入长度0x25C5BC
,最后输入保存的文件C:\\classes.dex
。
1 | import struct |
把dex文件dump到C盘中,由于是crackme0201
的classes.dex
,如果把dex放回之前博文的crackme0201
的apk中,可以正常启动应用。