吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 41320|回复: 105
收起左侧

[Android 脱壳] 某数字公司VMP脱壳简记

    [复制链接]
S18 发表于 2017-12-24 18:56
本帖最后由 S18 于 2017-12-24 19:33 编辑

0x00
最近花了一些时间学习逆向脱壳,这方面一直投入的时间比较少。样本经过某加固宝进行加固,这里简单记录一下脱壳过程和思路,感谢某数字公司对安全加固的无私贡献,让我有机会小小的提高一下这方面的技能。
本篇笔记同时贴在博客中:https://www.jianshu.com/p/d057b3fa3cbc
0x01 DUMP classes.dex
打开APK包中的classes.dex看一下:
image002.png
已经变成了壳代{过}{滤}理,没有一点原APK的代码。assets中,有两个壳相关的SO
image004.png
尝试从内存中DUMPclasses.dex
考虑到在Dalvik下,360可能会自己实现从内存中加载classes.dex的代码,不容易找到DUMP的点。而ART下,可操作空间就小多了,所以我是在ART下操作的。
具体的,我是在ClassLinker::DefineClass函数处得到dex_filebeginsize,然后DUMP出原来的classes.dex。我看到有人在dex2oat的地方DUMP,但我觉得如果360 HOOK execv,阻止dex2oat对原classes.dexoat转换的话,会不会就脱不出来了呢?不过我对Android虚拟机不太了解,可能有更好的DUMP点。
成功DUMP出原classes.dex
image006.png
但是可以看到,有些方法(图中onCreate)的指令被抽走了,并且改为了native方法。同时,在static代码块中,有一行调用StubApp.interface11(16)
可以猜测:当该class被加载时,static代码块会首先被执行,这样StubApp.interface11方法就会将onCreate注册到壳SO的某个native方法上。这样,当执行onCreate时,就会执行相应的native方法,该native方法会首先找到onCreate对应的指令,然后解密,最终解释执行。
interface11以及onCreate对应的native方法,以及解释器并没有实现在上图中的libjiagu.so中,而是实现在另一个运行时从内存中加载的SO中(暂且称其为解释器SO)。
0x02 DUMP解释器SO
APK运行后,会首先加载libjiagu.so,并执行其JNI_Onload方法。该方法最终会调用到__fun_a_18,这个方法进行了控制流混淆,流程对于我来说是非常复杂的。
image008.png
刚开始,我以为它用了o-llvm进行混淆编译。但仔细看一下汇编代码,应该不是。应该就是自己在源码中利用while-switch实现了“控制流平坦化”的混淆算法。
怎么破?我没有什么好办法,只有硬看,不断的调试,参考大神们的帖子。
由于我手机是自己编译的系统,对于某些反调试天然免疫,所以遇到的反调并不多。下面简述我是怎么过反调并DUMP出解释器SO的,因为这个混淆算法应该每个版本都有所变化,所以这个流程并不一定适用别的样本。
第一处反调,来自case 37
image010.png
继续执行:
image012.png
来到这个位置,看到R3保存的是rtld_db_dlactivity符号的地址,我担心它是要作SIGTRAP信号反调,所以手动将R3的值修改为0
继续执行。当第4次进入case 32时:
image014.png
继续执行,来到下面的位置:
image016.png
注意此时R1的值,要将600B0010修改为200B0010,否则会执行R4地址处的代码。
R4地址处的代码是什么?看一下:
image018.png
就是终止进程的代码。
过了此处反调之后,继续执行,来到case 31
image020.png
继续,来到如下位置,这里就是加载解释器SO的函数了。
image022.png
注意,这里不是通过调用dlopen函数来加载解释器SO的,而是自己实现的类似于linker的加载代码。
其实linker的工作原理并不复杂,简单来说就是将目标SO文件的LOAD段映射内存,解析文件格式,做好符号重定位,再调用init/init_array方法等等。
继续执行,来到解密ELF Header的地方:
image024.png
解密完毕:
image026.png
根据R3的值,将ELF HeaderDUMP出来。
image028.png
image030.png
继续执行,来到解密Program Header的地方:
image032.png
解密完毕:
image034.png
Program HeaderDUMP出来:
image036.png
继续执行,来到如下位置:
image038.png
这个方法是要将解释器SOLOAD段映射到内存,然后完成整个加载过程。
根据so_addrso_size将整个SO DUMP出来,但这里DUMP出来的SO是没有ELF HeaderProgramHeader的,但这两个头前面已经DUMP出来了。最后三者拼在一起,就是完整的解释器SO了。
image040.png
image042.png
0x03 还原onCreate
有了解释器SO,就可以继续分析了,核心的内容都在这个SO里面。
由于我编译的系统,加了很多日志,所以在执行到前面的onCreate方法时,看到如下日志:
image044.png
就像前面猜测的那样,当执行该onCreate方法时,先执行classstatic代码块,调用interface11方法,该方法将onCreate注册到了一个地址为0x75c74e2dnative方法上。该native方法就实现在解释器SO中。用0x75c74e2d减去load_base,可知是解释器SO中的sub_10E2C方法。
image046.png
跟踪并分析该方法。
继续动态调试,在解释器SO中偏移0xFAAE处下断点:
image048.png
观察此时R1寄存器的值为0xBE027450,跳到该处内存,并得到0xBE027458处的值为0x75EA5418
跳到0x75EA5418内存处。
050.png
观察0x75EA5418内存处的值,得到本次解释执行的方法是:com.xxx.xxxActivity->onCreate
继续,在解释器SO中偏移0x35C80处下断点:
052.png
观察此时R7寄存器的值为0x75E96A10,在Hex View中,跳到0x75E96A10内存处:
054.png
观察此时0x75E96A18地址处存储的值为0x7699C61C,在Hex View中跳到0x7699C61C内存处:
056.png
0x7699C61C内存处存储的就是DexCode结构,DexCode的结构定义如下:
image058.png
由此可知“com.xxx.xxxActivity->onCreate”方法的insns指令数组大小是0x93*2=294个字节,指令数据流是:
image060.png
这个指令数据流是经过加密的,解密key存储在0x75E96A2C地址处,值为0x3B
继续调试的话,就是执行switch型的解释器了。这个解释器和Dalvik解释器类似。在android2.x版本中曾有2种形式的C实现的解释器,一种goto的,一种switch的。后来谷歌把switch型解释器去掉了,因为执行效率没有goto的好。再后来就有了ART,貌似把C语言实现的解释器都去掉了。再再后来到了7.0gotoswitch型的C解释器又都回来了。
image062.png
简单来说,就是解释执行整个onCreate方法的指令数据流,每条指令在执行前会解密。那怎么将这些指令还原回原本的dalvik字节码指令,达到脱壳目的呢?可以根据每个case的实现,来得到当前执行的opcode对应dalvik字节码指令中的哪一条,然后对应还原。
064.png
比如,这里的0xAE,在解释执行时,跳转到case 174处执行。假设拿case 174处的代码对比分析Dalvik解释器,发现case 174执行的是invoke-static指令,那么这条指令就还原出来了。 066.png
这样有点麻烦。
有一个好点的办法就是:自己在onCreate方法中将所有的dalvik指令,一共200多条全部写出来。然后用360加固,动态调试,总结出每条dalvik指令对应的360解释器的case处理指令的偏移,最后得到一张指令映射表。这样,后续在脱壳的时候,就可以根据解释执行代码的偏移,还原出原来的指令。当然,360解释器也是在不断变化的,所以,这个表也是要跟着变化的。
那能写自动脱壳机吗?只要这张指令映射表是有效的,脱壳就可以自动化完成。
那如果指令映射表失效了,能通过代码自动生成新的指令映射表吗?仔细分析解释器,每个指令的处理逻辑没大变化的,也许可以。
扯远了,下图是某个onCreate方法还原前后:
image068.png
0x04 后序
由于时间和水平都有限,很多地方还没仔细分析,本篇笔记只是简单记录一下本次操作的大致过程和一些思路。最后,感谢论坛中各大神的分享,让我学习到了很多东西。
End

