-
-
[分享][原创]一次针对反fart的加壳apk的脱壳经历
-
发表于:
2021-9-13 23:33
20134
-
[分享][原创]一次针对反fart的加壳apk的脱壳经历
最近碰到一个加壳的apk,里面有类抽取,并且有做反fart脱壳。后来经过修改fart的源码,幸运地脱壳并还原dex成功。特将脱壳经历记录于此。
此次遇到的壳中两个核心的dex文件中几乎所有的方法的codeitem都抽取了,
庆幸的是,最后还原出来了:
从hanbing大神的github上下载源码:https://github.com/hanbinglengyue/FART。
fart的代码量也不大,其中一部分代码是原来系统的代码,一部分是作者自己加的代码,要想快速知道作者加了哪些代码,可以直接将fart代码文件和相应的系统源码文件(github源码中代码是对应Android 6.0系统的)双选拖到Beyond Compare中,然后作者自加的代码便一目了然(最左侧小红线的地址就是代码差异的地方)。
修改和编辑系统源码的ide,考虑到只是简单的修改一些代码,这里使用了vscode,直接将系统源码根目录导入即可,然后根据vscode提示,安装一些插件也能有一些简单的代码提示和定位功能。
一开始使用fart(fart脱壳机兼frida版fart)时,有两个dex dump下来是类被抽取了,并且codeitem没dump,显然是对fart做了防护。脱壳机中未dump出codeitem截图(frida版fart也没有,这里就不给出截图),如下:
为了排查原因和找到fart哪一步被卡住了,本人缩小排查范围,并在fart源码多个环节打印log,过程如下:
最后排查出是fart在反射调用getClassNameList_method方法时,返回的类名列表为空。针对这个问题,本人处理的方法是将dex的类名手动导出到文件(可以通过010导出类名列表,也可直接使用fart中另一个脱壳点dumpDexFileByExecute导出的类列表,后者更快一些,但前提是得跑一次原始的fart),然后存放到sdcard中,并修改fart源码从sdcard中读取该文件,从而获取dex的所有类名列表。后面的自动调用类方法的流程没有变。
虽然,目前反fart的原因找到了,但离最后脱壳还有一些距离。
接下来运行过程中还碰到了一个问题:类的<clinit>方法的codeitem dump不下来。
<clinit>的methodid不能通过getDeclaredConstructors和getDeclaredMethods获取到,所以原始的fart是没有对<clinit>方法进行主动调用的。后面发现Class.forName(cls)是可以触发cls中的<clinit>调用的,但是使用时,得用"Class.forName(eachclassname, true, appClassloader);",不然在fart代码调用位置默认是使用BootClassLoader,会导致类找不到。因此,把原始fart中获取类的代码修改如下:
fart中还有另一个脱壳点dumpdexfilebyExecute,会将所有执行过的方法都会dump下来。至此,所有的codeitem都获取到了,然后使用hanbing大神提供的fart.py可以将codeitem和dex中反编译代码通过命令行显示出来,对fart.py进行简单修改,可以将codeitem和dex合并,获取完整dex。
如果文中有不对的地方,还请批评指正。脱壳中过程文件和修改的脱壳机代码已加至:https://github.com/Chenyangming9/one-anti-fart-shell-pull,仅供参考。
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2021-9-24 13:12
被Denny Chen编辑
,原因: