论坛首页 移动安全专区 阅读主题

[原创]libmsaoaidsec.so 检测监测 绕过 Hook 脚本

1 浏览 0 回复
#1 楼主 2026-06-01 10:49:03
前文:[原创]libmsaoaidsec.so 检测体系分析
[原创]经典 Frida 检测 libmsaoaidsec.so 绕过

在 Android Native 安全分析中,很多安全组件并不会等到 JNI_OnLoad​ 后才启动检测,而是会将部分关键逻辑放在 ​.init​​ **、**​ ​.init_proc​​ 或 ​.init_array​​ 等更早的初始化阶段。

​libmsaoaidsec.so​ 的检测逻辑就存在这类特征:如果在 android_dlopen_ext​ 的 onLeave 阶段再安装 Hook,库的初始化逻辑通常已经执行完毕,部分反调试、注入检测或完整性校验可能已经触发,最终表现为 App 闪退、退出或关键流程异常。

Android 加载 Native SO 时,通常会经过以下流程:

需要注意的是,​android_dlopen_ext​​ 的 ​onLeave​​ 并不等价于“SO 刚刚映射完成” 。当 onLeave​ 被触发时,加载器通常已经执行完 .init​ 和 .init_array​ 中的初始化函数。如果目标库把检测逻辑放在这些早期阶段,那么在 onLeave 再安装 Hook 往往已经太晚。

更合适的思路是:在 ​android_dlopen_ext​​ 的 ​onEnter​​ 中识别目标 SO 加载事件,然后寻找 ​.init_proc​​ 内部调用的外部导入函数作为二级锚点。这样既可以保证目标 SO 已经进入加载流程,又能在其初始化逻辑执行过程中插入 Hook。

对 libmsaoaidsec.so​ 的 init_proc​ 进行分析,可以看到其早期逻辑中调用了 sub_123F0:

继续查看 sub_123F0​,可以发现其调用了 __system_property_get 读取系统属性:

对应导入表中也可以看到 __system_property_get:

由此可以确定一个较理想的早期 Hook 链路:

这个锚点的优势在于: ​__system_property_get​​ 是 ​.init_proc​​ 早期调用的外部导入函数,触发时机早于大多数检测逻辑,且比盲目轮询模块加载更稳定。

脚本中主要通过函数返回值判断不同检测逻辑是否启用,并对部分关键分支进行返回值替换或直接写入 RET 指令。

部分检测逻辑不是由单个函数返回值决定,而是由多个函数组合判断。

Frida / 注入痕迹检测:

含义如下:

轮询代码 CRC 校验:

含义如下:

这类复合条件非常适合通过日志进行动态观察,因为它不仅能显示某个函数是否被调用,还能帮助判断当前运行环境下到底触发了哪一类检测。

整体脚本可以拆分为四个部分:

这里选择 onEnter​ 而不是 onLeave​,关键原因在于:目标库的初始化函数会在 ​android_dlopen_ext​​ 返回前执行。如果等待 onLeave,很多早期检测已经错过。

这段逻辑的核心是过滤属性名:

只有当目标库读取该属性时,才认为命中了早期初始化锚点。随后再获取 libmsaoaidsec.so​ 的基址并安装 Hook,避免对其他模块调用 __system_property_get 的行为造成干扰。

以 sub_CC64​ 为例,该函数返回 218 时,可以判断 Magisk / root 检测相关逻辑被启用:

这种写法适合做动态观测:每个检测函数在进入和返回时都会打印日志,最终通过 [DETECT]​ 或 [SKIP] 输出当前检测分支是否激活。

对于部分校验函数,脚本直接在 onLeave​ 阶段替换返回值。例如 sub_16720:

这里的重点不是固定值 666​ 本身,而是 通过修改返回值改变上层分支判断结果。

脚本还对若干偏移直接写入 ARM64 RET 指令,使相关函数立即返回:

对应 Patch 实现如下:

这种方式适用于已经确认目标函数主要用于检测、线程创建或轮询校验的场景。

下面是整理后的完整 Frida 脚本。脚本目标为 ARM64 环境下的 libmsaoaidsec.so,通过早期锚点安装 Hook,并输出各类检测分支状态。

使用 Frida spawn 模式启动目标 App,并加载 Hook 脚本:

示例输出如下:

继续观察 Patch 结果:

检测分支输出示例:

从输出可以确认:

本文围绕 libmsaoaidsec.so 的早期初始化检测,整理了一套可复用的 Frida 分析思路:

这类分析的关键不在于某一个固定偏移,而在于方法论:先解决 Hook 时机,再定位初始化锚点,最后围绕检测函数建立可观测、可验证、可迁移的动态分析链路。


关键函数或段


​dlopen​ / android_dlopen_ext
系统加载器将目标 SO 映射到进程内存


​.init​ / .init_proc
执行 SO 的早期初始化代码


​.init_array
执行初始化数组中的函数,例如 C++ 全局构造函数


​JNI_OnLoad
注册 JNI 方法并完成 Java 与 Native 层绑定


判断条件
检测含义


​sub_CA28
​0xCA28
返回值是否为 167
ADB / USB 调试环境检测


​sub_CAA8
​0xCAA8
返回值是否为 248
Frida / 注入痕迹检测的条件之一


​sub_CAE8
​0xCAE8
返回值是否为 249
反调试、TracerPid、线程状态检测


​sub_CC64
​0xCC64
返回值是否为 218
Magisk / root 检测


​sub_CEE4
​0xCEE4
返回值是否为 203
目标区域 CRC32 校验


​sub_C830
​0xC830
返回值是否为 1
轮询代码 CRC 校验条件之一


​sub_95C8
​0x95C8
返回值是否为真
轮询代码 CRC 校验条件之一


​sub_12D9C
​0x12D9C
返回值是否为真
Frida / 注入痕迹检测的条件之一


​sub_25A48
​0x25A48
​(retval & 1) == 0
Native 环境检测、代码 CRC / APK v1 签名校验


​sub_CEA4
​0xCEA4
返回值替换为 666
通过返回值修改绕过特定检测分支


​sub_16720
​0x16720
返回值替换为 666
通过返回值修改绕过校验结果


__int64 __fastcall init_proc(__int64 a1)
{
...

StatusReg = _ReadStatusReg(ARM64_SYSREG(3, 3, 13, 0, 2));
v15 = *(StatusReg + 40);
s_1 = &StatusReg - 250;
*off_47FB8 = sub_123F0(a1);
...
}

__int64 sub_123F0()
{
_QWORD nptr[2];

nptr[1] = *(_ReadStatusReg(ARM64_SYSREG(3, 3, 13, 0, 2)) + 40);
nptr[0] = 0LL;
__system_property_get("ro.build.version.sdk", nptr);
return atoi(nptr);
}

extern:00000000000A76D8 IMPORT __imp___system_property_get
extern:00000000000A76D8 ; CODE XREF: __system_property_get+C
extern:00000000000A76D8 ; DATA XREF: LOAD:__system_property_get_0

const shouldCheck = lastSubCAA8Ret === 248 && !lastSub12D9CRet;

const shouldCheck = lastSubC830Ret !== 1 || !!lastSub95C8Ret;


回复或点赞可查看完整内容


传播安全知识、拓宽行业人脉——看雪讲师团队等你加入!


#基础理论
#逆向分析
#HOOK注入
#工具脚本
#其他

感谢分享


1天前


.mobile_more_operate_btn {
padding: 0px 4px;
background: #dee5ea;
border-radius: 0.2rem;
cursor: pointer;
}
.mobile_more_operate {
display: none;
left: -195px;
top: -13px;
width: 185px;
background: #222222;
border-radius: 0.3rem;
}
.mobile_more_operate_box .post_report {
color: #fff!important;
}


tonykros


雪    币:


能力值:


( LV1,RANK:0 )


在线值:


1天前


.mobile_more_operate_btn {
padding: 0px 4px;
background: #dee5ea;
border-radius: 0.2rem;
cursor: pointer;
}
.mobile_more_operate {
display: none;
left: -195px;
top: -13px;
width: 185px;
background: #222222;
border-radius: 0.3rem;
}
.mobile_more_operate_box .post_report {
color: #fff!important;
}


xianhuimin


雪    币:


活跃值:


(5588)


能力值:


( LV2,RANK:10 )


在线值:

感谢分享


1天前


.mobile_more_operate_btn {
pad

...(内容过长,已截断)

---
来源: 看雪论坛
原文链接: https://bbs.kanxue.com/thread-291403.htm

暂无回复,快来抢沙发吧!

请登录后参与讨论

立即登录 注册账号