首页
社区
课程
招聘
[原创] libmsaoaidsec.so 过检测
发表于: 2025-6-2 14:33 2488

[原创] libmsaoaidsec.so 过检测

2025-6-2 14:33
2488

在逆向某视频APP时,发现有对frida和hook java 层的检测,对于frida 的过检测,我使用了魔改后的frida 。
在hook native层的时候,没什么问题,但是只要我去hook java层,就会退出,即使hook java层时,什么都不写,只要有

Java.perform(); 就直接退出。
开始我是想看看程序是在哪里退出的,通过strace,发现app对/proc/self/status 和 /proc/self/task/<tid>/status 、/proc/self/map 等都有检测。

当我对/proc/self/status和/proc/self/task/<tid>/status 进行模拟。脚本如下:

这个时候还是会被检测,我想是模拟的文件不够真实,然后选择直接对目标文件复制,修改 TracerPid: 0 ,脚本如下:

此时,可以执行strace 指令了,   但是每次只能持续5-10秒钟,app就会被强制退出。原因不详,此时还是无法 hook java层,我怀疑是对/proc/self/maps的检测才导致的java hook 失败。

这时,我对maps 的文件进行copy ,放到/sdcard/download 目录下,然后慢慢比较有什么差别,但是没看出来。
还有种可能,是对/proc/self/task/tid/status 中的Name有检测,可能会有线程名有问题,所以我有打印出了每个task的Name ,没有任何发现,里面的名字没有什么问题,和正常情况下的名字差不多,没有frida 和其他异常的名称。

此时思路完全卡死,没有别的办法了。
然后我在网上找过这个SO的方法,比如在pthread 中nop掉线程,或者直接nop掉调用这些pthread 的方法。这些方法都会造成app 假死。 app 打开后就卡死在首页了。(找到的方法:0x1C544      0x1B8D4     0x26E5C)三个方法。


我只能在pthread中使用Stalker.follow 看看有哪些指令,看看有什么问题。


经过指令和IDA中的对应方法对比,在IDA中有存在


[培训]科锐逆向工程师培训第53期2025年7月8日开班!

收藏
免费 7
支持
分享
最新回复 (19)
雪    币: 45
活跃值: (3699)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
能够写的这么详细, 确实 花了不少时间, 我估计遇到问题 , 4个小时, 写成文章 4个小时, 特别折腾人. 楼主的 如此的执着精神令小生佩服...
2025-6-2 23:53
1
雪    币: 1449
活跃值: (2716)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
你这不如在内核隐藏frida的痕迹啊?
2025-6-3 00:49
0
雪    币: 112
活跃值: (158)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
感谢分析,新手学习
2025-6-3 10:04
0
雪    币: 234
活跃值: (2278)
能力值: ( LV5,RANK:73 )
在线值:
发帖
回帖
粉丝
5
app是哪个版本的?
2025-6-3 14:33
1
雪    币: 45
活跃值: (3699)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
hacker521 你这不如在内核隐藏frida的痕迹啊?
我也想要学习, 但是ebpf 课程中, r0yuse 佬, 提到过, ksu 逻辑 和  apatch 中的内核模块实现. 想要青椒高手, 探讨,能加wchat ,么? 
2025-6-4 02:34
0
雪    币: 395
活跃值: (447)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
7
calleng 能够写的这么详细, 确实 花了不少时间, 我估计遇到问题 , 4个小时, 写成文章 4个小时, 特别折腾人. 楼主的 如此的执着精神令小生佩服...[em_003]
这个我弄了好多天,菜鸟一枚,想学习逆向的东西。
2025-6-7 13:12
0
雪    币: 395
活跃值: (447)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
8
hacker521 你这不如在内核隐藏frida的痕迹啊?
不知道怎么弄,有什么切入点吗?  或者知识点是什么? 我找找。 谢谢
2025-6-7 13:13
0
雪    币: 395
活跃值: (447)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
9
falconnnn app是哪个版本的?
V16.4.7  你能看出这个APP是哪个?
2025-6-7 13:14
0
雪    币: 395
活跃值: (447)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
10
calleng 我也想要学习, 但是ebpf 课程中, r0yuse 佬, 提到过, ksu 逻辑 和 apatch 中的内核模块实现. 想要青椒高手, 探讨,能加wchat ,么?
电报  @lpy0001
2025-6-7 13:17
0
雪    币: 395
活跃值: (447)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
11
深圳PD Labs 这贴思路清晰、实战痕迹很重,`Java.perform()`被秒退的问题基本摸到了关键点:`/proc/self/status` 和 `maps` 的检测只是外围,核心还是 `libmsaoaidse ...
感谢告知,等我学习好,在找相关工作吧, 现在是个菜鸟,完成不了任何APP的逆向,  想想就可悲,已经学习了近半年了, 还是菜鸟水平。 
2025-6-7 13:21
0
雪    币: 395
活跃值: (447)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
12
深圳PD Labs 这贴思路清晰、实战痕迹很重,`Java.perform()`被秒退的问题基本摸到了关键点:`/proc/self/status` 和 `maps` 的检测只是外围,核心还是 `libmsaoaidse ...
function hook_native_addr(secmodule, addr) {
    if (!secmodule) {
        console.error("[-] libmsaoaidsec.so module not found");
        return;
    }
    var point = secmodule.base.add(addr);
    var startAddr = secmodule.base;
    var endAddr = secmodule.base.add(secmodule.size);

    Interceptor.attach(point,{
        onEnter:function (args){
            Stalker.follow(Process.getCurrentThreadId(), {
                transform: function (iterator) {
                    var instruction = iterator.next();
                    do{
                        if (instruction === null || instruction.address === null) {
                            continue;
                        }
                        if (instruction.address >= startAddr && instruction.address < endAddr) {
                            console.log(instruction.address.sub(secmodule.base) + ":" + instruction);
                        }
                        iterator.keep();
                    }  while ((instruction = iterator.next()) !== null);
                }
            });
 
        },
        onLeave:function(retval){
           
        }
    });
}


