首页
论坛
课程
招聘
[原创]360加固保分析
2020-6-11 20:08 28869

[原创]360加固保分析

2020-6-11 20:08
28869

背景:

调试手机是Android 6.032位的手机。样本是自己写的一个经过360加固的小程序。加固时间为今年的5月份左右。

步骤:

总体来说就是分为两大步,首先是分析libjiagu.so,从中dump出第二个so,也就是解释器so,第二步就是修复分析解释器so,找到指令映射的对应关系,得出指令映射表。

第一步:

首先看一下.init_array做了什么事


可以看到这里只有一个函数,经过我的分析这里并没有做什么重要的事。

然后继续看JNI_OnLoad区域。

发现是这样子的,然后我们的静态分析就变得困难了,只能开始我们的动态调试之旅了。

通过动态调试我从JNI_OnLoad一路跟到这个重要的函数,_Z10__fun_a_18Pcj

可以看到这个函数被混淆的非常严重。但是经过我的分析有用的分支基本只有case31case35两个分支。这里可以说一下case31是一个反调试的分支,case35是进入第二个so的入口,别的分支有的也做了一些事,但是对于我们来说用处不大。

反调试:

我们可以在这里下断,然后跟随R0寄存器。如图

这个版本的一共有三个反调试的点,一个是符号,一个是端口,一个是时间。

此处为第一个反调试了。

我们可以在内存窗口修改指令,改成无用指令。

第一个反调试之后,两次f9就是第二个反调试的点了,也就是时间反调试。

从这个跳转进入,即为时间调试。

在这里我们只需把R0寄存器置0就可以。

还有一个是端口检测,我们只需更改ida的默认调试端口就可以了。

到此,反调试告一段落。

 

接下来我们继续分析,sub_5CE8为第二个so加载的关键地方。

如图,这个是ida f5的结果。

但是我们会发现一个有趣的地方。

有没有觉得这个地方与Android源码中加载so的函数有点相似。

在这个函数断下就可以dump第二个so

但是可惜的是它并没有走这个分支,而是这个分支

sub_540C这个函数一共要解密四个部分,分别为程序头表、JMPREL、RELA、DYNAMIC

一个循环即为一部分。我们把这四部分dump出来。

R7寄存器地址即为整个第二个so的开始地址,我们可以把整个malloc的区域全dump下来。

需要注意的是

一定要在这个循环执行完之后dump,即解密完。

在这里说一下如何修复,因为这个so没有elf_header,所以需要我们自己修复,并且把其他三部分放到原来的地方。在这里特别说一下,R7寄存器为so的开始地址,R1寄存器为此部分在so的偏移,R0为要解密的数据大小。如此,我们可以修复解释器so

总结一下,我们把dump出来的四部分按照偏移直接覆盖到dump出来的so中就可以,因为我们dump出来的so的那四部分并未解密。但是需要注意先修复elf_header

第二步:

按惯例来分析init_array区域,经过分析init_array区域并没有做什么重要的事情。

然后分析JNI_OnLoad,这个函数做了很多事情,最重要的就是注册stub方法和dex的加载。

Dex的加载在这里完成

通过动态调试我们进入这个函数sub_1A104。这个函数很长,完成dex的一系列操作。

对了忘记说了,我们可以通过case35分支进入第二个so

因为我们的目标不是dump dex 这里dex的加载就不多说了,直接分析被native化的函数如何还原。

分析我们dumpdex会发现这样的现象,


这里有个interface11 那么这个动态注册的函数就是我们的切入点。

但是我们发现这个函数是这个样子的,

这个jumpout我确实解决的不是很好,就是静态分析和动态调试硬着头皮看的,我也试过网上分享的一些方法,但是效果都不怎么好。如果跳转的地方是连在一起的还好,可以进行patchp成一个函数,那样参数,变量还可以看,如果中间夹杂着别的东西,不能p成一个函数,那就是一团糟,索性我就这样看了。希望大佬能够在这里给点意见。

在这里说一下360 进行native化的函数都是绑定了同一个函数,类似于分发的作用。然后,经过分析找到这个函数,sub_BF75C。其实这个函数就是调用了sub_1C480

