360加固-脱壳修复

最近花了一些时间学习逆向脱壳,这方面一直投入的时间比较少。样本经过某加固宝进行加固,这里简单记录一下脱壳过程和思路,感谢某数字公司对安全加固的无私贡献,让我有机会小小的提高一下这方面的技能。

DUMP classes.dex

打开APK包中的classes.dex看一下:

已经变成了壳代{过}{滤}理,没有一点原APK的代码。在assets中,有两个壳相关的SO:

尝试从内存中DUMP原classes.dex。

考虑到在Dalvik下,360可能会自己实现从内存中加载classes.dex的代码,不容易找到DUMP的点。而ART下,可操作空间就小多了,所以我是在ART下操作的。

具体的,我是在ClassLinker::DefineClass函数处得到dex_file的begin和size,然后DUMP出原来的classes.dex。我看到有人在dex2oat的地方DUMP,但我觉得如果360 HOOK execv,阻止dex2oat对原classes.dex作oat转换的话,会不会就脱不出来了呢?不过我对Android虚拟机不太了解,可能有更好的DUMP点。

成功DUMP出原classes.dex:

但是可以看到,有些方法(图中onCreate)的指令被抽走了,并且改为了native方法。同时,在static代码块中,有一行调用StubApp.interface11(16)。

可以猜测:当该class被加载时,static代码块会首先被执行,这样StubApp.interface11方法就会将onCreate注册到壳SO的某个native方法上。这样,当执行onCreate时,就会执行相应的native方法,该native方法会首先找到onCreate对应的指令,然后解密,最终解释执行。

interface11以及onCreate对应的native方法,以及解释器并没有实现在上图中的libjiagu.so中,而是实现在另一个运行时从内存中加载的SO中(暂且称其为解释器SO)。

DUMP解释器SO

APK运行后,会首先加载libjiagu.so,并执行其JNI_Onload方法。该方法最终会调用到__fun_a_18,这个方法进行了控制流混淆,流程对于我来说是非常复杂的。

刚开始,我以为它用了o-llvm进行混淆编译。但仔细看一下汇编代码,应该不是。应该就是自己在源码中利用while-switch实现了“控制流平坦化”的混淆算法。

怎么破?我没有什么好办法,只有硬看,不断的调试,参考大神们的帖子。

由于我手机是自己编译的系统,对于某些反调试天然免疫,所以遇到的反调并不多。下面简述我是怎么过反调并DUMP出解释器SO的,因为这个混淆算法应该每个版本都有所变化,所以这个流程并不一定适用别的样本。

第一处反调,来自case 37:

继续执行:

来到这个位置,看到R3保存的是rtld_db_dlactivity符号的地址,我担心它是要作SIGTRAP信号反调,所以手动将R3的值修改为0。

继续执行。当第4次进入case 32时:

继续执行,来到下面的位置:

注意此时R1的值,要将600B0010修改为200B0010,否则会执行R4地址处的代码。

R4地址处的代码是什么?看一下:

就是终止进程的代码。

过了此处反调之后,继续执行,来到case 31:

继续,来到如下位置,这里就是加载解释器SO的函数了。

注意,这里不是通过调用dlopen函数来加载解释器SO的,而是自己实现的类似于linker的加载代码。

其实linker的工作原理并不复杂,简单来说就是将目标SO文件的LOAD段映射内存,解析文件格式,做好符号重定位,再调用init/init_array方法等等。

继续执行,来到解密ELF Header的地方:

解密完毕:

根据R3的值,将ELF Header先DUMP出来。

继续执行,来到解密Program Header的地方:

解密完毕:

将Program Header也DUMP出来:

继续执行,来到如下位置:

这个方法是要将解释器SO的LOAD段映射到内存,然后完成整个加载过程。

根据so_addr和so_size将整个SO DUMP出来,但这里DUMP出来的SO是没有ELF Header和ProgramHeader的,但这两个头前面已经DUMP出来了。最后三者拼在一起,就是完整的解释器SO了。

还原onCreate

有了解释器SO,就可以继续分析了,核心的内容都在这个SO里面。