var firstHandle = false;
function locate_init() {
    let secmodule = null
    Interceptor.attach(Module.findExportByName(null, "__system_property_get"),
        {
            // _system_property_get("ro.build.version.sdk", v1);
            onEnter: function (args) {
                secmodule = Process.findModuleByName("libmsaoaidsec.so")
                var name = args[0];
                if (name !== undefined && name != null) {
                    name = ptr(name).readCString();
                    if (name.indexOf("ro.build.version.sdk") >= 0) {
                        console.log("locate_init [+] 目标库已加载,开始Hook... secmodule base: " + secmodule.base);
                        if (!firstHandle) {
                            hook_native_addr(secmodule, 0x26334);
                            firstHandle = true;
                        }
                    }
                }
            }
        }
    );
}

发现一个更不知道的方法, 只要在里面加入Stalker.follow 就可以过java hook ,好奇怪。  使用 frida -H xxxxxx  -l xxxx.js -f xxxx  启动后,等会app会被杀死,但是可以手动在手机上打开app, 此时app 就可以被 java hook了。  但是10%的概率会卡死。  原因不明。  我在过广告的过程中发现的,弄了2周了,还是过不了广告,发现应该是在native层加入的广告。 但是没找到JNI的调用,理论上,从界面上点击后,应该会有JNI的调用,在View层将广告的视频流写入到同一个SurfaceView, 但是没找到对应的入口。好多次想放弃了,还是坚持下来了, 不过还是没达到目的。 再研究研究吧~  给自己加油-小菜鸟。


2025-6-7 13:32
1
雪    币: 10
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
13

respect!!!

我之前也研究过这个库,当时只专注于native层对frida注入的检测,得出结论如下:

1、当主线程对libmsaoaidsec.so库完成链接、重定位后,在constructor函数会通过dlsym查找pthread_create创建子线程进行间歇性检查。
2、libmsaoaidsec库实现了字符串特征进行检测(如下图)包括、线程名称、文件fd、文件名称(/data/local/tmp)、TracerPid、等等。
我以为所有的检测工作都是在子线程中进行的,但是当我通过spawn方式进行注入魔改版的frida(基本去除了所有的字符串特征),libmsaoaidsec会在主线程中触发崩溃机制,libmsaoaidsec在不断进化,我测试的版本已经不能仅仅通过hook pthread_create进行绕过了,主线程也会检测frida。
此外,java层的hook检测我也没搞清是怎么回事,不只是Java.perform,当我使用Java.use也会被检测到,不知道是什么检测方法,看了许多帖子,并没有找到相关的研究,问了AI也没头绪,就暂时搁置了。
楼主加油,看好你!

2025-6-7 18:54
1
雪    币: 10
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
14

我刚刚测试了一下,当使用Java层的hook,libart.so的PrettyMethod会被frida-agent hook,因为inline hook就是将目标函数入口的指令替换成了跳转到自定义代码的跳转指令(arm64下为BLR),所以,通过检测PrettyMethod入口的字节码就知道是否使用了Java Hook。

楼主可以试试执shell命令

readelf /apex/com.android.art/lib64/libart.so -s | grep PrettyMethod

记录一下PrettyMethod函数在原始libart.so文件中,入口的指令。
再注入frida,然后随意使用一个Java Hook,再查看内存中libart.so库PrettyMethod函数的入口指令。


最后于 2025-6-8 02:48 被null0bj编辑 ,原因:
2025-6-7 20:33
1
雪    币: 395
活跃值: (447)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
15
null0bj 我刚刚测试了一下,当使用Java层的hook,libart.so的PrettyMethod会被frida-agent hook,因为inline hook就是将目标函数入口的指令替换成了跳转到自定义代 ...
好的,我尝试一下看看,  感谢提供的思路。 看来还得学习一下inline hook的原理
2025-6-9 15:24
0
雪    币: 395
活跃值: (447)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
16
null0bj respect!!!我之前也研究过这个库,当时只专注于native层对frida注入的检测,得出结论如下:1、当主线程对libmsaoaidsec.so库完成链接、重定位后,在constructor函 ...
一起加油吧
2025-6-9 15:25
0
雪    币: 117
活跃值: (849)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
写的很好很细 切实可行 学习下
2025-6-9 18:10
0
雪    币: 163
活跃值: (2778)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
很好的分析啊
2025-6-10 00:53
0
雪    币: 208
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
19
null0bj 我刚刚测试了一下,当使用Java层的hook,libart.so的PrettyMethod会被frida-agent hook,因为inline hook就是将目标函数入口的指令替换成了跳转到自定义代 ...
怎么过这个检测
5天前
0
雪    币: 10
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
20
mb_pnlabahd 怎么过这个检测
对PrettyMethod的检测一般利用子线程轮询检测。所以,在主线程使用pthread_create clone子线程的时候可以知道子线程所执行的偏移地址,将该偏移地址放一条ret指令即可。
5天前
1
游客
登录 | 注册 方可回帖
返回