脱壳入门
hook , 抓包,调试和反调试等安卓逆向基础知识都学了,刚准备成就一番事业,出门遇到大boss 360加固,要么就是梆梆加固企业版,打开app就是网络错误,或闪退或连不上网,源码是看不到的,frida一启动就是process terminated,根本无从下手,深感无力,感觉还是功力尚浅,故欲深究加壳和脱壳。
简要原理和过程
主流是写一个代理Application,加载so文件,so里面写dex文件的解密逻辑,再用DexClassLoader加载解密后的dex文件。
要懂一点双亲委派机制,Dex文件结构等知识,具体就不多写了,可以见:[原创]Android漏洞之战(11)——整体加壳原理和脱壳技巧详解-Android安全-看雪-安全社区|安全招聘|kanxue.com 以及这篇文章里的提到的其他链接
例如梆梆加固免费版,这里我用的apk是吾爱破解论坛安卓逆向这档事的demo,梆梆加固注册个账号,把apk传上去加固下再下下来就行,jadx打开
尝试IDA打开,函数名基本都是没啥规律的,点开也是JUMP_OUT(地址),要么是一堆LABEL混淆过的,看不明白。
咋办呢,那就从内存里下手呗。例如frida-dexdump。
原理是这样的,/proc/<pid>/maps放了这个进程分配的所有内存块索引,然后在这些内存块里寻找dex文件特征的部分,如果能匹配到就dump到文件里。
梆梆加固免费版会有frida的检测,可以用frida魔改版server:Release 16.6.6 · Ylarod/Florida
大致的魔改原理可以见:《安卓逆向这档事》十八、表哥,你也不想你的Frida被检测吧!(上) - 吾爱破解 - 52pojie.cn
究其根源还是要看frida的源码,看看可能会有什么特征。如果未来遇到魔改server也不起作用的话,还要深入研究一下这块。
frida-dexdump -U -f com.zj.wuaipojie
拿到20个dex文件,jadx打开:
可以看到成功脱壳。
frida-dexdump脚本原理
frida-dexdump/agent/src/index.ts at master · hluwa/frida-dexdump
这里只写关键函数,主要看searchDex,分为普通搜索和深度搜索,先看普通的:
先检查文件头特征”64 65 78 0a 30….”,假如有的话,先检测路径是否为/data/dalvik-cache或/system,如果是的话直接return(系统的dex),然后调用verify函数验证。
先看0x70是否比这块内存大(0x70是dex文件头大小,如果都没这个大,那这块肯定不是dex文件),然后根据maps来判断,关键在verify_by_maps方法。
0x34
是 DEX 文件头(Dex Header)中的 map_off
偏移量,用于获取 map_list
的地址,然后遍历。
1 |
|
遍历的是DexMapItem结构,每个大小为0xC,然后判断类型是否为”TYPE_MAP_LIST”。也就是item_type === 4096这一行。这个类型里的offset表示map_list本身的偏移地址。
所以把之前获取的和TYPE_MAP_LIST里的对比下就能判断是否为完整DEX文件了。
deepsearch部分,检测70 00 00 00
在 DEX 文件头(Header)中,**偏移 0x0C
处存储了 header_size
**,它表示 DEX 头部的大小,永远是0x70 (112)
并且还考虑了magic字段被抹去的情况dex_base.readCString(4) != "dex\n"
,还多了一个verify_ids_off
这里是dex文件里各种重要字段的偏移,要比dex文件本身小,比文件头大(0x70)
剩下的就不写了。
其他方法
假如打乱了内存里dex文件的内容,这该怎么办?frida-dexdump肯定就没辙了。在App的启动流程里,DexFile数据结构是一个重要的角色,不管怎么加密解密,随便折腾,最后都要经过这个数据结构。所以hook dexfile相关的函数,也可以实现脱壳。
ida打开libart.so,看雪里的文章中挑选的是这个函数。
第一个参数就是Dexfile,ida应该是自动处理了?得找到原来的名字。
鼠标放上面,按X查看引用下,然后copy出来即可。
frida脚本:
1 |
|
frida -f -U com.zj.wuaipojie -l unpack.js
运行成功后pull出来
成功拿到源码!
思考总结
假如,假如说,直接重写DexFile的加载,这该怎么办?也看了一些其他文章,说目前最新的技术是啥vmp保护。总之要走的路还很长,慢慢学吧。