首页
社区
课程
招聘
[原创]神奇日游保护分析——从Frida的启动说起
发表于: 2025-6-10 00:40 2402

[原创]神奇日游保护分析——从Frida的启动说起

2025-6-10 00:40
2402

最近看论坛里很多人在讨论一个日游——jp.gungho.*,特征so是lib__ 6dba__.so。

出于兴趣看了看,发现不是常规的自定义linker。于是花了三天时间把基本的加固流程和保护原理分析的差不多了,发现其中的so完整性检查(可用于anti frida)和mmap模块化调用很有新意,所以整理成文章和大家分享一下。

frida已经成为逆向爱好者必备的工具,各种app对于frida的检测也五花八门,甚至还有什么“某某企业壳frida关了也能给检测出来”这种吓人操作。网上也有大量相关的文章。

可是frida启动时做了什么却很少有人分析。通过阅读frida源码,可以发现frida在启动时留下了大量可供检测的特征。

使用frida的第一步是在目标机器上启动frida-server,即使我们什么app都不hook,只启动一个server。

frida-server一启动,就主动注入了zygote进程:

查看zygote进程的内存布局,在启动frida-server之前:

只启动frida-server,什么都不hook:

可以看到frida 的so已经注入zygote了

frida-server启动注入zygote后,立刻自己hook了一些libc函数

主要有退出相关:exit,_exit,abort

fork相关:

和一些文件操作相关的函数。

frida是使用inline hook对函数进行hook的,inlinehook意味着要写内存,所以在hook前,frida会修改目标函数所在页的页属性为RWX:

在maps文件中,连续内存的不同页属性会被独立列出来:

启动frida-server前,zygote maps文件中libc.so的布局:

启动frida-server后:

可以看到libc.so的内存中多了很多长度为0x1000的rwx片段,这些片段正是frida自己hook 那些libc基本函数导致的。

这两点就是一些“企业壳”所谓在frida就算关了也能检测出来的基本原理。

打开目标so,发现只有一个init函数,没有JNI_OnLoad,同时.text段一大堆0,很明显是个壳子。

于是跟入init函数调试看看。

首先通过解密字符串/proc/self/maps打开maps文件,找到自身so的内存地址:

使用的是自实现的svc函数mmap。这个壳没有使用任何libc函数,所有的字符串操作:strcpy,strcmp,内存操作:memcmp等,都是自己实现,或者直接走svc 0。

这无形中增加了逆向的难度。

不过这个操作没什卵用,更重要的是打开了本地的lib__ 6dba__.so,然后解析elf文件,寻找type为0x80000000的section:

sh_type为0x80000000 - 0xffffffff为用户自定义区间:

可以看到这里存放了大量的加密数据:

然后对这段加密数据进行解密,首先解密出元信息,包括模块的大小,初始函数入口偏移等信息:

如0x257c8是解密的模块长度,0x5d4是解密后入口的偏移。

接下来会mmap一段0x257c8长度的内存,然后将数据解密过去,然后根据偏移跳转到解密出来的代码里执行:

注意,这里解密出来的是一个模块而不仅仅是一个函数。里面包含了几十个函数,所以我们需要将其dump下来分析。

进入解密的代码块中,首先mmap了一块0x1800大小的内存,这块内存用来存储后面mmap出的模块的信息。

每个模块的基本信息如下:

struct module{
int id;
int isrodata;
void* base;
int64 size;
};

首先插入了两个模块,id分别是0xe2和0xd0,其中0xe2模块的内存基址是0x709e426000,大小是0x257c8

而0xe2模块,其实就是2.1中解密出的模块,就是当前模块本身。

这个保护解密出来的模块分为三种类型,最核心的是解释器模块:

解释器模块主要负责循环解密下一个模块。

1.解释器模块首先检查当前执行的模块id是否大于0xe2,如果是的话将id-1的模块移除(在模块列表里删除,同时将对应的内存清空(memset为0)释放(munmap))。

这个操作主要的作用是解释器替换。

因为解释器模块可能mmap解密出新的解释器模块,这样执行新的解释器模块后,会将上一个解释器模块释放掉,用新的解释器模块来解密。

2.循环解密新的模块

3.如果解密出来的模块有初始化函数,调用初始化函数。

主要有两个初始化函数

新的模块入口函数执行后,如果返回1,继续解密下一个模块执行。如果返回0,会跳出循环,然后清除之前的所有模块,然后调用svc exit退出。

注意,解释器模块是不会返回的,因为上一个解释器已经被清掉了,返回会直接crash。

而逻辑模块则必须返回1。如果逻辑模块返回0,则必然会svc exit退出。

逻辑模块主要执行不同的逻辑,有的是安全模块,检查各种环境信息。有的是解密模块。

例如:

没有入口函数,解密出来扔在模块列表里,供其他模块使用。

第一个模块0xe2由原始so的init函数解密出来并执行。

然后0xe2模块解密了

0xe3模块解密出了

0xe4模块解密了

0xe5解密出了

0xe6解密出了

0xe7模块解密出了

0xe8模块:

解密出了0x98模块,该模块执行原始so的init_array函数。然后返回到linker中。

当然还有其他一些模块,这里只列举出比较重要的,一共大概有20多个模块。

为什么返回到linker中了?因为我们从init函数来的,最终所有模块执行完了(如果都成功的话),会返回到linker掉用init函数的地方。

以上所有模块都是mmap在内存中,直接调用入口函数执行。如果没有研究清楚,就会觉得在无限次mmap。

