← 返回总索引基址更新子程序 · 验证与修复报告 2026-09-16-13-19-49\基址更新_验证与修复报告.md
分类:内存逆向与基址定位来源会话:2026-09-16原件:2026-09-16-13-19-49\基址更新_验证与修复报告.md

基址更新 子程序 — 二进制级验证与修复报告

目标二进制D:\rxjh2025\client\YGOnline.exe
PE 信息:32 位(ImageBase = 0x400000,Magic = PE32)
分析方法:用 Python 解析 PE,对 基址更新 子程序里的 34 条 Q_gw.FindData 字节特征,逐条在文件里做精确匹配;对未命中的再做通配(??)容错复扫,区分「帧偏移漂移(可修)」与「架构/版本不符(修不了)」。


一、结论速览(34 条特征)

状态 数量 含义
✅ 精确命中(直接可用) 20 该二进制的代码段里就有这段特征,基址更新 运行时能找到
🔧 帧偏移漂移(改几个字节即可) 3 特征存在但 ebp 帧偏移字节变了,给出修正字节
❌ 本构建缺失(x86 但整段不存在) 2 昇天列表基址辅组列表基址 在该二进制里完全搜不到
🚫 64 位特征(架构不符) 9 48 8B/44 0F B6 等 REX 前缀,是 64 位客户端的特征,32 位 exe 永远 0 命中

核心结论:你贴的 基址更新 是「按字节特征动态找基址」的权威做法,思路完全正确。但它是一份混合了多个游戏版本的特征库——当前 rxjh2025 这个 32 位客户端只认其中 20 条;另外 14 条要么字节漂移、要么来自别的版本(含 9 条 64 位客户端特征)。


二、✅ 精确命中,可直接用(20 条,模块基址=0x400000)

Q_gw.FindData 返回运行地址,临时地址 = 读数 + 模块地址 - 模块地址 得到模块相对偏移(即 .常量 值)。下表 target=mod_rel+调整 就是该 .常量 应得的模块相对偏移:

名称 类型 target(mod_rel,即常量值)
血量基址 data 0x5F52B9
周围数量基址 data 0x9E09A2
周围列表基址 data 0x9E09AC
背包列表基址 data 0x6DEACB
状态列表基址 data 0x2B97BD
技能栏基址 data 0x7473A8
放置技能CALL基址 call 0x953490
选中对象基址 data 0x934F23
使用快捷CALL基址 call 0x749A1E
NPC对话基址 data 0x268951
NPC_CALL基址 call 0x879661
NPC选项基址 data 0x87914F
NPC选项CALL基址 call 0x879154
小助手CALL基址 call 0x63F6E7
NPC功能CALL基址 call 0x881C5F
副本道具基址 data 0x9539F5
副本道具CALL call 0x9539FA
BUFF遍历基址 data 0x8E3CD0
背包使用CALL call 0x9538BE
道具遍历基址 data 0x368D49

注意:周围列表基址(0x9E09AC)就是实体数组指针变量的位置,运行时 读整数(模块地址+0x9E09AC) 才是实体数组本身——与你之前 怪物基址值/#怪物基址 的用法一致(只是表述成模块相对偏移,抗 ASLR,比写死绝对值稳)。


三、🔧 帧偏移漂移,3 条可一键修复

特征本身存在,只是 ebp 帧偏移字节变了(原特征 0 命中,通配后命中)。已替你抠出该二进制里正确的字节,直接替换 FindData 的第三个参数即可:

1. 人物基址(最关键,原特征 0 命中)

2. 全局大列表基址

3. 攻击列表基址(⚠ 有 11 个候选,需游戏内确认)

通配后有 11 处命中,原特征帧尾 F6 FF FF 在本构建里没出现(帧整体偏移了),无法单凭二进制判断哪一个是「活的」那一条。候选(取最低地址一条做首选,游戏里若攻击列表为空再换下一条):

首选(最低VA): 89 85 3C BF FF FF 89 95 40 BF FF FF 8B 95 3C BF FF FF 0B 95 40 BF FF FF
其它候选:     89 85 28 F9 FF FF ... / 89 85 FC F5 FF FF ... / 89 85 5C FF FF FF ...
              89 85 50 AE FF FF ... / 89 85 88 F9 FF FF ... / 89 85 90 FD FF FF ...
              89 85 14 FE FF FF ... / 89 85 68 FF FF FF ... / 89 85 60 FF FF FF ...
              89 85 78 FF FF FF ...

