首页
社区
课程
招聘
[原创]新版梆企检测绕过
发表于: 17小时前 805

[原创]新版梆企检测绕过

17小时前
805

IDA打开发现导入表空空如也,无需多言,先dump修复一份so,IDA打开之后发现只有寥寥数个函数,并且注册了constructor函数,那只好先去入口处看看了

这是入口函数,上来就会被调用,其中0x464C457F是ELF魔数,这段代码在从自身页面开始往上扫描,直到扫描到ELF魔数,从而查找自身的基地址,然后拿到sscanf的地址,存到全局变量中。我也不晓得这一通操作意欲何为。前一个还可以理解,这么做会比较节省时间,至于sscanf,直接拿来用不就行了吗,他这里还查找这个符号然后保存有点没理解,有懂的大牛子可以解释一下

然后就是保存一些全局变量,都是写死的偏移或者秘钥信息,比较重要,后续解密时会用到。最后就是这个壳so最重要的函数了sub_33F8()

建议如果要分析的话,先看看这个简单的项目吧,因为项目里so加载流程和这个壳不能说100%一样,但是也有90%是一样的 Yuuki/soLoader

这个函数有900多行,不算很复杂,而且核心函数一目了然。它调用了 mmapdlopenmprotect等函数,结合之前发现的,1.36M的so,反编译之后就几个函数,其他地方都是被加密的,那不难猜到这个函数的作用就是在运行时动态解密释放真正的so,然后真正的so再去对dex做解密等操作。如果是简单的upx壳,那么大概率不会使用到dlopen,因为upx只需要申请内存,解密payload即可,但是这里它调用了dlopen,还是在一个循环中调用的

这很明显就是在处理DT_NEEDED条目了,那么这个函数,基本上可以初步判断为一个简易的linker,职责是加载真正的so

那么我们当下的直接目标就是解密出真正的so,所以先来简单分析一下这个函数吧~,我只截取关键的部分,感兴趣的可以自己从头看看

这里反编译之后跟看源码没啥区别。先解析maps,根据上面拿到的 so 基地址来判断当前条目是否命中,命中取出 so 路径,为了拿到libDexHelper.so的路径。这里这么做是因为android加载so时,会从 /data/app/一串神秘代码/libs 下加载,而厂商的代码是写死的,他不知道这个神秘代码是啥就拿不到文件的磁盘路径,所以需要这样获取一下。当然我觉得直接在内存里操作也是可以的,不过这个看个人喜好了

拿到路径之后 ,它做了如下三件事情

读了磁盘上的so的特定偏移的一些数据,这些偏移地址是写死的,上述初始化函数里提到过。其中 sub_3184是一个变种的RC4算法,秘钥用的是qword_15068qword_15068来自 从0x1181DD读的20字节,所以这一块的逻辑就是,读取秘钥,读取要解密的64字节,调用解密函数,解密

解密出的数据如下:

7F454C460201010000000000000000000300B70001000000B0F8000000000000400000000000000000F71000000000000000000040003800080040001A001900

这完全验证了我们之前的猜想,这是一个标准的ELF头,所以这个函数的确是一个迷你的linker,并且我们已经拿到了ELF头的解密算法,接下来就是找剩下的数据是如何被加密的了

关键解密函数是sub_2B1C,这就是一个简单的xor加解密

秘钥是0x41,之前读20字节的时候读出来的,那么就可以静态解密出真正的so了。当然你也可以运行时动态dump,我看见有的朋友是直接在dlopen onLeave的时候扫描匿名可执行内存,然后直接dump的,这样也可以的,并且不用分析壳so的逻辑,建议大家这么做

分析到这里就可以解密出主so了,但是本着来都来的的心态,还是看看后面它做了哪些操作吧

总结下来就是:

感觉和我之前写的差不多,但是我把加密的步骤前置了 so加固玩具版

运行一下,就要开始分析主so了捏

我们后面在hook主so里的函数时需要使用主so的基地址+函数偏移,但是主so是被映射到它自己mmap的匿名内存上的,这里有很多方案,我们选择相对优雅的一种

之前分析出了

我们直接hook mmap,根据后面四个参数值进行过滤即可,如果噪音过多,可以根据映射大小进一步过滤。过滤完可以看到只这样的

如此我们便可以知道映射大小=len=0x134000的时候的返回值是我们要的,我们就可以写出更简洁的脚本

蓝蓝一片非常之爽,.init_array里没有注册函数,但是JNI_OnLoad反编译之后居然有3000行,那暂时先不看了

先来明确一下目标吧

到现在为止还没咋使用到frida,但是不用想,附加上去启动app包是会崩溃的。目前已知所有重要逻辑入口都在JNI_OnLoad,那直接来trace一下函数调用链吧

这里使用到oacia大佬的stalker_trace_so,建议大家优先使用这个工具,他可以记录所有IDA识别出来并且被主线程执行到的函数,帮我们快速定位大致范围

需要注意的是生成的脚本在trace时基地址要稍作修改,因为它的主so是动态释放的

只看最后几条日志

直接hook sub_1304C试试看,当然这样不严谨,但是可以快速看看有没有效果