由于我编译的系统,加了很多日志,所以在执行到前面的onCreate方法时,看到如下日志:

就像前面猜测的那样,当执行该onCreate方法时,先执行class的static代码块,调用interface11方法,该方法将onCreate注册到了一个地址为0x75c74e2d的native方法上。该native方法就实现在解释器SO中。用0x75c74e2d减去load_base,可知是解释器SO中的sub_10E2C方法。

跟踪并分析该方法。

继续动态调试,在解释器SO中偏移0xFAAE处下断点:

观察此时R1寄存器的值为0xBE027450,跳到该处内存,并得到0xBE027458处的值为0x75EA5418。

跳到0x75EA5418内存处。

观察0x75EA5418内存处的值,得到本次解释执行的方法是:com.xxx.xxxActivity->onCreate。

继续,在解释器SO中偏移0x35C80处下断点:

观察此时R7寄存器的值为0x75E96A10,在Hex View中,跳到0x75E96A10内存处:

观察此时0x75E96A18地址处存储的值为0x7699C61C,在Hex View中跳到0x7699C61C内存处:

在0x7699C61C内存处存储的就是DexCode结构,DexCode的结构定义如下:

由此可知“com.xxx.xxxActivity->onCreate”方法的insns指令数组大小是0x93*2=294个字节,指令数据流是:

这个指令数据流是经过加密的,解密key存储在0x75E96A2C地址处,值为0x3B。

继续调试的话,就是执行switch型的解释器了。这个解释器和Dalvik解释器类似。在android2.x版本中曾有2种形式的C实现的解释器,一种goto的,一种switch的。后来谷歌把switch型解释器去掉了,因为执行效率没有goto的好。再后来就有了ART,貌似把C语言实现的解释器都去掉了。再再后来到了7.0,goto和switch型的C解释器又都回来了。

简单来说,就是解释执行整个onCreate方法的指令数据流,每条指令在执行前会解密。那怎么将这些指令还原回原本的dalvik字节码指令,达到脱壳目的呢?可以根据每个case的实现,来得到当前执行的opcode对应dalvik字节码指令中的哪一条,然后对应还原。

比如,这里的0xAE,在解释执行时,跳转到case 174处执行。假设拿case 174处的代码对比分析Dalvik解释器,发现case 174执行的是invoke-static指令,那么这条指令就还原出来了。

这样有点麻烦。

有一个好点的办法就是:自己在onCreate方法中将所有的dalvik指令,一共200多条全部写出来。然后用360加固,动态调试,总结出每条dalvik指令对应的360解释器的case处理指令的偏移,最后得到一张指令映射表。这样,后续在脱壳的时候,就可以根据解释执行代码的偏移,还原出原来的指令。当然,360解释器也是在不断变化的,所以,这个表也是要跟着变化的。

那能写自动脱壳机吗?只要这张指令映射表是有效的,脱壳就可以自动化完成。

那如果指令映射表失效了,能通过代码自动生成新的指令映射表吗?仔细分析解释器,每个指令的处理逻辑没大变化的,也许可以。

扯远了,下图是某个onCreate方法还原前后:

由于时间和水平都有限,很多地方还没仔细分析,本篇笔记只是简单记录一下本次操作的大致过程和一些思路。最后,感谢倾听。