到这里我们进入正题,这个最重要的函数sub_1C480的分析。

我们悲剧的发现,这里跟前面一样,都被处理了。

幸好这个函数不是很长,我就一步步跟出来了。

然后进行jni接口的赋值,然后根据注册vmp方法时的描述信息执行哪条分支,

一种是直接将指令复制到原地方,然后用jni函数调用,调用完成后再将其清空。另一种方式是自己实现的解释器,边解密边解释执行,且解密后的指令也是替换过的

描述信息是这样的,

4F 3C 00 00 01 00 00 00  5C 60 1C 00 03 00 00 00

00 00 00 00 00 00 00 00  00 00 00 00 6D 07 00 00

00 00 00 00 00 00 00 00  00 00 00 00 65 78 00 00

4F 3C 00 00   methon_id

01 00 00 00   0为实例方法,1为静态方法

5C 60 1C 00   code_item在dex中的偏移

03 00 00 00   第几个方法

00 00 00 00   如果为0表示直接解密原来code_item中的指令执行,不为0则执行的时候,   把该处的指令复制到原来的code_item,执行完后又清除。  

其他字段意义就不是很大了。

 

接下来执行sub_1C51E,解析参数,分析类名和包名

再就是执行sub_1C5D0,根据是否为静态方法来分别走两个分支。

但是,最后都会执行到这个地方

这里是申请寄存器空间,将参数解析出来最后调用sub_2ABC8。

经过分析sub_37652函数为重点。

此处的描述信息为

54 B2 E5 A1 04 00 00 00  00 5D B1 AE C1 3B

54 B2 E5 A1 指向指令

04 00 00 00 这个字段还不知道代表什么

00 5D B1 AE 执行dex

C1 3B  method_id

C1 3B 这个是我的apk的oncreate方法的method_id

现在内存窗口是这样的

下一条指令

58-54=4

4即为上一条指令的长度。

后面就是根据op来对应指令执行了。因为是自己写的apkoncreate方法的smali指令都知道,所以分析指令映射表就比较容易点,到这里,我们就可以对应出指令映射表来了。

到此为止,我对这个数字壳的加固就分析完了。有感兴趣的大佬可以分析一下指令映射表。

最后,再奉上附件。


恭喜ID[飞翔的猫咪]获看雪安卓应用安全能力认证高级安全工程师!!