免费评分

参与人数 50吾爱币 +54 热心值 +47 收起 理由
九袋 + 1 + 1 我很赞同!
遇到你是我的缘 + 1 + 1 我很赞同!
15237633705 + 1 + 1 用心讨论,共获提升!
吾爱木天 + 1 + 1 用心讨论,共获提升!
ripples + 1 + 1 用心讨论,共获提升!
堂前燕 + 1 + 1 我很赞同!
hmd111 + 1 + 1 用心讨论,共获提升!
dryzh + 2 + 1 666
王亦棋 + 1 + 1 用心讨论,共获提升!
?﹏從此沉默 + 1 + 1 已答复!
wuhanbin + 1 + 1 用心讨论,共获提升!
no_one + 1 + 1 谢谢@Thanks!
C-ARan + 1 热心回复!
快乐交友 + 1 + 1 热心回复!
2864095098 + 1 热心回复!
sunnylds7 + 1 + 1 谢谢@Thanks!
Emoei_PG + 1 + 1 用心讨论,共获提升!
kylinpapa + 1 + 1 用心讨论,共获提升!
Ravey + 1 + 1 谢谢@Thanks!
MaxMadcc + 1 + 1 谢谢@Thanks!
滚雪球 + 1 谢谢@Thanks!
bigkat + 1 + 1 我很赞同!
太冲 + 1 + 1 谢谢@Thanks!
我爱你一万年 + 1 + 1 谢谢@Thanks!
zym8058 + 1 + 1 用心讨论,共获提升!
SorryyyX + 1 + 1 用心讨论,共获提升!
luozh7682 + 1 + 1 热心回复!
294380915 + 1 + 1 我很赞同!
没有如果儿 + 1 + 1 我很赞同!
乖含住 + 1 + 1 用心讨论,共获提升!
无痕软件 + 1 + 1 用心讨论,共获提升!
liuanta + 1 + 1 高手啊,佩服啊,学习了。
依旧沉沉 + 1 + 1 我很赞同!
MXWXZ + 3 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
YYL7535 + 1 + 1 谢谢@Thanks!
h080294 + 1 + 1 用心讨论,共获提升!
七个八个九个 + 1 + 1 我很赞同!
arryboom + 2 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
wnagzihxain + 3 + 1 写的很棒
luhaohaovip + 1 + 1 谢谢@Thanks!
Tim-52Pojie + 1 + 1 谢谢@Thanks!
pk8900 + 1 + 1 写的真详细!
zhishui + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
whklhh + 2 + 1 谢谢@Thanks!
kilkilo502 + 1 + 1 用心讨论,共获提升!
超级无敌大帅逼 + 1 + 1 用心讨论,共获提升!
嚣张的猪 + 1 用心讨论,共获提升!
疯狂醉虎 + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
610100 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
wmsuper + 1 + 1 已答复!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

禁止盗版 发表于 2017-12-24 22:58
厉害                              了
轩轩1018 发表于 2017-12-24 20:14
楼主大神级的,手机是自己编译的系统,光这点就膜拜了
lghlth 发表于 2017-12-24 18:58
winding 发表于 2017-12-24 19:20
需要这个,但是看得一头雾水,补基础去了。。。。
烟尘沐雨丶 发表于 2017-12-24 19:21
鼓掌鼓掌,厉害了。
_pan 发表于 2017-12-24 20:04
学习了,好文章
6767 发表于 2017-12-24 21:10

兹磁认真分析
lyliucn 发表于 2017-12-24 21:25
厉害 学习了
疯狂醉虎 发表于 2017-12-24 21:33
不明觉厉!感谢分享!
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-15 13:28

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表