0x00 背景
最近在做一个函数的app的脱壳,记录一下遇到的坑。
0x01 步骤
- 将IDA的android_server push 到手机上,启动android_server。
- 转发端口
adb forward tcp:23946 tcp:23946
如果是用gdbserver调试,则转发gdbserver设置的端口,比如
adb forward tcp:9090 tcp:9090
- 启动app:
adb shell am start -D -n com.aaaa.bbbb/com.seworks.medusah.MainActivity
如果你想用gdbserver进行调试,则在进行这个步骤之后用gdbserver attach上进程:
gdbserver64 tcp:9090 --attach [pid]
- 打开android studio,打开ddms。或者用这个命令转发jdwp的端口(mac用):
for pid in `adb shell "ps | grep your.package.name" | awk '{print $2}'`; do adb forward tcp:8700 jdwp:$pid; done
- 打开IDA->Debugger->Attach->Remote ArmLinux/Android debugger,点击OK。
如果你是使用gdb,则使用ndk的gdb输入以下命令连接gdbserver:gdb (gdb)set architecture arm (gdb)target remote :9090 (gdb)set arm force-mode thumb // or arm if the instructions look weird
- 打开IDA->windows->modules,搜索libdvm.so,双击libdvm.so,在新开的tab中搜索dexFileParse,双击该函数,在函数开头按F2设置断点。
- 连接jdb
jdb -connect "com.sun.jdi.SocketAttach:hostname=localhost,port=8700"
- 回到IDA中执行F9直到执行到断点。
- 打开File->Script command,输入:
static main(void) { auto fp, begin, end, dexbyte; fp = fopen("E:\\dump.odex", "wb"); begin = r0; end = r0 + r1; for ( dexbyte = begin; dexbyte < end; dexbyte ++ ) fputc(Byte(dexbyte), fp); }
然后执行
-
取出手机里的所有framework文件:
adb pull /system/framework/ ./framework/
- 根据framework将odex文件转换为smali文件:
java -jar .\baksmali-2.1.2.jar -x .\dump.odex -d .\framework
,此时会生成out文件夹,里面都是smali文件。
-
将smali文件打包为dex文件:
java -jar .\smali-2.1.2.jar out -o classes.dex
- 将dex文件反编译为jar文件:
.\dex2jar-2.0\d2j-dex2jar.bat .\classes.dex
-
使用jd-gui打开classes-dex2jar.jar文件即可查看。
0x02 坑
-
必须把app设置为debuggable,否则即使打开ddms也无法使用
jdb -connect
。为了使所有app变为debuggable,可以使用这个substrate的hook: https://github.com/iSECPartners/Android-OpenDebug -
dump时C盘有可能没有写入权限,所以我们写入E盘。
-
dvmDexFileOpenPartial并没有被执行到,无法在这个函数中设置断点进行dump,据网上的说法是有的壳判断系统版本,OS >= 4.0则使用dvmRawDexFileOpenArray函数,OS <= 4.0则使用dvmDexFileOpenPartial函数。(http://bbs.pediy.com/showthread.php?p=1396042)