转载自http://drops.wooyun.org/tips/6840
在现在的移动安全环境中,程序加壳已经成为家常便饭了,如果不会脱壳简直没法在破解界混的节奏。ZJDroid作为一种万能脱壳器是非常好用的,但是当作者公开发布这个项目后就遭到了各种加壳器的针对,比如说抢占ZJDroid的广播接收器让ZJDroid无法接收命令等。我们也会在”安卓动态调试七种武器之多情环 - Customized DVM”这篇文章中介绍另一种架构的万能脱壳器。但工具就是工具,当我们发布的时候可能也会遭到类似ZJDroid那样的针对。所以说手动脱壳这项技能还是需要学习的。在这一节中我们会介绍一下最基本的内存dump流程。在随后的文章中我们会介绍更多的技巧。
这里我们拿alictf2014中的apk300作为例子来介绍一下ida脱简单壳的基本流程。 首先我们用调试JNI_OnLoad的技巧将程序在运行前挂起:
adb shell am start -D -n com.ali.tg.testapp/.MainActivity
![enter image description here][59]
然后在libdvm.so中的dvmDexFileOpenPartial函数上下一个断点:
然后我们点击继续运行,程序就会在dvmDexFileOpenPartial()这个函数处暂停,R0寄存器指向的地址就是dex文件在内存中的地址,R1寄存器就是dex文件的大小:
然后我们就可以使用ida的script command去dump内存中的dex文件了。
1
2
3
4
5
6
7
8
9
|
static main( void )
{ auto fp, begin, end, dexbyte;
fp = fopen ( "C:\\dump.dex" , "wb" );
begin = r0;
end = r0 + r1;
for ( dexbyte = begin; dexbyte < end; dexbyte ++ )
fputc (Byte(dexbyte), fp);
} |
Dump完dex文件后,我们就可以用baksmali来反编译这个dex文件了。
因为过程有点繁琐,我录制了一个dump dex文件的视频在我的github,有兴趣的同学可以去下载观看。
当然这只是最简单脱壳方法,很多高级壳会动态修改dex的结构体,比如将codeoffset指向内存中的其他地址,这样的话你dump出来的dex文件其实是不完整的,因为代码段保存在了内存中的其他位置。但你不用担心,我们会在随后的文章中介绍一种非常简单的解决方案,敬请期待。