某数字公司VMP脱壳简记---native的OnCreate还原相关推荐

  1. H网、某播放器、某数字公司是一根绳上的三个蚂蚱

    最近在百度知道.搜搜问问.论坛.QQ群里,每天都有大量用户求助,说自己的浏览器被劫持,电脑不停弹广告,因中的***太多,什么奇怪的现象都会发生,有的用户电脑上还检测到了鬼影病毒,吓得要重装系统.而出现 ...

  2. 个人总结的一个VMP脱壳步骤

    个人总结的一个VMP脱壳步骤     个人在学习脱VMP加壳的过程中总结的一个步骤.按照这个步骤,包括VMP1.6-2.0在内应该有70%-80%能脱壳.脱不了的也别问我,我也刚开始学习.我还想找人问 ...

  3. 「娃娃分享」-个人总结的一个VMP脱壳步骤.

    个人总结的一个VMP脱壳步骤     个人在学习脱VMP加壳的过程中总结的一个步骤.按照这个步骤,包括VMP1.6-2.0在内应该有70%-80%能脱壳.脱不了的也别问我,我也刚开始学习.我还想找人问 ...

  4. 关于360的一些理解(不是黑数字公司的)

    作为一个菜鸟,我没法子静下心去好好去学linux的命令行,这的确是我的大错特错,不过东西学的不多,但是精髓得到了不少,我说的精髓不是指这里面的精华啊,linux内核的大部分最近几天有点耽误都没用下心和 ...

  5. 为什么“数据驱动”只属于那些“天生的数字公司”,传统企业却只有束缚?...

    快速失败,更快学习:在颠覆.大数据和人工智能时代的数据驱动领导力课程中,Randy Bean 指导传统企业进行数字化转型的"长期旅程",以及实现"数据驱动型领导" ...

  6. 2010.09.28_ximo_纠正下VMP脱壳中的修复DLL的错误

    http://hi.baidu.com/ximo2006/blog/item/ff0d3211f139f7def6039e75.html 用来纠正下<也来谈谈VMP2.05的脱壳>中,那个 ...

  7. 音频数字合成器:KORG Opsix Native Mac

    KORG Opsix Native Mac 是一款与众不同的数字合成器,具有可匹配的声音.立即探索数百种新鲜.前沿的声音,激发您的下一个音乐项目!借助触手可及的定制功能走得更远.前面板彩色控件可轻松实 ...

  8. 个人总结的一个VMP脱壳步骤.

    042A000 0012F670   000069DE  |Size = 69DE (27102.) 0012F674   00000002  |NewProtect = PAGE_READONLY ...

  9. [转] 菜鸟手脱VMP,附上脱壳过程和自己写的脚本,可跨平台

    转载:http://www.52pojie.cn/thread-467703-1-1.html 工作需要要脱一个VMP壳,我是一个从来没接触过脱壳的人.瞬间那种心情遇到的人应该都知道!没办法硬着头皮找 ...

最新文章

  1. 硬回车与软回车[转]
  2. systemctl和service
  3. 将程序添加到自动启动
  4. wxWidgets:最小的 wxWidgets 示例
  5. 魔兽争霸Ⅲ运行时不能初始化directX的错误解决
  6. lora技术在无线抄表行业应用
  7. 我的特长是计算机VF编程,2016计算机二级考试VF模拟题及答案
  8. 两相电机倒顺开关的接法是什么?
  9. Spark mapPartition方法与map方法的区别
  10. 苹果手机远程服务器桌面,如何进行远程管理?如何实现苹果手机远程管理电脑?...
  11. Java教程(一)---JDK和Maven安装配置
  12. vue报错RangeError: Maximum call stack size exceeded
  13. 计算机病毒主要是通过什么传播,计算机病毒主要是通过什么传播
  14. 光储直流微电网能量管理。 系统主要由光伏发电模块、mppt控制模块、混合储能系统模块、直流负载模块、改进前的soc限值管理控制模块
  15. 可视化学习:可视化布局方法简介及优缺点
  16. 【前沿技术】在安全且可靠的区块链基础设施中运行业务条线应用
  17. 目前大数据分析的发展状况是怎样
  18. 分享一个自己做的一个3DM手机客户端
  19. 《ImageNet Classification with Deep Convolutional Neural Networks》翻译
  20. 苹果a10处理器_苹果“芯”基建简史:自己掌握不了核心技术 乔布斯也得干着急...

热门文章

  1. 蓝魔RM970升级为2.4
  2. pymatgen正确安装姿势
  3. 项目实训(校园互助平台)
  4. pdf转换器的注册码
  5. windows提示“你可能是盗版软件受害者”的解决方法
  6. 类初始化与实例初始化
  7. Camera ITS当中的部分测试项文档
  8. 【操作系统】30天自制操作系统--(18)应用程序
  9. Angular4 失焦与点击冲突处理
  10. 单纯形法表格法例题详解_最优化单纯形法例题讲解