这玩意儿实在是有点恶心,各种骚操作来浪费你的时间。比如把jni接口的函数全部重新排列了一遍,你得在他赋值的时候手动去把两百多个函数复制过来。把if-else的分支跳转地址全放在数组里面,f5生成伪代码全是JUMPOUT,你得手动去修复所有地址。。。
自己随便新建个项目,用360加固保去加固。加固后apk包如下所示。原来的class都没了,assets下多了几个so。
通过AndroidManifest.xml可知入口在com.stub.StubApp。
先看attachBaseContext方法,可知是判断cpu,然后将对应的so文件释放到app的data目录下的.jiagu目录,然后用System.load方法加载该so,这里我手机对应的为libjiagu_a64.so。
用ida打开so,查找init_array,里面只有一个函数sub_17CC。
函数sub_17CC调用sub_20B4,其内容如下,先通过mmap分配一段内存,然后通过sub_1F4C将一段数据解密后存在刚刚分配的内存中。再然后调用sub_1ECC对解密后的数据进行重定位。最后通过mprotect修改内存页属性。
然后分析JNI_OnLoad,从刚刚解密的数据中获取函数地址,然后跳转,最终调用到__arm_a_1(地址0x89C0),
__arm_a_1内容如下,sub_8950检查当前so名字是否为libjiagu开头的,不是则生成信号9结束进程。sub_837C读取/proc/net/tcp文件,检查端口0x5D8A,如果存在则kill进程,所以动态调试要把ida的默认端口改了。sub_83B4则是解密出一个so并通过自定义的加载器将它加载。然后找到新so的JNI_OnLoad调用。
sub_83B4通过分析,最终调用到sub_5254的时候,所有数据都解密出来了,可以在此处dump新的so。
sub_5254函数有两个参数,其数据结构分别如下:
参数1中buf_1、buf_2、buf_3、buf_4分别为解密后的程序头表、JMPREL、RELA、DYNAMIC
参数2中的decode_data为中间数据,参数1中的buf_1、buf_2、buf_3、buf_4就是从这里解密出来的,最后还包含一个so,该so被抹除了前面这几部分内容。
在sub_5254入口处dump解密的so,脚本如下。
将dump出来的so用ida打开,该so因为没有Section Header Table,所以要自己到动态节中去找到init_array。
动态节内容如下。可以知道init_array在0x1277c0
init_array内容如下。这些函数都是在初始化一些变量。
然后分析JNI_OnLoad。
先是注册StubApp的各种native方法,内容如下:
然后再解析linker64查找符号rtld_db_dlactivireport保存起来。未被调试时返回0。后面解密vmp方法的时候会用到,如果不为0会导致解密失败。
然后将从dex中解析出附加数据,其包含加固的配置信息和所有原始dex。
解析dex的地方为sub_240C8,该函数主要就是对每个dex开启一个线程进行解密,然后join获取结果。
所以在sub_240C8返回的时候,dump所有dex,返回值结构如下
dump脚本如下。
然后通过DexFile::OpenCommon加载所有的dex文件。
然后通过循环调用sub_8B6E4,从dex中解析出附加数据,该附加数据包含所有被vmp方法的信息,如下所示,每个item包含5个字段,每个4字节。
第一个字段为方法在dex中的method_id,
第二个字段为方法类型,0为实例方法,1为静态方法,
第三个字段为方法对应的code_item在dex中的偏移。
第四个字段为360自定义的clas_id,注册vmp方法的时候用到。
第五个字段为后面紧跟着的指令数,如果为0表示直接解密原来code_item中的指令执行,不为0则执行的时候,把该处的指令复制到原来的code_item,执行完后又清除。
然后到sub_1FF80,该函数将所有dex中的DexPathList.Element添加到原类加载器中
然后将所有dex前8字节清空。
然后解析dex,为vmp方法执行分配空间,并初始化一些数据结构。其中sub_8FD08会分配一个数组,每个vmp方法都会将sub_12D040函数的机器码复制过来。作为调用代理。之所以每个方法都复制,是因为到时调用的时候,会将函数的地址作为参数,这样通过偏移就能知道是调用哪一个方法。
然后再根据配置决定是否dex2oat
再然后就是注册一些类的native方法,就先不管了。到此为止,所有加载工作就完成了。
回到StubApp类中attachBaseContext,在加载so后还调用了interface5,onCreate调用了interface21,通过前面注册是时候找到的方法,分析后,这两个方法只是根据配置做了一些操作,就先不管了。
现在来看之前dump的dex文件。对比下加固前后的内容,可以看到,onCreate方法被改为native方法了,而且类初始语句中多了一行代码StubApp.interface11(1344);
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
最后于 2020-6-8 23:13
被卧勒个槽编辑
,原因: 附件