1.配置环境

一台已root手机
IDA pro6.6
Android SDK

准备工作:
1.1把Android SDK添加到环境变量中
1.2把已root手机的系统中关键so拖到本地,必要时可以静态读取,获取系统函数的偏移地址。
例如把手机系统的system/lib的文件拖到本地debugging文件夹中。

adb pull /system/lib .\debugging\lib

1.3在IDA pro6.6中找出android_server,并把android_server放到手机system/bin中。push的时候没有root权限,可以如下操作:

adb push android_server /data/local/tmp
adb shell
su
cp /data/local/tmp/android_server /system/lib

2.环境启动

由于需要调试程序启动加载的so,所以步骤比较多。
2.1进入adb shell,在手机中执行android_server。

adb shell
su
android_server

2.2进行端口转发

adb forward tcp:23946 tcp:23946

2.3使用调试模式启动程序,adb shell am start -D -n 包名/类名,以上一篇博文的dexunshellram为例,dexunshellram动态加载了crackme0201,启动命令如下:

adb shell am start -D -n com.droider.dexunshellram/com.droider.crackme0201.MainActivity

2.4打开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。如果你觉得你用不着调试系统函数,可以不用指定。
image0
2.5在Android SDK中找出ddms.bat,双击打开,为了后面执行jdb。
2.6在IDA中点击运行或者按F9,然后在cmd中运行一下命令启动jdb

jdb -connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8700

2.7IDA在linker中停下了,然后在path中找到相应调试的libunshellram.so,选择函数Java_com_droider_dexunshellram_unshellram_loadDex,这里是内存动态加载dex的地方。在else语句之前进行断点,就是loc_前一行插入断点,按F2,然后再运行程序,按F9。

3.dump内存

如下图所示,R0寄存器BE8F9144-48保存着Dex文件的地址。
image1
可以看出寄存器保存的地址为0x7653E008
image2
查看0x7653E018地址可以看出存储的就是DEX文件,DEX文件是dex.035开头的。而0x7653E038-3B存储着是DEX文件的长度25C5BC
image3
把以下脚本保存成dump.py,通过在file->Script File,选择dump.py。然后输入0x7653E018,输入长度0x25C5BC,最后输入保存的文件C:\classes.dex。

import struct
def dumpdex(start, len, target):
	rawdex = idaapi.dbg_read_memory(start, len)
	fd = open(target, 'wb')
	fd.write(rawdex)
	fd.close()

def getdexlen(start):
	pos = start + 0x20
	mem = idaapi.dbg_read_memory(pos, 4)
	len = struct.unpack(' 0 and start > 0x0 and target and AskYN(1, 'start is 0x%0x, len is %d, dump to %s' % (start, len, target)) == 1:
	dumpdex(start, len, target)
	print('Dump Finish')

把dex文件dump到C盘中,由于是crackme0201的classes.dex,如果把dex放回之前博文的crackme0201的apk中,可以正常启动应用。

更多