← 返回总索引内存逆向与基址定位 03_内存逆向与基址/19_基址全量复验报告.html
基址复验生成:2026-09-18分析对象:D:\rxjh2025\client\YGOnline.exe纯静态验证 · 70 项

热血江湖 基址全量复验报告

分析对象D:\rxjh2025\client\YGOnline.exe(32 位 PE,14,752,768 字节,ImageBase 0x400000,构建 2026-09-14)
验证方式:纯静态(pefile 解析节区 + capstone 逐条反汇编 + 全代码段 disp32 引用索引),不依赖运行环境
验证范围:历史上找过的全部基址 —— ①辅助常量「XXX基址值」系列 ②「基址更新」子程序 34 条 FindData 特征 ③31007 参考模块 ④助手 UI 链路地址,共 70 项
结论A 组 8/11 有效、B 组 20/20 全部有效(含 8 条 call 类全通)、C 组 31007 全部失效、D 组助手链路全部有效;另修正了 2 条旧特征、指认出 1 条攻击列表正确候选、定位 2 个 0 引用基址的活跃邻居。


一、结论速览

项目 有效 待复核 说明
A 活游戏「XXX基址值」 11 8 3 怪物/人物/坐标/背包/凝神珠/状态栏/地图/NPC 全部有效;仓库、商店 0 引用;封包Eax基址是代码地址
B 基址更新 34 条特征 34 20 1 20 条精确命中(含 8 条 call 类 全部 rel32 解析成功);14 条未命中(含 9 条 64 位特征)
C 31007 参考模块 26 0 全部 0 引用 → 该版本基址已完全失效(与旧结论一致)
D 助手 UI 链路 12 12 虚表、函数入口、全局变量全部实打实验证通过

一句话:你的辅助现在用的那 8 个「XXX基址值」全都还是活的;「基址更新」那套特征查找20 条能命中且指向正确的全局变量——这套运行时自适应机制是当前最可靠的找址方式。


二、验证方法(含一处关键修正)

对每个基址做三重判据:

