python 工程结构加固_【安卓逆向】360加固-脱壳修复
360加固-脱壳修复
最近花了一些时间学习逆向脱壳,这方面一直投入的时间比较少。样本经过某加固宝进行加固,这里简单记录一下脱壳过程和思路,感谢某数字公司对安全加固的无私贡献,让我有机会小小的提高一下这方面的技能。
DUMP classes.dex
打开APK包中的classes.dex看一下:
已经变成了壳代{过}{滤}理,没有一点原APK的代码。在assets中,有两个壳相关的SO:
尝试从内存中DUMP原classes.dex。
考虑到在Dalvik下,360可能会自己实现从内存中加载classes.dex的代码,不容易找到DUMP的点。而ART下,可操作空间就小多了,所以我是在ART下操作的。
具体的,我是在ClassLinker:
efineClass函数处得到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方法还原前后:
由于时间和水平都有限,很多地方还没仔细分析,本篇笔记只是简单记录一下本次操作的大致过程和一些思路。最后,感谢倾听。
转载自→
python 工程结构加固_【安卓逆向】360加固-脱壳修复相关推荐
- 20145307陈俊达_安卓逆向分析_Xposed的hook技术研究
20145307陈俊达_安卓逆向分析_Xposed的hook技术研究 引言 其实这份我早就想写了,xposed这个东西我在安卓SDK 4.4.4的时候就在玩了,root后安装架构,起初是为了实现一些屌 ...
- apk逆向思路_安卓逆向和手游辅助学习路线
一.安卓逆向基础(建议1周) 1. 学习安卓逆向第一步必须先把环境搭建好,这是你学习安卓逆向的开始,环境搭建好后表示正式迈入安卓逆向.在环境安装的工程中会遇到很多细节上的问题. 2. 第二步就是要了解 ...
- android应用加固后闪退,360加固保加固后打开app即闪退
首次使用360加固,完全按照说明操作. 用签名后的apk进行加固,加固选项选择了应用盗版检测和支持x86架构.加固后下载到本地,使用了360提供的签名工具进行签名.签名后安装到手机里,一运行就闪退. ...
- app混淆加固+防止反编译+360加固
android studio混淆加密,没有使用第三方加密后的效果好,混淆加密还能看到大体的混淆包名,使用了那些框架 而使用了360加固后,全部看不到了 下图是360加固window操作IDE,非常好用 ...
- android获取apk名称_安卓逆向——APK安装流程
制丨文生 整理丨阿星 很多学习安卓逆向的朋友大多都会卡在安卓apk上,今天小生就来给大家讲解一下,安装apk的流程,希望能帮助到大家. 安装方式: ⑴系统程序安装 ⑵通过Android市场安装 ⑶手机 ...
- native层 安卓_安卓逆向——拼xx协议java层分析
制丨阿星 整理丨阿星 老铁们大家好,今天小编给大家带来很实用的技巧叫拼xx协议java层分析,有啥不足的地方望大家指点指点! 首先抓包 反编译 这个时间段我们方法剖析一下 找到onclick 看他的 ...
- 4 安卓安装路径_安卓逆向——APK安装流程
很多学习安卓逆向的朋友大多都会卡在安卓apk上,今天小生就来给大家讲解一下,安装apk的流程,希望能帮助到大家. 安装方式: ⑴系统程序安装 ⑵通过Android市场安装 ⑶手机自带安装 ⑷使用ADB ...
- python 工程结构加固_[原创]某企业级加固[四代壳]VMP解释执行+指令还原
现在的VMP的比较常见了,应该也是稳定性满足要求了,今天来分析一波,如有不当还请各位大佬指正 实际上 libdexjni.so在不同的APP中体积会不一样,应该是硬编码写入字符串和指令导致的 1-VM ...
- android 360加固 反编译,[原创]逆向360加固等dex被隐藏的APK
如果遇到apk中的lib文件夹中是这样的 基本没有dex文件可以反编译,这中的dex文件一般都是加密混淆压缩后放在so中啦. 但是软件要想运行就需要解出dex字节码然后加载到手机内存中,这样就可以在软 ...
- java反编译工具_安卓逆向之反编译工具的使用
SMALI/BAKSMALI是一个强大的apk文件编辑工具,用于Dalvik虚拟机(Google公司自己设计用于Android平台的虚拟机)来反编译和回编译classes.dex.其语法是一种宽松式的 ...
最新文章
- C#如何进行多线程编程
- linux 进程的作用,linux的几个进程的作用
- CI/CD 最佳实践的基本原则
- CodeForces - 1208E Let Them Slide(模拟+multiset)
- 基于 Nginx 的 HTTPS 性能优化实践
- 主机排行网重大更新,移动端自适应
- black-box优化——第二篇:直接搜索算法
- [转载] 【全面总结】Tensorflow 2.0+与Keras的联系与应用(含model详解)
- 为什么人很难承认自己的错误?
- c语言关于内存编程,c语言内存
- 在国外当程序员到底爽不爽?
- CAJ格式文件怎么转换为PDF格式
- java判断名字是否为张三_现有5个学生{张三,李四,王五,那六,小七}的数组,输入一个姓名,检查姓名是否存在,如果java啊...
- SIRO Challenge 状态压缩 + DP 未解
- 成都拓嘉辰丰:拼多多新手开店需掌握的运营方向
- P1757 通天之分组背包(动态规划 分组背包)
- 深入计算机组成原理(四)穿越功耗墙,我们该从哪些方面提升“性能”?
- qt编写网易云界面(3)----列表框的实现
- winrar主要参数
- paper:DeepAR: Probabilistic forecasting with autoregressive recurrent networks DeepAR模型
热门文章
- [4G/5G/6G专题基础-158]: 5G VoNR(Voice over NR)与VoLTE共同组成5G三大语音方案
- GnuCash 3.5 发布,跨平台财务管理软件
- 展望新型少儿编程教学理念
- AutoHotKey
- [幽默笑话]超漂亮的美女 任你点 [超级好玩](转载)
- 大数据如何助力营销(3)产品定位
- 九月十月百度人搜,阿里巴巴,腾讯华为小米搜狗笔试面试五十题
- word保存时内存不足
- 【面试】以面试者的角度回答Vue中的diff算法(附图示diff运算过程)
- 在Vue中对百度地图组件mapv的使用