腾讯 ACE / tersafe × DFM(com.tencent.tmgp.dfm)反作弊完整分析报告
目标:三角洲行动手游(Delta Force Mobile,UE4 引擎)tmgp 渠道,腾讯 ACE(Anti-Cheat Expert)注入的反作弊本体
libtersafe.so(= proxima 渠道libanogs.so的同一 anogs 引擎,仅改名)。 方法:minimem(Android 内核级读写/硬件断点,runtime 动态)+ IDA Pro(headless,静态反编译/反汇编)双管齐下。 样本:runtime PID 27854 / 31597(基址随注入变,只认模块 RVA / 段内 offset)。 日期:2026-07-04 ~ 07-05。 方法论来源:承接 proxima 渠道 s9/s10 完整分析集(..\..\..\proxima.dfm\),逐环复用、数据全新(模块名/基址/偏移/字节码/常量池/记录库布局全不同)。本报告为 tmgp 分析总纲,各业务详见配套专题文档(§9 索引)。
一、总体架构
腾讯 ACE 在 libUE4 引擎函数入口植入 260 个直接入口 hook(LDR X16;BR X16,runtime 实扫),经三层跳转链分流到四套独立业务:一套取数加密(FEncTransform)+ 三支柱检测(比较器 VM / 寄存器 VM / 检测段)。
| 业务 | 本体位置 | 功能 | 执行频率 |
|---|---|---|---|
| ① FEncTransform | anon 主段 0xEA000 | USceneComponent transform 坐标加密(防 ESP/自瞄/听声辨位) | 持续高频(runtime 8035次/批) |
| ② 比较器 VM | libtersafe(checklist wrapper) | desc-item-operand + 165 路由通用检测(模块完整性/inline-hook/反瞬移/内存) | 持续高频(每帧,16440次/批) |
| ③ 寄存器 VM | libtersafe sub_359174 | 弹道/输入的设备完整性(Root/MediaDrm/Aorus/ShadowHook) | 极低频/条件化(runtime 0 命中) |
| ④ 检测段 | 4× anon 次段 | 设备信任根/环境指纹/maps+线程/设备枚举 | 条件触发(det③ 未映射) |
核心结论:tmgp libtersafe 与 proxima libanogs 逐环同构(结构/字段/路由/算法/判定常量一致,仅地址与数据不同),部分函数二进制级逐地址复用(如检测段 JNI KeyAttest sub_10564/10128/11DA0)。
二、Hook 注入体系(入口层)
2.1 三层跳转链
2.2 六段分流(runtime 实扫 260,静态 dump 仅少量)
| 段 | hook | 落点 | 业务 |
|---|---|---|---|
| MAIN_FEncTransform | 230 | 主段 0xEA000 | 取数加密 |
| libtersafe checklist | 12 | 0x41B020(×?)/0x41B228 | 比较器 VM |
| det 段(×4) | 16 | 4 objects 次段 | 检测段 |
| 快照 trampoline | 2 | 0x72b976b000 | 寄存器 VM |
- 发现方法:runtime 扫 libUE4 全可执行映射搜特征
50 00 00 58 00 02 1F D6(LDR X16,#8;BR X16),4 字节对齐,literal 低 48 位去 tag。 - 产物:
hook_scan_raw.csv/hook_map_full.csv(260 行 rva→slot→body→seg→handle_off→2nd_hop)。 - 详见 libUE4_直接入口Hook全量映射_tmgp。
三、业务① FEncTransform 取数加密
定性:把 USceneComponent 的 transform 字段(坐标/朝向/矩阵)在内存中加密存储 + 诱饵混淆,只有经 tersafe hook 链取数才得明文 → 阻断外挂直读组件内存做 ESP/自瞄/透视/听声辨位。
3.1 端到端数据流
3.2 记录库布局(tmgp 全新参数 vs proxima/s9)
| 项 | s9 | proxima s10 | tmgp s10 |
|---|---|---|---|
| 记录元素步长 | 0x578 | 0x570 | 0x590 (1424) |
| slot 区起点 | +0x40 | +0x38 | +0x68 |
| slotCount | 10 | 11 | 10 (%0xA) |
| slot 步长 | 0x30 | 0x30 | 0x30 |
| 主入口 | GetComponentTransform | 0xE90FAFC→+0x3A000 | 0xE738950→+0x45000 |
| 盐乘子 | — | — | 0x39711CFC7F2C2879 |
| 盐加 | — | — | 0x4104055BAD62F84D |
3.3 runtime 确认(PID 31597)
- 主段 runtime 基址
0x71eb936000(0xEA000) - GET handler
+0x45000(0x71eb97b000) 执行断点 8035 次高频命中(100% LR=0x6faa210530)→ 加密链 runtime 持续运行 - x0=root_raw 指向 FEncTransform 记录库索引 map 根(红黑树节点,非 UE4 组件)
- IDB 补建 359 函数 / 125 page 对齐 handler(getter 11 / 记录库 86 / 特殊 26 / stub 2)
四、业务② 比较器 VM(checklist 通用检测)
描述符(desc) + item 容器(std::map 红黑树) + operand 表达式树(AST) + 165 路由分发;返回地址 x30 匹配检测描述符;持续高频运行。
4.1 引擎执行流
4.2 VM 数据结构层级
detect_ctx 单例 (qword_566810, 2104B, runtime 0x718552D200)
└─ desc 列表(静态 B: ctx+0x18 / 动态组: ctx+0x2B0[i],253 desc / 12 含VM)
└─ desc(+0x10 leftmost / +0x18 root / +0x20 nitem)
└─ item 容器 = std::map<int,item*> 红黑树(node 0x30: L@0/R@8/P@0x10/flag@0x18/key@0x20/item*@0x28)
└─ item(+0x408 operand)
└─ operand(+0x18 class / +0x19 key / +0x20 const|snap句柄 / +0x28 字符串SSO / +0x40 childvec / +0x58 hash)
4.3 165 路由(class1=8 / class2=29 / class3=128)+ 检测点
| class3 原语 | key | handler | 语义 |
|---|---|---|---|
| check_mem | 1 | 0x4386CC | 内存内容检测 |
| check_sym_hooked | 10 | 0x4398B8 | 符号 inline-hook |
| check_module_integrity | 11 | 0x439F98 | 模块完整性 |
| snapshot_sample | 49 | 0x43A838 | 快照采样(反瞬移) |
| check_range | 52 | 0x43AE80 | 区间边界 |
检测目标(VAL.STR 实读):模块完整性 libUE4.so/libtersafe.so;inline-hook libc.so:sprintf、libandroid.so:AMotionEvent_getFlags;反自动点击 start_record_clicker;快照采样反瞬移。
4.4 runtime 活跃度 + VM2ARM
- eval_operand runtime 16440 次命中 100% c3/k49 快照采样(内联快速路径,绕过 class3_detect 重分派)→ 运行态唯一高频检测 = 反瞬移采样;主集/输入集条件触发
- VM2ARM 全量反解:主集 12 item + 输入集 17 item 检测表达式 + VM→ARM 伪汇编(
full_*.csv+vm2arm_tmgp.py)
详见 libtersafe_checklist比较器VM_完整分析 / 数据结构与指令系统参考 / VM字节码全量反解_VM2ARM。
五、业务③ 寄存器字节码 VM(弹道/输入设备完整性)
Dalvik/DEX 风格寄存器机(sub_359174,序言 EF3BB66D),~70 opcode,解释 ~270KB 字节码;极低频/条件化触发(runtime 多次 0 命中)。
5.1 入口链
5.2 检测目标(常量池 + SYMRES 符号,修正解密)
| 类别 | 目标 |
|---|---|
| 三模块完整性 | libUE4.so / libtersafe.so / libtprt.so |
| 反 Root | KernelSU /data/adb/ksud、Magisk |
| 设备指纹 | MediaDrm getPropertyByteArray/deviceUniqueId |
| 外挂框架(tmgp 特有) | Aorus (libaorus.so) / ShadowHook (shadowhook-enter) |
| 子进程反调试(tmgp 新增) | fork/pipe2/waitpid |
| native API 武器库(~110,SYMRES 修正解密) | 信号反调试 sigaction 族 / 计时 / prctl / popen / fanotify / __system_property_get / self-exe 自校验 |
| hook 自检 | libUE4+0xE738950(= FEncTransform detour,双 VM 互守护) |
- 序幕 15 加密符号(pool+0x6260,自密钥 XOR):proxima 9 + tmgp 子进程组 6
详见 libtersafe_寄存器VM_完整分析 / 寄存器VM指令系统参考。
六、业务④ 检测段(4× objects_external_alloc 次段)
独立检测子系统(det guard hook 落点 + 段内自包含编排),与两台 VM 三足鼎立。
6.1 四段总览
| # | det 段(runtime) | size/函数 | 定性 | proxima |
|---|---|---|---|---|
| ① | 0x729a1f6000 | 0x14000/63 | JNI Key Attestation 设备信任根 + GPackageLoader vtable + Charles + ACE云配 | 7be213a(逐地址同构) |
| ② | 0x72bbc86000 | 0x11000/12 | 输入设备指纹+虚拟输入检测(AInputEvent/InputDevice.isVirtual) | 7c055ad |
| ③ | (未映射) | 0x29000/42 | maps完整性+分配器基线(scudo)+线程枚举(RenderThread/GameThread/TaskGraphNP)+sigaction信号+.dynsym符号 | 7be1d6d+扩展 |
| ④ | 0x72bc0df000 | 0x2d000/33 | 设备节点全枚举指纹+Magisk+minidump+PackageManager应用/悬浮窗/隐藏检测 | 强化/新增 |
6.2 立体检测纵深
6.3 det① RootOfTrust 判定逻辑(IDA decompile,逐地址同构)
sub_11DA0(=proxima keyattest_parse_rot)遍历 AuthorizationList TLV:
- tag 704 → deviceLocked(期望
0x100000000,=false 检出已解锁) - tag 709 → verifiedBootKey 32B 摘要(期望
0x1100000000,≠官方检出自定义 ROM) - sub_10564(4828B)/sub_10128(1084B)/sub_11DA0(640B) 与 proxima 7be213a 地址+size 完全一致
6.4 字符串解密(strdec 算法逆出)
sub_FDAC(26 字节 in-place):v=ROR(c)+i; v=((((-v>>2)-(v<<6)-48)^0xD6)-19); c=ROL(v),密钥 0xD6 = proxima 四密钥之一。
- 密文条件载入:加密串在 .bss,运行期动态载入 + in-place 解密;det② 当前静默(sub_A01C 0 命中)→ .bss=0,明文需进对局触发时抓 byte_FF8E
- det② 输入设备目标是 .rodata 明文(runtime 已确认)
七、双 VM 互守护 + 检测协同
纵深防御:FEncTransform(数据加密挡直读)+ 比较器 VM(实时行为/内存检测)+ 寄存器 VM(设备完整性取证)+ 检测段(信任根/环境/设备/线程)—— 加密与检测双向互守护。
八、tmgp ↔ proxima 逐环对照
| 维度 | proxima | tmgp |
|---|---|---|
| 反作弊本体 | libanogs.so | libtersafe.so |
| 第三完整性模块 | libanort.so | libtprt.so |
| 直接入口 hook | 256 | 260 |
| FEncTransform hook | 229 | 230 |
| 记录库 步长/slot/count | 0x570/+0x38/11 | 0x590/+0x68/10 |
| checklist wrapper | 0x44CB90/0x44CD98 | 0x41B020/0x41B228 |
| VM 解释器 | sub_403DF4 | sub_359174 |
| 路由数 | 166 | 165 |
| 寄存器 VM 字节码 | 192KB (0x2F05C) | ~270KB (0x420fb) |
| 检测段 JNI KeyAttest | 7be213a sub_10564/10128/11DA0 | 逐地址+size 完全一致 |
| strdec 密钥 | 0xD3/CB/BF/D6 | 0xD6(同族) |
| 外挂检测 | KernelSU/Magisk | + Aorus/ShadowHook(tmgp 定向) |
| 子进程反调试 | 无 | fork/pipe2/waitpid(新增) |
| 保护模型/ISA/算法/判定常量 | — | 逐环同构(仅地址/数据不同) |
结论:tmgp = proxima 同一 anogs/tersafe 引擎,方法论逐环复用;数据全新 + tmgp 强化(Aorus/ShadowHook 定向、子进程反调试、检测段线程枚举/设备全枚举)。
九、文档与产物索引
dec_hook/(反作弊)
| 文档 | 内容 |
|---|---|
README_tmgp_dechook_2026-07-04_CN.md |
dec_hook 总纲 |
libUE4_直接入口Hook全量映射_tmgp_2026-07-04_CN.md |
260 hook 三层链/6段 |
libtersafe_checklist比较器VM_完整分析_tmgp_2026-07-04_CN.md |
比较器 VM 引擎/路由/检测/runtime |
libtersafe_VM数据结构与指令系统_参考_tmgp_2026-07-04_CN.md |
数据结构+ISA+完整 AST 速查 |
VM字节码全量反解_VM2ARM_tmgp_2026-07-04_CN.md |
比较器 VM 字节码→表达式/ARM |
libtersafe_寄存器VM_完整分析_tmgp_2026-07-04_CN.md |
寄存器 VM 全环 |
libtersafe_寄存器VM指令系统_参考_tmgp_2026-07-04_CN.md |
寄存器 VM ISA 速查 |
libtersafe_检测段_完整分析_tmgp_2026-07-05_CN.md |
检测段索引/总览(4 段总表 + 立体纵深 + 跨段结论) |
det1_设备信任根_JNI_KeyAttestation_tmgp_2026-07-05_CN.md |
det① KeyAttest + sub_11DA0 RootOfTrust decompile |
det2_输入设备指纹_虚拟输入检测_tmgp_2026-07-05_CN.md |
det② InputDevice/AInputEvent + strdec 6-stub + detect_ctx |
det3_maps完整性_线程枚举_信号_ELF符号_tmgp_2026-07-05_CN.md |
det③ maps/线程/信号/.dynsym(★双污染裁决) |
det4_设备节点枚举_Magisk_minidump_应用检测_tmgp_2026-07-05_CN.md |
det④ 设备枚举/Magisk/minidump/PackageManager应用检测 |
libtersafe_检测段_代码级反解_det2det3_tmgp_2026-07-05_CN.md |
(已拆分备查)det②/det③ 代码级 |
EncTransform/(取数加密)
| 文档 | 内容 |
|---|---|
FEncTransform_tmgp_完整分析_2026-07-04_CN.md |
保护模型/数据流/记录库/handler/runtime |
CSV / 脚本 / dump
hook_scan_raw.csv · hook_map_full.csv · tersafe_route_table.csv · tersafe_class3_dict.csv · tersafe_vm_desc_reversed.txt · tersafe_regvm_symbols_targets_2026-07-04.txt · full_main_700cf09000.csv · full_input_700d5e4600.csv · vm2arm_tmgp.py · regvm_disasm_tmgp.py · dumps/(libtersafe/4 det/regvm/trampoline IDB+bin) · EncTransform/main_71dc17a000_ea000_20260704.bin.i64
十、关键地址 / 常量速查(tmgp)
[模块] libtersafe(反作弊本体) / libtprt(第三完整性) / libUE4(引擎) / FEncTransform主段 0xEA000
[FEncTransform] detour libUE4+0xE738950 → 主段+0x45000; 记录库步长0x590/slot+0x68/count10;
盐乘子 0x39711CFC7F2C2879 / 盐加 0x4104055BAD62F84D
[比较器VM] wrapperA/B 0x41B020/0x41B228; match_retaddr 0x41CA40; runner 0x41CE40;
exec_linear 0x41CFF4/jump 0x41D310; eval_item 0x41E260; eval_operand 0x420214;
class1/2/3/4 = 0x421624/0x421900/0x421B44/0x464610; 路由表 0x4436EC; ctx单例 qword_566810
class3: k1=0x4386CC k10=0x4398B8 k11=0x439F98 k49=0x43A838 k52=0x43AE80
[寄存器VM] dispatch 0x317D04; gate 0x2F62B0; expected_sig 0x2F4EF0; detect_method 0x2EF7D0;
interp_main 0x359174(变体 0x345428/0x34D44C); SYSCALL handler 0x35A938;
字节码 0x71fe11b000(PCMAX 0x420fb); 常量池 0x72b9742000; SYMRES 序幕 pool+0x6260(^自密钥)
[检测段] det① JNI KeyAttest: gen_main 0x10564/verify 0x10128/parse_rot 0x11DA0(RootOfTrust tag704/709,期望0x100000000/0x1100000000)
det② strdec: sub_FDAC(^0xD6 in-place)/编排 sub_E01C/path_check sub_FA90
det③ maps: sub_256D4(sscanf %llx-%llx)/libc+.dynsym sub_2624C/线程枚举 sub_C868(白名单 RenderThread/GameThread/TaskGraphNP + sigaction)
det④ Magisk: sub_2201C(MAGISKTMP+maps+memmem)/主体 sub_285C0; PackageManager(SYSTEM_ALERT_WINDOW悬浮窗/[HideToMe]隐藏/checkPackageStartable)
[runtime基址 PID31597] libtersafe 0x70b0c0f000 / libUE4 0x706106b000 / FEncT主段 0x71eb936000 /
detect_ctx 0x718552D200 / det① 0x729a1f6000 / det② 0x72bbc86000 / det④ 0x72bc0df000
[双VM互守护] 寄存器VM+比较器VM 校验 FEncTransform detour(libUE4+0xE738950)完整性
报告范围说明:本报告涵盖 tmgp「反作弊 + 取数加密」全部业务(FEncTransform / 比较器 VM / 寄存器 VM / 4 检测段 / Hook 体系)。游戏机制层(弹道/角色/地图,proxima s9 weapon/dump 有分析)在 tmgp 侧未展开——如需,可套用 proxima 方法论 + libUE4 IDB(dump/ue4.so.bin.i64)分析。 runtime 补全项:检测段加密环境串明文(需进对局触发 det② 后抓 byte_FF8E,strdec 算法已就绪);寄存器 VM 活体触发(极低频,需特定反作弊事件)。
评论
- 还没有评论,来说点什么吧。