SO加固强度怎么量化?腾讯ACE与FairGuard静态分析实测

拿到两个AArch64安全模块时,file给出的第一印象很接近:都是64位共享库,都已经Strip,文件大小也只相差约0.36 MiB。NX、Full RELRO和BIND_NOW等基础安全项同样全部通过。

继续检查后,差异很快出现。FairGuard样本的节区表只覆盖文件的6.94%,.text仅16字节且全部为零;腾讯ACE样本的节区表覆盖率达到99.96%,还能恢复16,286条FDE记录。两份文件在常用ELF工具中的可读程度并不在一个水平线上。

本文用同一套静态口径,比较两份安全模块在ELF结构、动态符号、字符串、重定位、函数边界和局部熵分布上的表现,并给出可以复核的命令与量化结果。

样本与分析方式

项目 FairGuard 腾讯ACE
游戏与版本 《闪烁之光》4.4.8 《火影忍者》1.79.79.9
安全模块 libFairGuard.so libtersafe.so
SHA-256 e34dd793cb58f360fc235e0375486a9a116154d664724ce5e688a46c611bf4fe 517f1e3891e7a7c5dd8254bedcb09a5fe1d2acb0147cec757efb3a06ec5b2a10
架构 AArch64 AArch64
文件大小 5.16 MiB 5.52 MiB
ELF类型 64位共享库 64位共享库
Strip

本次使用ChatGPT GPT-5.6 Sol,推理强度设置为"极高"。AI主要用于组织检查项、汇总命令输出、统计异常分布;涉及结构判断的数据,再回到ELF工具输出中复核。

基础信息可以直接通过以下命令重现:

bash 复制代码
sha256sum libFairGuard.so libtersafe.so
file libFairGuard.so libtersafe.so

readelf -hW -lW -SW -sW -rW -dW libFairGuard.so
readelf -hW -lW -SW -sW -rW -dW libtersafe.so

readelf --debug-dump=frames libFairGuard.so
readelf --debug-dump=frames libtersafe.so

strings -a -n 8 libFairGuard.so
strings -a -n 8 libtersafe.so

节区覆盖率、最大无节区区间、字符串长度分档和64 KiB分块熵值,需要对上述结果继续做脚本统计。

1. ELF结构:工具能否直接建立代码地图

指标 FairGuard 腾讯ACE
节区表覆盖文件比例 6.94% 99.96%
最大无节区描述区域 4,805,144字节 1,799字节
最大无节区区域占比 88.80% 0.03%
声明的.text大小 16字节 3,590,944字节
.text零字节比例 100% 10.10%
RX段中可执行节区覆盖率 0.0039% 65.74%

FairGuard的.text只有16字节且全部为零,显然没有呈现实际代码主体。其ELF入口为0xfe00,落在节区表未描述的区域;文件内最大的无节区区间达到4,805,144字节,占比88.8%。

这种布局会直接影响IDA、Ghidra、radare2等工具的初始识别。分析者无法只依赖节区表确定代码范围,还要回到程序段、入口和加载逻辑中重新寻找有效内容。

腾讯ACE的节区表覆盖率为99.96%,.text.rodata.eh_frame、重定位表和版本表都能正常定位。常规工具打开文件后,更容易生成初始代码地图。

2. 符号与字符串:能留下多少定位线索

动态符号

指标 FairGuard 腾讯ACE
动态符号总数 1,028 288
空名称符号 1,002(97.47%) 1(0.35%)
可读符号比例 2.24% 99.65%
可读导出接口 0 71
唯一导入函数名 4 216
4字节伪函数条目 999 2
不落在声明节区的符号 1,007 0
readelf一致性警告 10条 0

FairGuard虽然包含1,028个动态符号,但1,002个没有名称,999个函数条目的长度固定为4字节,另有1,007个符号地址与声明节区不一致。3个非空导出名称也是不可读字节序列,可读导出接口因此记为0。

腾讯ACE可以直接识别71个导出接口,包括JNI_OnLoadtss_sdk_inittss_sdk_encryptpackettss_sdk_decryptpacket等。部分名称来自公开SDK接口,但在逆向工具里仍是清晰的路标,可以沿交叉引用继续定位初始化、数据收发和加解密逻辑。

可打印字符串

指标 FairGuard 腾讯ACE
长度≥8 427 4,224
长度≥16 27 1,624
长度≥32 12 370
.rodata可打印字符串 6 10,880
源码路径 0 6
明文JNI_OnLoad 未发现 可见

为降低高熵数据随机形成短字符串带来的干扰,这里主要观察8字节以上的连续可打印ASCII内容。

腾讯ACE中长度达到16字符的字符串为1,624条,约为FairGuard的60倍,还能提取到NDK版本、Build ID及部分.cpp和LLVM编译路径。FairGuard主要保留依赖库名称与GCC 4.9编译痕迹,没有提取到可直接指向反调试、Hook或签名校验功能的明文关键词。

3. 重定位与FDE:函数边界还能恢复多少