依旧崩了,但是这次的崩溃相较上一次正常的多,判断为不是被同一处检测点检测到了,把hook sub_1304C的 逻辑加上,再trace一次

这次的日志的最后几行

初步看了一下,上面几个没啥可疑的,估计就是检测到了然后正常退出,这里由于最后几条函数并不是检测函数和退出函数,所以这里大概率不是同步的检测。或者还有一种可能,假设函数B是检函数,函数A调用B,然后根据B的返回结果决定是否退出App。当前trace脚本只能记录“执行流进入了哪些函数入口”,但没有记录“函数返回到了哪里”以及“调用者在拿到返回值后又执行了什么分支逻辑”,所以只能看到A和B都执行过,却不一定能定位到 A 在函数内部哪一条指令上完成了退出。

搞这里也是时间有点晚了,我也懒得跟他废话了,直接用内核模块监控一下哪里给我app干崩了(上文已经分析出此处的崩溃是正常的退出)

一共两处,IDA跳过去看看

两处都是直接svc call __NR_kill函数直接退的,果然是像我们上面猜测的那样,我们直接给它们patch掉就行了

直接注入启动,app完美运行,美美得吃了也是

但是这种方式并不是很优雅,毕竟不是每个人都能用内核模块。值得注意的是上面两个退出点都在JNI_OnLoad函数中,这就很值得注意了,正常检测逻辑怎么会放在这个函数中呢?我觉得只有*才会这样写代码,所以这里JNI_OnLoad只是起到一个最终的决策作用。具体来说就是JNI_OnLoad里通过无论是新建线程还是直接同步调用函数的方式,去启动检测函数,然后不在检测函里执行退出机制,而是拿到检测函数的结果,集中在JNI_OnLoad里进行处理。当然这些只是我的猜测,至于为什么这么做,可能是因为JNI_OnLoad经过了混淆,开发者觉得大多数逆向人员不会去优先看这个函数。事实也的确如此

有的朋友通过hook clone那套 + 处理sub_1304C也能绕过检测,但是我感觉这样比较麻烦

我们继续来优雅(暴力)的解决刚刚的问题吧

已知退出是正常的退出,只是通过svc直接call内核函数而已。这里可以有一些大众的处理方案

这里我们直接选择方案二,因为它足够简单,直接写个IDA脚本,帮我们生成对应的frida patch脚本代码,这里我只处理了 exitexit_groupkilltkilltgkill,其他的退出方式并没有做处理,抛砖引玉感兴趣的大佬可以自行拓展

加上我们之前对 sub_1304C的处理,就可以完美绕过啦~

完整过检测代码如下:

很早以前就读壳感兴趣,但是一直没有时间研究。这次特意选了安卓端最简单的壳进行分析。之前不懂为什么那么多国家相关的APP,以及一些大银行,都喜欢用这个的壳,明明比它强的壳还有很多。最近和朋友聊天时问了这个问题。他跟我说,很多东西不是技术层面的问题,而是法律层面的。恍然大悟了也是

这篇篇幅还是有点太短了,剩下的dex解密流程分析过两天回学校有空了再写吧ovo

很多都是边逆边写的,有些结论可能缺乏准确性,自行甄别

使用到的一些工具以及文章:


[培训]《冰与火的战歌:Windows内核攻防实战》!从零到实战,融合AI与Windows内核攻防全技术栈,打造具备自动化能力的内核开发高手。

收藏
免费 57
支持
分享
最新回复 (37)
雪    币: 1549
活跃值: (4613)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
2
17小时前
0
雪    币: 482
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
3
6666
16小时前
0
雪    币: 155
活跃值: (4486)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
学习。
14小时前
0
雪    币: 59
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
5
666
14小时前
0
雪    币: 6
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
6
学习。
14小时前
0
雪    币: 200
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
7
tql
14小时前
0
雪    币: 6602
活跃值: (6520)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
66
14小时前
0
雪    币: 44
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
9
tql
14小时前
0
雪    币: 20
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
10
666
13小时前
0
雪    币: 682
活跃值: (1055)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
11
12小时前
0
雪    币: 20
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
12
666
12小时前
0
雪    币: 21
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
13
11
12小时前
0
雪    币: 1030
活跃值: (2666)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
14
22
12小时前
0
雪    币: 200
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
15
666
12小时前
0
雪    币: 4477
活跃值: (4276)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
11
12小时前
0
雪    币: 1942
活跃值: (2736)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
17
季东 11
22
12小时前
0
雪    币: 14
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
18
111
12小时前
0
雪    币: 4080
活跃值: (6339)
能力值: ( LV9,RANK:200 )
在线值:
发帖
回帖
粉丝
19
6
11小时前
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
20
6
11小时前
0
雪    币: 29
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
21
6
10小时前
0
雪    币: 8679
活跃值: (5368)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
666
10小时前
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
23
666
10小时前
0
雪    币: 3517
活跃值: (4554)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
学习一下
9小时前
0
雪    币: 507
活跃值: (1257)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
25
学习
1小时前
0
游客
登录 | 注册 方可回帖
返回