最后于 2020-6-11 20:08 被[軍]编辑 ,原因:
上传的附件:
收藏
点赞16
打赏
分享
最新回复 (39)
雪    币: 28
活跃值: 活跃值 (215)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
endlif 活跃值 1 2020-6-11 23:14
2
0
感谢分享
雪    币: 662
活跃值: 活跃值 (432)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
哆啦噩梦 活跃值 2020-6-12 08:09
3
0
感谢分享,jumpout咋对抗的呢
雪    币: 73
活跃值: 活跃值 (652)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
hixhi 活跃值 2020-6-12 11:36
4
0
楼主这功力,简直了,佩服。
雪    币: 6378
活跃值: 活跃值 (798)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
战马 活跃值 2020-6-12 15:10
5
0
这是免费版的吗
雪    币: 224
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
感谢你曾来过 活跃值 2020-6-12 15:58
6
0
这才是我遇到的加固so,之前那些大佬分析的 我都找不到样本
雪    币: 5736
活跃值: 活跃值 (3319)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
[軍] 活跃值 1 2020-6-12 17:20
7
0
是的 免费版的
雪    币: 5736
活跃值: 活跃值 (3319)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
[軍] 活跃值 1 2020-6-12 17:21
8
0
哆啦噩梦 感谢分享,jumpout咋对抗的呢
暂时还没有找到好的对抗方法
雪    币: 662
活跃值: 活跃值 (432)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
哆啦噩梦 活跃值 2020-6-12 18:10
9
0
[軍] 暂时还没有找到好的对抗方法
楼主jumpout咋处理的
雪    币: 5736
活跃值: 活跃值 (3319)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
[軍] 活跃值 1 2020-6-12 19:06
10
0
哆啦噩梦 楼主jumpout咋处理的
可以patch处理 但是对于参数的识别不是太友好
雪    币: 210
活跃值: 活跃值 (95)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
caijunfan 活跃值 2020-7-1 19:15
11
0
老师,请教一下。
“R7寄存器地址即为整个第二个so的开始地址,我们可以把整个malloc的区域全dump下来。”  这个需要在哪条指令处dump?
雪    币: 5736
活跃值: 活跃值 (3319)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
[軍] 活跃值 1 2020-7-2 10:59
12
0
caijunfan 老师,请教一下。 “R7寄存器地址即为整个第二个so的开始地址,我们可以把整个malloc的区域全dump下来。” 这个需要在哪条指令处dump?
把整个malloc区域全dump下来就可以,然后进行so修复
雪    币: 210
活跃值: 活跃值 (95)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
caijunfan 活跃值 2020-7-2 17:34
13
0
[軍] 把整个malloc区域全dump下来就可以,然后进行so修复
是把四次malloc的区域dump下来吗~
雪    币: 5736
活跃值: 活跃值 (3319)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
[軍] 活跃值 1 2020-7-3 18:48
14
0
caijunfan 是把四次malloc的区域dump下来吗~[em_85]
那四个区域肯定要dump的,这四个区域是so文件中加密的四部分 等它解密完后dump下来 用来修复so文件 除此之外还要dump整个so文件,就是截图中这部分 AEEC0000 AEFC0000   这是完整的so文件,只不过里面其中的四部分加密了,当然,除了这四部分之外,还有别的很多部分。
雪    币: 3264
活跃值: 活跃值 (226)
能力值: ( LV3,RANK:25 )
在线值:
发帖
回帖
粉丝
yezheyu 活跃值 2020-7-5 11:13
15
0
感谢分享
雪    币: 229
活跃值: 活跃值 (51)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
初音未来 ㅤ 活跃值 2020-7-7 20:07
16
0
感谢大佬分享教程
雪    币: 210
活跃值: 活跃值 (95)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
caijunfan 活跃值 2020-7-16 17:18
17
0
[軍] 那四个区域肯定要dump的,这四个区域是so文件中加密的四部分 等它解密完后dump下来 用来修复so文件 除此之外还要dump整个so文件,就是截图中这部分 AEEC0000 AEFC0000 ...
感谢大佬~我分析的可能版本不太一样 有差别
雪    币: 19
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
mb_jgzwnuxx 活跃值 2020-7-17 15:23
18
1
感谢分享
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
mb_evshufvg 活跃值 2020-8-2 21:20
19
0
跟大佬请教一下,整个malloc区域全dump下来文件大小不到100K,比你提供的的dump.so 765k文件小很多,是什么原因
雪    币: 5736
活跃值: 活跃值 (3319)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
[軍] 活跃值 1 2020-8-3 11:51
20
0
mb_evshufvg 跟大佬请教一下,整个malloc区域全dump下来文件大小不到100K,比你提供的的dump.so 765k文件小很多,是什么原因
可能是dump错了地方 也可能是没有dump下来的原因
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
mb_evshufvg 活跃值 2020-8-4 09:08
21
0
谢谢,我忘了按照十六进制转换了
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
mb_evshufvg 活跃值 2020-8-4 21:20
22
0
再跟大佬请教一下,我如何在加载第二个so里面下断点了,这个断点对应的地址怎么确定
雪    币: 5736
活跃值: 活跃值 (3319)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
[軍] 活跃值 1 2020-8-5 11:43
23
0
mb_evshufvg 再跟大佬请教一下,我如何在加载第二个so里面下断点了,这个断点对应的地址怎么确定
上面提到过,从case35可以进入第二个so
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
mb_evshufvg 活跃值 2020-8-5 17:15
24
0
请教一下,从case35的.engine:0000CEF4                 BLX     LR,进入,加载的第二个so在模块列表中是什么名称,怎么找到调试中的sub_1CE60的断点位置,如何确定第二个so的调试基地址了
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
mb_evshufvg 活跃值 2020-8-5 18:26
25
0
已经找到了,大佬不用答复了,谢谢
游客
登录 | 注册 方可回帖
返回