判断方法:替换后运行 基址更新,进游戏打怪看「攻击列表基址」是否填充且数量正确;不对就逐条试上面候选(adj 不变,仍为 -0x34 / 派生 0x32)。


四、❌ / 🚫 本构建无法自动修复的 14 条

4.1 整段不存在(x86 但换了版本/函数)

4.2 64 位客户端特征(架构不符,32 位 exe 永远 0 命中)

以下 9 条含 REX 前缀(48/44/45/49),是64 位游戏版本的特征库,对当前 32 位 YGOnline.exe 无效:
- 对话call基址对话选项call基址小范围瞬移call基址函数遍历基址
- 输入文本call基址出售物品call基址快速出售灰色物品call基址自动堆叠call基址购买物品call基址

含义:你的 基址更新 同时服务多个版本(含 64 位)。若 rxjh2025 用不到对话/瞬移/出售/堆叠/购买这些功能,0 命中无影响;若需要,必须从 32 位 rxjh2025 运行进程用 CE 重新抠这 9 条特征(方法同下「队员基址」)。


五、🎯 队员基址 —— 整段缺失,需补一段

基址更新完全没有 队员基址 这一项(与之前结论一致:它不在你任何字节特征库里,也不在 常量.e.txt 里)。补法与其它基址一样——加一段「按特征找指针变量」的代码。模板如下(特征字节需你用 CE 提供,静态二进制无法可靠抠出,原因见下):

' ===== 队员基址(需 CE 提供特征字节)=====
临时文本 = Q_gw.FindData (窗口句柄, 查找范围, “<在此填 CE 抠出的特征>”)
.如果 (临时文本 ≠ “”)
    临时地址 = 进制_十六到十 (临时文本) + 进制_十六到十 (“<调整量>”)
    临时地址 = Q_gw.ReadIntAddr (窗口句柄, 临时地址, 0)   ' 读出的应是 8 槽指针数组
    调试输出 (“队员基址”, 十到十六 (临时地址))
    _启动窗口.编辑框_偏移文本1.加入文本 (“队员基址” + 十到十六 (临时地址) + #换行符)
    _启动窗口.编辑框_偏移文本.加入文本 (“.常量 队员基址, ” + 到文本 (临时地址 - 模块地址) + “, ,” + #换行符)
.否则
    _启动窗口.编辑框_偏移文本.加入文本 (“.常量 队员基址, ” + “未找到” + “, ,” + #换行符)
.如果结束

怎么拿到「队员基址」的特征字节(CE,5 分钟)

  1. 组队,队里留一个已知队友(名字如 一至尊霸王花一)。
  2. 在 CE 里搜该名字的 BIG5 字节(=A440,=A456,=BDA4,=BBAF,=AA4C,=AA44,=A440 → A4 40 A4 56 BD A4 BB AF AA 4C AA 44 A4 40),勾「也扫描未知初始值 / 先精确再未知」。
  3. 找到队友名字地址 → 「找出是什么访问了这个地址」→ 上一层是 队员结构+0x338 读名字,+0x334 读成员ID字,+0x38C 队长名,+0x3A0 队伍等级)。
  4. 在反汇编里往上找mov eax,[全局X]lea ecx,[eax+(slot-1)*4]」那一句——那个 [全局X] 就是 队员基址(8 槽指针数组起点)。
  5. 把那 1~2 句指令的机器码抄成 FindData 特征字节,按上面模板填进去即可。

    关键点:队员结构与你之前分析的「玩家对象(type=0x31,名字 +0x18)」不是同一个结构——队员是独立的 8 槽小结构(名字 +0x338),所以不能直接复用玩家对象偏移,必须单独抠。


六、推荐行动清单

  1. 立即修复:把「三、🔧」里 人物基址全局大列表基址 的字节改掉(唯一命中,稳)。
  2. 验证修复攻击列表基址 用首选候选,游戏内确认攻击列表是否填充。
  3. 补队员基址:按「五」用 CE 抠特征,加一段到 基址更新
  4. 按需补 64 位/缺失特征:若 rxjh2025 要用对话/瞬移/出售/堆叠/购买,昇天列表辅组列表,从运行进程用 CE 重抠(同上法)。
  5. 字段偏移:对象字段(玩家/怪物/物品)的相对偏移用我之前给的「验证子程序」在游戏内点按钮确认,与本报告基址是两件事、互不冲突。

附:扫描脚本 scan_bases.py(精确)、scan_missing.py(通配容错)、extract_fix.py(抠修正字节)均在本工作区,可复跑核对。