首页
社区
课程
招聘
[原创]小日本也有大安全——记一次不寻常的手游反调试,反hook分析与绕过
发表于: 2023-7-21 19:23 35316

[原创]小日本也有大安全——记一次不寻常的手游反调试,反hook分析与绕过

2023-7-21 19:23
35316

前两天水友群里老哥遇到了一个游戏样本:

我点开一看,符号都没去卧槽??!什么逆天保护:

所谓“浅藏诲盗,冶容诲淫”,保护做成这样不就是自找破解吗?于是我想当然的说“这玩意适合新手入门!”

深入研究了之后,发现比想象中的要复杂,而且检测手段都挺别致,不常见,并且是一款叫做nhnent appguard的日韩商业保护,挺有意思,于是出一篇文章总结以下。

打开最核心的libloader.so,映入眼帘的是ida的一堆warning,提示section header不合法。无所谓,直接强行进去:

看到代码都是灰色的,一些无意义的二进制,应该是被加密了,看看init array:

第二个是红色的什么鬼?试图jump过去看看,但是ida显示:Command "JumpAsk" failed

说明这个地址目前还不在可见范围??

010editor打开看看他的段信息:

代码段的文件长度是0x25c848,内存长度也是0x25c848,padding是0x10000,没什么问题。

数据段的文件偏移是0x25ea50,但是内存中的偏移却是0x35ea50,这中间活生生多出来了0x100000字节(100K),根据代码段的padding 0x10000,数据段的内存偏移应该是0x26ea50才对,这显然不正常。

init array 的第二个函数地址是0x29c1ec,既没有在代码段里,也没有在数据段里,而在中间空出来的padding里??!神奇!

所以第一个init 函数肯定要把这部分处理好,否则linker会报错,我们先看第一个init函数:

通过fopen打开/proc/self/maps文件,然后通过strtok和strtoul找到链接过程中多映射的100k的内存空间,获取首地址

然后通过mmap将这些地址先设置为rwx权限,再通过memcpy把藏在数据段的代码复制过去,然后使用mprotect把这块内存恢复为rx权限:

其中memcpy分别根据源地址,目标地址,长度,分5次copy

复制完后,第二个init函数就已经在内存中准备好了,可以开始执行。

第二个init函数就是作解密用的:

可以看到先解密了字符串,简单了异或了几个字符串就结束了,然后解密section。

字符串解密比较简单,我们看看如何解密section:

给linker的callarray函数下断点,在执行到第二个init函数时跟进去:

首先根据X0定位到so里面的加密数据,起始地址是:0xab710

刚好是.text的开始

然后将.text开始偏移0x4和0xc的字节拿来异或,得到的结果是加密数据的长度:

然后根据X1(解密后数据大小长度)malloc一段内存,再将真正的加密数据内容(.text偏移0x10开始),按照计算的长度x22,memcpy过来

然后将.text偏移0x8和0xc的数据异或,计算出第一个key(w11),用于后面解密:

第二个key 在加密数据的末尾,通过x22找到加密数据的末尾,下一个字节即是第二个秘钥(w25)

然后开始解密工作,每字节异或一次,同时根据当前的偏移,奇数字节用key1,偶数字节用key2:

解密完后看到数据的开头是0x78,0x9c,显然是zlib的压缩数据:

接下来初始化zlib为1.2.7版本:

然后循环解压,再将解压后的代码复制回.text段:

解压复制完代码也就解密完成了:

所以我们可以根据他的解密方式,自己写一套加密方式,把解压后的代码修改后压缩,加密回去,这样就可以对原代码进行修改了。加密代码如下:

注意由于修改后的代码经过压缩长度可能会变化,所以需要针对性的修改.text开始的0x4,0x8和0xc处的字节,以符合解密算法。同时需要在加密数据的末尾按照小端法重新添上key2

至此,该加固的解密方式已经全部清楚,并且我们也可以定制化的修改代码,加密回去了。、

加固研究完了,我们直接F9起飞,但是ida崩了。显然后反调试存在,但是so中没搜索到什么有用的字符串信息,应该是被加密了。

研究各种安全保护的第一步应该是:找到字符串解密函数。找到这个之后对方做的各种骚操作就一目了然了。

寻找字符串解密函数通常可以给fopen下断点,然后回溯。以反调试为例,通常先打开/proc/self/status文件,然后读tracerid。而打开这个文件会用到fopen。so里没有明文/proc/self/status,那肯定是解密后传给fopen的,即解密函数离fopen不远。

通过简单的调试观察发现,sub_C4A50是字符串解密函数:

可以看到也是简单的异或。

我们给sub_C4A50下断点,看看能发现什么:

发现解密出了很多常用的libc函数,感觉不妙

然后出现了熟悉的 /proc/self/status

单步跟下去,发现又加密了Tracerid,这下图穷匕首现了:

接下来就是常规的操作:

fopen打开/proc/self/status:

fgets循环读取,然后strstr检查是否读到了tracerid:

如果读到了通过atoi获取Tracerid,如果不是0就进入退出流程:

退出流程比较复杂:

最终会根据传入的参数不同,定制一种退出方式,有exit,有造crash,也有svc exitgroup,不再赘述。

我们只需要将atoi的返回结果改成0,就可以绕过了。

但是,要真的这么简单也就不会有这篇文章了。

一开始并不知道atoi后走的是什么退出流程,所以给exit下了断点:

但是发现下断点之后,还没走到检查Tracerid一步,exit就被调用了,说明有别的检查。

通过反复的调试发现,只要给exit下断点,目标进程还没到检查Tracerid就会提前走退出流程。如果不给exit下断点,就会去检查Tracerid,然后根据atoi的结果决定是否走退出流程。

我们记得在调试中看到了解密出了exit,_exit等字符串,跟下去看看:

发现不光解密了exit,_exit,还解密了__exit,kill,tgkill

而且每解密一个函数名,都通过dlsym获取函数的地址:

神奇。

接着跟下去,发现调用dlclose关闭了之前dlopen打开的libc


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

最后于 2023-7-21 19:32 被乐子人编辑 ,原因:
收藏
免费 44
支持
分享
打赏 + 1.00雪花
打赏次数 1 雪花 + 1.00
 
赞赏  jelasin   +1.00 2023/12/13 感谢分享~
最新回复 (52)
雪    币: 587
活跃值: (1002)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
大佬牛鼻,都是干活,可以进一下你的水友群吗?
2023-7-21 20:04
5
雪    币: 147
活跃值: (345)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
刚看完你unidbg模拟执行的帖子,想请教点问题的,没想到又发新的技术文章,先pdf转存一下,方便以后翻看
2023-7-21 21:20
0
雪    币: 3221
活跃值: (4992)
能力值: ( LV9,RANK:160 )
在线值:
发帖
回帖
粉丝
4
wuli鸭蛋君 [em_3]刚看完你unidbg模拟执行的帖子,想请教点问题的,没想到又发新的技术文章,先pdf转存一下,方便以后翻看[em_13]
感谢支持
2023-7-21 22:42
0
雪    币: 520
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
5
大佬 我自己 IDA 调试加固的app 为啥会一直报错弹窗 看你这个好像不会
2023-7-22 00:01
0
雪    币: 3194
活跃值: (5181)
能力值: ( LV3,RANK:25 )
在线值:
发帖
回帖
粉丝
6
so样本放出来看看呗
2023-7-22 10:07
0
雪    币: 3221
活跃值: (4992)
能力值: ( LV9,RANK:160 )
在线值:
发帖
回帖
粉丝
7

so样本

上传的附件:
2023-7-22 10:15
1
雪    币: 3535
活跃值: (31011)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
tql
2023-7-22 16:25
1
雪    币: 129
活跃值: (4645)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
9
666
2023-7-22 19:26
0
雪    币: 116
活跃值: (1012)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
如沐春风
2023-7-23 00:22
0
雪    币: 1979
活跃值: (2318)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
剖析过程层层递进,讲解方式抽丝剥茧,看君一文胜读十年书
2023-7-23 00:52
0
雪    币: 3237
活跃值: (1886)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
是哪款游戏呢
2023-7-23 09:46
0
雪    币: 498
活跃值: (4291)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
太细了
2023-7-24 10:16
0
雪    币: 100
活跃值: (2493)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
 前人栽树后人乘凉
2023-7-24 12:27
0
雪    币: 219
活跃值: (1147)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
蓝色监狱啊,足球漫改编的手游
2023-7-24 12:39
0
雪    币: 3700
活跃值: (4091)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
感谢分享,收藏了。
2023-7-24 12:52
0
雪    币: 18
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
17
大佬,牛be。
2023-7-24 13:36
0
雪    币: 248
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
18
学习了 , 感谢分享!
2023-7-24 14:10
0
雪    币: 14633
活跃值: (17729)
能力值: ( LV12,RANK:290 )
在线值:
发帖
回帖
粉丝
19
其实我自己在搞游戏服务器的时候就有明显感觉,日本的防守做的好一些,台湾的服务器就老是被打宕机
2023-7-24 16:14
2
雪    币: 217
活跃值: (778)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
分析到位。思路清晰。
2023-7-25 11:21
0
雪    币: 3221
活跃值: (4992)
能力值: ( LV9,RANK:160 )
在线值:
发帖
回帖
粉丝
21
hsgj000 分析到位。思路清晰。
感谢支持
2023-7-25 13:23
0
雪    币: 103
活跃值: (1963)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
大佬 如何进水友群?
2023-7-25 15:34
0
雪    币: 3221
活跃值: (4992)
能力值: ( LV9,RANK:160 )
在线值:
发帖
回帖
粉丝
23
azd放 大佬 如何进水友群?
水友群也是我后面水进去的,得找群主
2023-7-25 15:36
0
雪    币: 103
活跃值: (1963)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24

最后于 2023-7-25 16:41 被azd放编辑 ,原因:
2023-7-25 16:09
0
雪    币: 1367
活跃值: (6252)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
.KK
25
哥哥好强~
2023-7-25 18:18
0
游客
登录 | 注册 方可回帖
返回
//