判据 做什么 为什么可信
① 地址归属 该 VA 落在哪个节区(.text / .rdata / .data 判断「是全局变量 / 是代码 / 是越界死值」
② 指令级引用计数 .text 内统计有多少条指令以 disp32 绝对寻址访问它 引用 ≠ 0 即证明当前程序真的在用它;这是「死值」的决定性判据
③ 交叉解析 特征命中点 + adj → 读出 4 字节 → 得到真正的全局变量地址 → 再回代判据② 把「代码偏移」翻译成「真实数据地址」,与 A 组互证

★ 关键修正:disp32 有两种形态,上一版漏了 SIB 变址

形态1  [disp32]          例:8B 15 CC 28 BF 03   mov edx,[0x3BF28CC]
形态2  [索引*4 + disp32]  例:8B 14 8D 68 3E BE 03  mov edx,[ecx*4+0x3BE3E68]
                          ↑ ModRM=0x14(mod=00,rm=100) 带 SIB=0x8D(base=101→disp32)

只统计形态 1 会大面积误判——例如「怪物基址值 0x03BE3E68」在形态 1 下是 0 引用(像死值),补上 SIB 形态后是 1487 处引用(明确有效)。本报告全部数据均为补齐两种形态后的结果。

节区表(用于判据①)

节区 VA VirtualSize 文件原始大小 性质
.text 0x00401000 0xC6D5B1 0xC6D600 代码段
.rdata 0x0106F000 0x170356 0x170400 只读数据 / 虚表
.data 0x011E0000 0x4A377A8 0x1F800 全局变量区(原始大小极小 → 绝大多数全局变量在文件里无内容,运行时才赋值
.fptable 0x05C18000 0x80 0x200
.rsrc 0x05C19000 0x14320 0x14400 资源

⚠ 由此得出一条重要限制:静态验证只能证明「代码在用这个地址」,不能证明「运行时该地址里存的指针指向的对象是对的」。后者必须用 CE 挂活进程读一次值。本报告已把所有「静态可证」的部分做完。


三、A 组|活游戏基址总表(「XXX基址值」系列)

来源:辅助自己的常量文件;这是你当前正在用的基址。

常量名 地址 节区 指令引用 立即数出现 判定
怪物基址值 0x03BE3E68 .data 1487 1971 ✅ 有效
人物基址值 0x03BF28CC .data 2503 3000 ✅ 有效
坐标基址值 0x03BF28CC .data 2503 3000 ✅ 有效(与人物基址同址)
背包基址值 0x03B9DCE0 .data 3417 3495 ✅ 有效
凝神珠背包基址值 0x03B9DCEC .data 78 79 ✅ 有效
状态栏基址值 0x03BA387C .data 897 906 ✅ 有效
地图基址值 0x011E0084 .data 3 3 ✅ 有效
NPC基址值 0x0183C52C .data 10268 10793 ✅ 有效(全表引用最多,也是助手链路头)
仓库基址值 0x0182A2DC .data 0 0 ⚠ 0 引用,待复核(见第八节)
商店基址值 0x03BC33BC .data 0 0 ⚠ 0 引用,待复核(见第八节)
封包Eax基址 0x0076C2A1 .text 代码地址,lea eax,[ebp-0x401c](发包用的取址点,非函数入口)

「立即数出现次数」= 该 4 字节小端序列在整个文件里出现几次(宽松口径,会含巧合);「指令引用」才是硬判据。两者接近说明巧合很少。


四、B 组|「基址更新」34 条 FindData 特征

4.1 data 类 12 条 —— 命中点 + adj = 取址点 → 读出真正的全局变量

名称 命中点 VA +adj 取址点 读出的全局变量 引用数 判定
血量基址 0x009F529E 0x009F52B9 0x03970A70 8
周围数量基址 0x00DE098E 0x00DE09A2 0x03BF2900 8
周围列表基址 0x00DE098E 0x00DE09AC 0x05BFEE78 14
背包列表基址 0x00ADEAA7 0x00ADEACB 0x03B9DCE0 3417 ✅ ★与「背包基址值」完全同址
状态列表基址 0x006B9772 0x006B97BD 0x03BA4C3C 53
技能栏基址 0x00B4736D 0x00B473A8 0x03BA4A08 403
选中对象基址 0x00D34F6E 0x00D34F23 0x0183C51C 1786
NPC对话基址 0x00668955 0x00668951 0x0183C52C 10268 ✅ ★与「NPC基址值」完全同址
NPC选项基址 0x00C79138 0x00C7914F 0x017EF378 1005
副本道具基址 0x00D539C8 0x00D539F5 0x0184437C 114
BUFF遍历基址 0x00CE3CDB 0x00CE3CD0 0x03BA387C 897 ✅ ★与「状态栏基址值」完全同址
道具遍历基址 0x00768D22 0x00768D49 0x01801170 0 ⚠ 读出是合法 .data 地址但 0 引用,待复核

4.2 call 类 8 条 —— +adj 落在 E8 后的 rel32,读出来是「相对偏移」

这是本次最重要的机制澄清:call 类基址的 +adj 不是指向函数入口,而是指向 call 指令的 rel32 操作数位置。读出 4 字节得到 rel32,再 + 取址点 + 4 才是目标函数。

call 指令 = E8 [rel32]        取址点 = rel32 的第 1 字节
目标 = 取址点 + 4 + rel32
名称 命中点 +adj 取址点 读出的 rel32 算出目标函数 入口 判定
放置技能CALL基址 0x00D5343A 0x00D53490 0xFFFE19BC(-0x1E644) 0x00D34E50
使用快捷CALL基址 0x00B49A0E 0x00B49A1E 0x00003AFE 0x00B4D520
NPC_CALL基址 0x00C7963F 0x00C79661 0x0000520B 0x00C7E870
NPC选项CALL基址 0x00C79138 0x00C79154 0xFFAF2F28(-0x50D0D8) 0x0076C080
小助手CALL基址 0x00A3F676 0x00A3F6E7 0x00000015 0x00A3F700 ✅ ★与旧辅助直调目标完全一致
NPC功能CALL基址 0x00C81C1C 0x00C81C5F 0xFFFF76FD(-0x8903) 0x00C79360
副本道具CALL 0x00D539C8 0x00D539FA 0xFFB52162(-0x4ADE9E) 0x008A5B60
背包使用CALL 0x00D538C3 0x00D538BE 0x0000819E 0x00D5BA60

8/8 全部通过,且每一个目标函数都是 push ebp; mov ebp,esp 开头的标准函数入口。

顺带解答了旧疑问:「小助手CALL基址」读出的 0x15 曾被误判为「不是地址」——它是 rel32,0xA3F6EB + 0x15 = 0xA3F700,正是你旧代码里硬编码的那个函数。

4.3 未命中的 14 条

类别 条目 原因
64 位特征(架构不符) 对话选项call、小范围瞬移call、函数遍历、快速出售灰色物品call、购买物品call 含 REX 前缀(48/44/45/49),32 位 exe 永远 0 命中
32 位但整段不存在 对话call基址、输入文本call基址、出售物品call基址、自动堆叠call基址 该构建里代码逻辑已变;另有昇天列表、辅组列表两条历史缺失
帧偏移漂移(可修) 人物基址全局大列表基址 见下

两条可修的已给出修正字节,本次已复验唯一命中:

名称 原特征 修正特征 复验结果
人物基址 8B 8D 30 B6 FF FF … (0 命中) 8B 8D 20 B6 FF FF 8B 51 0C 89 90 24 1D 00 00 ✅ 唯一命中 0x007DB9C7 → 读出 0x03BF28CC(=人物基址值,2503 引用)
全局大列表基址 6A 00 6A 00 68 50 04 00 00 8B 85 3C B6 FF FF … (0 命中) … 8B 85 2C B6 FF FF 8B 88 24 1D 00 00 ✅ 唯一命中 0x007DB8A9 → 读出 0x03BE3E68(=怪物基址值)

两条修正特征命中点相距仅 0xED,在同一个函数内(0x7DB860 附近)——该函数就是「取人物基址 / 取全局大列表」的原始取址代码,其反汇编原文见第八节。


五、C 组|31007 参考模块(全部失效)

26 项全部 0 引用,包括 #怪物基址 0x03173B70#角色基址 0x03165088#背包基址 0x031455E4#队员基址 0x03148650#游戏基址 0x03165090 等,以及 #发包call地址#隐藏怪物/人物/建筑#穿墙地址1/2 等代码地址。

结论:31007 那套基址对本客户端完全不可用(与 2026-09-16 的结论一致,本次是全表复核确认)。队员基址 依然是空白项,必须用指针扫描现找。


六、D 组|助手 UI 链路(全部有效)

名称 地址 验证结果
助手窗口虚表 0x010A20F8 真虚表:前 12 项中 9 项指向 .text;槽0=0xA2FBF0、槽1=0xA3F3D0(与实机读到的值一致)
助手分派槽#1 0x00A3F3D0 ✅ ★函数入口 push ebp; mov ebp,esp; sub esp,0x20
InterInGameTotalShop 虚表 0x01079A6C 真虚表:前 12 项中 11 项指向 .text槽0 = 0x68B2B0
总控槽0 0x0068B2B0 ✅ ★函数入口
0xA3F700 选项实现 0x00A3F700 ✅ ★函数入口(旧辅助直调目标)
选项跳转表 / 字节索引表 0x00A41588 / 0x00A41698 ✅ 在 .text 内且被代码引用(跳转表 1 处直接引用)
选项公共尾部 0x00A41204 cmp [ebp+8],0x1c / cmp [ebp+8],0x27(区间批处理入口)
助手构造 0x00A2DCC0 ✅ ★函数入口
助手窗口创建点 / 写 [+0x414] 0x009E739E / 0x009E73CE call 0xa2dcc0mov [ecx+0x414], edx(助手窗口链头的来源)
NPC基址值(链头) 0x0183C52C ✅ 10268 处引用

一处细节修正0x68B2B0 是 InterInGameTotalShop 虚表的槽 0,此前记录成「槽 #1」。助手窗口那边 0xA3F3D0 才是槽 #1——两者不是同一个窗口体系,不要混用。


七、三条交叉互证(不同来源指向同一地址)

全局变量 来自「XXX基址值」 来自「基址更新」特征 引用数
0x03B9DCE0 背包基址值 背包列表基址0xADEACB 读出 3417
0x0183C52C NPC基址值(助手链头) NPC对话基址0x668951 读出 10268
0x03BA387C 状态栏基址值 BUFF遍历基址0xCE3CD0 读出 897

两套完全独立的定位方式(写死常量 vs 字节特征)指向同一个全局变量地址 —— 这三条是本次验证中可信度最高的基址

另外 人物基址值 0x03BF28CC 与修正后的「人物基址」特征互证(2503 引用),怪物基址值 0x03BE3E68 与修正后的「全局大列表基址」特征互证(1487 引用)。


八、待复核项与修正建议

8.1 攻击列表基址 —— 11 个候选已逐个评估

原特征帧尾 F6 FF FF 在本构建不存在,需从候选中挑。按「-0x34 取址点读出的值是否落在 .data 且被引用」,只有两个像真的:

候选 命中点 -0x34 取址点 读出值 引用数 评价
候选3 89 85 FC F5 FF FF … 0x006B91DD 0x006B91A9 0x03BA4C40 204 最可能:与「状态列表基址」读出的 0x03BA4C3C 相邻 4 字节,同属一个状态/列表区块
候选4 89 85 5C FF FF FF … 0x00A3C185 0x00A3C151 0x03BE3E68 1487 读出的是怪物基址(实体数组),语义不符「攻击列表」
其它 9 个 非地址 / .text / 越界 0

建议:用候选3 替换,进游戏打怪确认「攻击列表被填充且数量正确」即为定论。

8.2 两个 0 引用基址的活跃邻居(用于校正)

基址 当前值 邻近真有引用的地址(±0x2000 内)
仓库基址值 0x0182A2DC 0x0182B5E8(244)、0x0182AEB0(70)、0x0182AEC4(42)、0x0182AEA8(12)、0x0182AEA0(10)
商店基址值 0x03BC33BC 0x03BC21F8(76)、0x03BC30F0(16)、0x03BC311C(10)、0x03BC30F8(8)、0x03BC2F2C(7)
道具遍历基址(特征) 0x01801170 待复核

注意:0x0182B5E8 恰好出现在「NPC_CALL基址」的反汇编里(add eax, 0x182b5e8),是仓库/物品相关的高频全局变量,很可能就是仓库基址的正确值

8.3 取址函数原文(两条修正特征的来源)

007DB89F  cmp  dword ptr [edx*4 + 0x3be3e68], 0     ; ← 怪物基址值(SIB 变址访问)
007DB8BE  mov  edx, dword ptr [ecx*4 + 0x3be3e68]
007DB8D3  mov  ecx, dword ptr [ecx*4 + 0x3be3e68]
007DB8DA  mov  eax, dword ptr [edx + 4]              ; 虚表槽1
007DB8DD  call eax                                   ; 与助手点击同一套虚调用机制

007DB911  mov  edx, dword ptr [0x3bf28cc]            ; ← 人物基址值
007DB96C  mov  ecx, dword ptr [0x183c52c]            ; ← NPC基址值
007DB98F  mov  eax, dword ptr [0x183c52c]
007DB994  mov  ecx, dword ptr [eax + 0x4d0]          ; NPC 对象 +0x4D0
007DB9C2  mov  eax, dword ptr [0x3bf28cc]
007DB9D0  mov  dword ptr [eax + 0x1d24], edx         ; 人物基址+0x1D24(索引/槽位)

这段代码同时使用 [disp32][索引*4 + disp32] 两种形态 —— 也是本次发现扫描盲区的直接证据。

8.4 关于「活体验证」

静态已能证明「代码在用这些地址」,但地址里存的指针是否正确只能活体读。要做的话需要:
1. CE 挂 YGOnline.exe,Table → Show Cheat Table Lua Script → 载入 ce_mcp_bridge.lua → Execute(出现 MCP 标记)
2. 我逐条读 [基址] 的值并核对指向的对象(例如 [[NPC基址值]+0x414] 应等于助手窗口、[背包基址值] 应指向物品容器)


九、本次复验脚本清单

脚本 作用
verify_all2.py 70 项基址总表:节区归属 + 指令引用(含 SIB)+ 立即数出现 + 代码入口判定
verify_feat_map.py 34 条特征 → 命中 → 取址点 → 全局变量地址 → 引用数(data 类)/ rel32 算目标(call 类)
verify_calls.py call 类落点反汇编 + 目标函数入口判定 + 助手链路函数体检
verify_feats2.py 两条修正特征复验 + 攻击列表 11 候选评估
verify_addr47.py 0x7DB860 取址函数完整反汇编 + 两种 disp32 形态举证

基线数据(可直接复核):exe 大小 14752768.text 覆盖 0x401000–0x106E5B1.data 内被引用地址总数 3264


报告生成:2026-09-18 · 分析对象 D:\rxjh2025\client\YGOnline.exe · 全部结论可凭上述脚本在本地复跑复核