指标 FairGuard 腾讯ACE
重定位总数 93 25,380
INIT/FINI目标 4 66
位于标准.text的INIT/FINI目标 0 66
位于无节区区域的INIT/FINI目标 4 0
可恢复FDE记录 0 16,286
.eh_frame零字节比例 100% 32.51%
.gcc_except_table零字节比例 100% 38.33%

FairGuard的4个构造与析构目标全部落在无节区描述区域。.eh_frame.gcc_except_table虽然存在,内容却全部为零,readelf只能读出终止符,无法恢复有效FDE。

腾讯ACE可以恢复16,286条FDE记录。即便这些记录不包含函数名称,也能辅助逆向工具识别函数边界和栈展开关系。

重定位数量受代码规模和编译方式影响,单独比较意义有限。结合初始化入口、节区结构和FDE一起看,腾讯ACE保留了更多可被工具直接利用的交叉引用信息。

4. 熵值:整体数字低,不等于内容更透明

指标 FairGuard 腾讯ACE
整体信息熵 4.626 6.456
文件零字节占比 54.43% 21.89%
RX段中熵≥7.8的64 KiB块 35/83,42.17% 4/84,4.76%
RX段中熵<1的64 KiB块 42/83,50.60% 0/84

FairGuard的整体熵更低,原因是文件中存在大量零填充。若只对比整体熵值,很容易误判。

将RX段按64 KiB切分后,可以看到FairGuard同时包含大量高熵块与低熵零块。结合88.8%的无节区区域,这种分布更接近隐藏载荷、加密数据或自定义布局。腾讯ACE的数据分布较为连续,高熵分块数量也更少。

5. 基础安全项持平,量化差距来自静态信息隐藏

两份样本均通过NX Stack、GNU RELRO、BIND_NOW和Full RELRO检查,也都没有TEXTREL与RWX加载段。这部分没有拉开差距。

业内没有统一的SO加固百分制。下面采用本次专用的"静态抗分析强度"评分,将结构隐藏、信息暴露和工具可恢复程度汇总到同一张表中。总分适合快速查看,判断依据仍以原始指标为准。

评分维度 权重 FairGuard 腾讯ACE
ELF结构与节区隐藏 25 23 8
符号与接口信息隐藏 20 18 11
字符串与构建信息保护 15 14 8
初始化、重定位及FDE隐藏 15 14 7
数据不透明度与局部熵特征 15 13 9
基础ELF安全属性 10 10 10
总分 100 92 53

结论

在这套静态口径下,libFairGuard.so表现出更强的结构隐藏和信息收敛:实际内容没有通过常规节区完整呈现,动态符号中包含大量无名及固定长度条目,字符串、重定位和函数展开信息也更少。常规工具很难在打开文件后直接恢复有效代码地图。

libtersafe.so同样完成了Strip,基础ELF安全配置也比较完整,但整体保持标准共享库布局。符号、接口、字符串、重定位及FDE能够被常用工具较完整地提取,建立模块结构和选择后续分析入口会更直接。

这次AI辅助分析的价值主要体现在批量统计和异常筛选。GPT-5.6 Sol可以较快汇总节区覆盖率、无名符号、长字符串和FDE等数据,人仍需根据readelf等工具的原始输出复核口径与异常项。

如果要快速检查一份SO的静态抗分析程度,可以依次看五个位置:

  1. 节区表是否真实描述代码主体;
  2. 动态符号能否提供函数名和接口入口;
  3. 字符串中是否暴露功能名称与构建路径;
  4. 重定位和FDE能否帮助恢复交叉引用与函数边界;
  5. 局部熵分布是否与节区布局相互印证。

只看文件大小、Strip状态或单一熵值,都很难解释常用逆向工具中的实际分析阻力。

相关推荐
终端安全笔记3 小时前
描述文件、企业证书、MDM 不是三个名字,是三层
android·ios·智能手机
字节暗面3 小时前
一次游戏安全SO静态分析记录:腾讯ACE与FairGuard加固强度对比
android·逆向工程·游戏加固
传奇开心果编程4 小时前
【Jetpack Compose基础语法学与练】第9课 SideEffect副作用 + LaunchedEffect,处理异步任务和生命周期
android·学习·ui·kotlin·android jetpack
2401_833269305 小时前
RecyclerView多布局详解
android
v_34836087626 小时前
Android_8 zygote启动分析
android
消失的旧时光-19436 小时前
Android 系统层扫盲 11:JNI 到底是什么?Java / Kotlin 是怎么调用 C/C++ 的?
android·binder·zygote·system_server·aops
mmsx6 小时前
Android 地图几万要素卡成幻灯片?顶点缓冲批上传与显存复用
android·opengl·地图·栅格
北京自在科技17 小时前
谷歌 Find Hub 迎来新版本更新
android·安卓
晚风醉蝶17 小时前
用 Babel AST 把“天书“ JS 一键还原:七步流水线反混淆实战
ast·逆向·反混淆·代码还原·控制流平坦化