欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

[原创]360加固之onCreate函数还原并重打包

[原创]360加固之onCreate函数还原并重打包

断断续续弄360的壳子搞了个把月,把这次的成果分享给大家。。。


在还原之前,我们需要一份360加固的指令映射表,感谢https://bbs.pediy.com/thread-222412.htm这篇文章提供的指令映射表,我对这个表进行了补全,包含所有的Dalvik opcode

struct DexCode {

u2  registersSize;           

u2  insSize;        

u2  outsSize;                

u2  triesSize;               

u4  debugInfoOff;      

u4  insnsSize;          

u2  insns[1];            

};


对于native onCreate函数的DexCode,前0x10个字节没有加密, 后面的insns被360加密了,我们需要做的就是将insns指令还原,

加密的insns指令以及解码insns指令的key值都是通过parse_tree这个函数得到的,其中第一个参数是一个全局变量,第二个参数是"类名->方法名"


虽然可以手动改变第二个参数为不同类的onCreate方法,来获取不同方法的加密指令insns,但是我分析的样本是360自家的一个App,共有49个native onCreate函数,手动弄很麻烦,


手动调用parse_tree函数

还原的核心思路就是手动调用parse_tree函数,

由于parse_tree函数是在360的第二个so里面,而且是通过内存加载的方式来加载这个so,这里我们来进行“ 二阶Hook ” 获取parse_tree函数地址


首先Hook dlopen函数得到libjiagu.so的基址,在new_dlopen函数中内存加载函数soMemLoader


在new_soMemLoader函数中,调用完原始函数后,表示第二个so已经内存加载完成,并且初始化了init和init_array函数,根据偏移获取parse_tree函数地址,获取第一个参数使用全局变量,但是我们需要保证这个全局变量指向的内容是初始化了的,所以我们可以继续在这里Hook JNI_OnLoad函数,等JNI_OnLoad执行完以后,保证全局变量所在的内存数据是正确的。


在new_JNI_OnLoad函数中,当JNI_OnLoad函数执行完以后,就开始还原所有的onCreate函数了。


手动调用parse_tree函数进行解密


还原过程中有几个坑需要注意

1.Try/Catch的处理

2.packed-switch,sparsed-switch,fill-data指令的处理


修复之后jeb和jadx可以完美地反编译onCreate函数了。


重打包

原始的Application其实保存在strEntryApplication = "com.qihoo360.crypt.entryRunApplication",在JNI_OnLoad中动态修改为原始的Application了,com/stub/StubApp的strEntryApplication成员

替换为com.qihoo.root.AuthApp

一般第一个activity都没变,但是我这个样本的启动activity不是原始的dex,而是360自带的一个dex,将类"com/stub/stub01/StartActivity"的成员mEntryActivity替换为com.qihoo.root.SplashActivity

还有一些小细节懒得说了。


不过360最新的dex vmp好像没用指令映射表,本文的方法应该可以适用最新版本以前的。。。


上传的附件 代码和样本.z04
代码和样本.z03
代码和样本.z02
代码和样本.z01
代码和样本.z05
代码和样本.z06
代码和样本.z07
代码和样本.zip

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功