模块在执行中解释器从0xe2-0xe3-0xe4-0xe5-0xe6-0xe7-0xe8,一共换了7次,所以显得非常复杂。但其实基本逻辑是相同的,研究清楚了很好跟进。

对于每个模块,只有plt函数和代码段,没有elf头,动态链接信息,section header等。所以dump下来后需要自己将dump下来的代码自己修复为一个so,然后用ida打开分析。否则所有代码在内存中,并且没有符号,很难分析。

每个模块都自己实现了一套libc基本函数,svc调用和字符串解密函数,所以hook libc函数没什么作用。

这个壳的安全部分就是

0x60模块(root检查)

0x40模块(模拟器检测)

0x20模块(hash校验和libc检查)

0x54模块(反调试检查)

这四个模块。

在 /proc/mount,/proc/pid/mounts文件中检查magisk,同时检查一些su文件和路径(/system/bin/su之类)

主要使用了自定义的strcmp函数检查字符串,svc调用newfstatat检查文件是否存在。

(在调试过程中解密出的字符串被我改了,为了绕过检测)

主要检查模拟器,通过检测文件路径和包名来判断是否存在对应的模拟器。


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2025-6-10 00:48 被乐子人编辑 ,原因: 排版
收藏
免费 25
支持
分享
最新回复 (28)
雪    币: 5049
活跃值: (7720)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
niub plus
2025-6-10 09:52
0
雪    币: 2733
活跃值: (3393)
能力值: ( LV9,RANK:160 )
在线值:
发帖
回帖
粉丝
3
還得是你啊乐佬, 分析得真好, 比我詳細多了
2025-6-10 10:08
1
雪    币: 119
活跃值: (5392)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
4
乐哥效率这么快
2025-6-10 10:18
0
雪    币: 498
活跃值: (4656)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
膜拜乐哥
2025-6-10 10:30
0
雪    币: 552
活跃值: (4644)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
赏乐哥一个G罩杯骚妇
2025-6-10 10:39
0
雪    币: 4245
活跃值: (5372)
能力值: ( LV9,RANK:200 )
在线值:
发帖
回帖
粉丝
7
ngiokweng 還得是你啊乐佬, 分析得真好, 比我詳細多了[em_092]
那个libc条目数小于10的检测方式真的很神奇。
2025-6-10 10:45
1
雪    币: 4245
活跃值: (5372)
能力值: ( LV9,RANK:200 )
在线值:
发帖
回帖
粉丝
8
New对象处 乐哥效率这么快
必须效率啊
2025-6-10 10:45
0
雪    币: 4245
活跃值: (5372)
能力值: ( LV9,RANK:200 )
在线值:
发帖
回帖
粉丝
9
DirtyAngle 赏乐哥一个G罩杯骚妇
拿这个考验技术人员?
2025-6-10 10:46
0
雪    币: 20
活跃值: (1053)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
写的真好,乐哥牛逼
2025-6-10 10:50
0
雪    币: 4245
活跃值: (5372)
能力值: ( LV9,RANK:200 )
在线值:
发帖
回帖
粉丝
11
matrump 写的真好,乐哥牛逼
感谢支持
2025-6-10 10:51
0
雪    币: 102
活跃值: (2785)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
12
乐哥牛逼啊。。。。
2025-6-10 10:52
0
雪    币: 2733
活跃值: (3393)
能力值: ( LV9,RANK:160 )
在线值:
发帖
回帖
粉丝
13
乐子人 那个libc条目数小于10的检测方式真的很神奇。
確實, 雖然早就知道frida有這樣的特徵, 但還是第一次見到真有人會去檢測
2025-6-10 11:02
0
雪    币: 2148
活跃值: (2007)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
乐哥牛逼
2025-6-10 11:13
0
雪    币: 552
活跃值: (4644)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
乐子人 拿这个考验技术人员?
我觉得你经不住考验
2025-6-10 11:18
0
雪    币: 2247
活跃值: (1865)
能力值: ( LV3,RANK:35 )
在线值:
发帖
回帖
粉丝
16
乐哥牛逼
2025-6-10 12:48
0
雪    币: 6
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
17
乐哥,来个文章同版本的样本
2025-6-10 13:10
0
雪    币: 2272
活跃值: (7536)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
.KK
18
nb~
2025-6-10 14:02
0
雪    币: 4245
活跃值: (5372)
能力值: ( LV9,RANK:200 )
在线值:
发帖
回帖
粉丝
19
mb_zfqvurgb 乐哥,来个文章同版本的样本
jp.gungho.padHT,22.3.0
2025-6-10 14:22
0
雪    币: 1885
活跃值: (3424)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
20
可以可以 好文
2025-6-10 15:05
0
雪    币: 1663
活跃值: (2169)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
21
好文,受益匪浅
6天前
0
雪    币: 4960
活跃值: (14952)
能力值: ( LV9,RANK:230 )
在线值:
发帖
回帖
粉丝
22
为啥不看看Hunter这块硬骨头呢。
6天前
0
雪    币: 4245
活跃值: (5372)
能力值: ( LV9,RANK:200 )
在线值:
发帖
回帖
粉丝
23
珍惜Any 为啥不看看Hunter这块硬骨头呢。
看了一下疑似加了全量的ollvm,有空了再说吧。。。
6天前
0
雪    币: 4960
活跃值: (14952)
能力值: ( LV9,RANK:230 )
在线值:
发帖
回帖
粉丝
24
乐子人 看了一下疑似加了全量的ollvm,有空了再说吧。。。
 嗯呢
6天前
0
雪    币: 4162
活跃值: (6033)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
25
乐哥牛啊
5天前
0
游客
登录 | 注册 方可回帖
返回