热血江湖 任务列表基址探测记录(2026-09-25 18:48) 一、已确证的事实 1. 任务列表【不在】背包/仓库容器分发家族内。 - 反汇编 0x00D59614 / 0x00D5BC7B(背包/仓库/综合仓库/个人仓库四基址共用分发函数), 提取出的静态容器只有:0x3BEF5D0(普通背包)、0x3BEF5E8(活动背包)、 0x3C0CC4C/50/54/58(仓库四基址)、0x0188C61C(type18 神秘容器)。无任务列表静态。 2. 任务名是内联 Big5 字符串。全内存扫描: - "來安魂吧" = A8 D3 A6 77 BB EE A7 61,在 +R 数据段命中 5 处(0x30499274 / 339D2D24 / 33A25CA4 / 6C96F938 / 72875568)。 - "蛛絲馬跡" 命中 8 处。 - UTF-16 扫描:0 命中(确认是 Big5 非宽字符)。 - 这些副本之间【没有任何指针互相引用】,也不是连续数组 → 名字来自"字符串表", 列表本身按 ID 索引。 3. 任务条目对象结构(以 0x30499234 的"來安魂吧"为例,堆分配): +0x00: 类 vtable 指针 (0x45F642A8) +0x40: 任务名内联 Big5 字符串("來安魂吧") 该对象是【临时/选中态对象】,全内存扫不到指向它的指针 → 非持久列表稳定条目。 4. 0x0188C61C(type 18,同分发家族):容器 vtable 0x010E196C,数据数组 0x54E17C68, 首条目前 4 dword = 362 / 274 / 350 / 300,末尾 float 300.0 / 350.0,【无内联名】 → 是 ID/数值表,不是任务名列表。 5. 任务类 vtable 0x45F642A8 的静态引用点在数据段 0x3C37814(A8 42 F6 45 字节命中)。 但 0x3C37400~0x3C37C00 区域扫不到含>5指针槽的 vector 容器。 二、与背包/仓库结构的对比(为什么难) - 背包/仓库/装备:容器对象 → 槽指针数组 → 物品对象(名字内联+0x64)。静态基址可直接读槽数组。 - 任务列表:条目是各自独立堆对象(带 vtable),名字在字符串表,列表按 ID 索引, 且当前见到的条目对象是临时对象 → 没有现成的"静态基址→槽数组"形态。 三、待定方向(需用户确认) A. 要读【任务名】→ 需要解析"ID→名字字符串表"映射(深,需继续逆向字符串表)。 B. 要读【任务列表容器(IDs/状态)】→ 最可能是 0x0188C61C(type18) 或其衍生;需验证 362 等 是否为任务 ID。 C. 要 CE 指针链直达【当前任务条目对象】→ 可用已发现的条目布局(+0x40 名字)做活体读取, 但需要"什么访问了这个地址"反推稳定基址。 四、A 路线(名字字符串表)结论 —— 2026-09-25 - 任务名不是静态数组,而是【惰性实例化的任务定义对象】,每个对象: +0x00 = 类 vtable 指针 (0x45F642A8,内存中字节 A8 42 F6 45) +0x40 = 任务名内联 Big5 字符串(如 來安魂吧 / 罌…) - 全内存扫 vtable 0x45F642A8 只命中 2~3 个对象(0x30499234=來安魂吧、0x1E444BFC=罌…、 0x6C5957C0),即"当前已加载的任务定义",全量名字表不在内存(从数据文件惰性加载)。 - 候选任务 ID 容器 0x0188C61C(type18):count=14/cap=22,数组 0x54E17C68 仅 4 个有效值 362/274/350/300 + 0xFFFF,其余空 → 是"激活项小表"而非 14 任务名字列表;且 362 等 并未出现在 來安魂吧 定义对象里,二者非同一子系统。 - 结论:不存在背包式单一"任务列表静态基址"。可用的两种读名字方式: (1) 活体读当前任务:扫 vtable 0x45F642A8 → 每个对象 +0x40 即名字(脚本 quest_strA3.py)。 (2) 读任务 ID:0x0188C61C(容器+0x38=数组,count+0x08),需配合定义表按 ID 查名。 - 若要坚持"全量名字字符串表":需定位任务定义数据表(从 .dat/.pak 载入的大缓冲),属深逆向, 建议改用 CE 对活体任务名"找出什么访问了这个地址"反推稳定基址。 五、参考脚本(CE 桥在线时运行) D:\ce_mcp\quest_hunt2.py 字符串锚点扫描 D:\ce_mcp\quest_hunt7.py 反查名字指针 D:\ce_mcp\quest_hunt8.py 名字命中点前后窗口解码 D:\ce_mcp\quest_hunt12.py stride 验证(误判为帮助菜单 0x339D2D24) D:\ce_mcp\quest_hunt15.py 分发函数静态基址提取 D:\ce_mcp\quest_hunt17.py vtable 方法表读取 D:\ce_mcp\quest_strA3.py ★扫全部任务定义对象导出当前任务名(+0x40) 六、B 路线(静态代码分析法)结论 —— 2026-09-25(本轮) 1. 【关键发现】CE 桥 find_what_accesses(硬件断点)对【所有】目标均 0 命中: - 监控 來安魂吧 名字字段 0x30499274、vtable 0x30499234 - 监控 激活ID数组 0x54E17C68、静态基址 0x0188C61C、容器 0x214810A0 → 全部 0 命中。结论:XIGNCODE 反作弊会清除 DR0~DR3 硬件调试寄存器, "找出什么访问了这个地址"类活体反推被反作弊封死,此路不通。 2. 改用【静态代码分析法】:0x0188C61C 是模块内固定地址(无ASLR), 在代码段 +X 搜其立即数 1C C6 88 01 → 命中 80 处,确认 60 处为 `mov reg,[0188C61C]`(即任务/任务系统【总管理器】的静态根指针)。 3. 管理器结构(容器对象 0x214810A0, vtable 0x010E196C): - +0x38 → 激活任务【索引/ID 数组】指针 (0x54E17C68) 内容 dword、0 结尾:当前 = [362, 274, 350, 300] - +0x3D0 / +0x408 / +0x430 / +0x508 …… 各指向不同子系统(任务列表UI、追踪、定义等) 4. 15000 项全局表 0x03C35758(按 eax*4 索引,0..14999),在 0x57B92B 区域被 0..14999 循环遍历 —— 是【全量任务表】。激活数组里的 362/274/350/300 正是该表 的【内部索引】:0x03C35758[idx] → 任务状态/条目对象(vtable 0x10F1EE4 等)。 5. 名字解析:任务名是【运行时动态构建】的(來安魂吧 Big5 串只命中堆副本、无模块内 静态字符串表;状态对象/定义对象前 0x400 字节及一层指针里也扫不到可读 Big5 名)。 → 静态指针链只能到"任务状态对象",可读名字仍需活体(被反作弊封)。 七、最终交付:任务列表基址(静态,可长期用) - 静态根:0x0188C61C (YGOnline.exe + 0x148C61C;无 ASLR,每次启动不变) - 激活任务列表:[[0x0188C61C] + 0x38] → 0 结尾的 dword 数组 = 激活任务索引, 当前 [362, 274, 350, 300] - 索引查表:0x03C35758 + idx*4 → 任务状态对象(再按其内部字段取运行数据) - 读名字(仅活体,每会话变堆址):扫 vtable 0x45F642A8 对象 +0x40(quest_strA3.py) - 说明:背包式"单一静态基址→槽数组→名字"形态在任务列表不存在;任务名动态构建, 静态层止步于"激活任务索引列表 + 全量任务表基址"。 八、本轮新增脚本 D:\ce_mcp\quest_fw_probe.py 活体对象扫描(修正 aob 保护位 R / 解析嵌套 result) D:\ce_mcp\quest_fw_diag.py aob_scan 保护位诊断(确认用 'R' 非 '+R') D:\ce_mcp\quest_log_probe.py 管理器容器结构勘察(+0x38 数组定位) D:\ce_mcp\quest_static.py ★静态代码分析法: 搜 0x0188C61C 立即数定位管理器 + 反汇编 D:\ce_mcp\quest_chain_verify.py 激活数组→定义表 链验证 D:\ce_mcp\quest_link.py 状态对象→定义对象 链接扫描 D:\ce_mcp\quest_namehunt.py 暴力扫描状态对象内 Big5 名 D:\ce_mcp\quest_fw_run.py / quest_fw_run2.py find_what 尝试(均0命中, 证伪) 九、【重要踩坑】read_memory_batch 单次上限 100 条 —— 2026-09-25 - CE 桥 read_memory_batch 一次最多 100 个请求,超过【整体返回 error dict】而不是报错抛异常, 导致 dwords(n>100) 全部返回 None → Earlier 遍历把管理器对象的指针字段误判成"0 个"、 把全量表同型对象统计误判成"0 个命中"。 - 修正:所有批量读必须按 100 分批(chunk)。 - 另一坑:浮点常量会被 isptr() 误判为指针(如 1.0f = 0x3F800000),需排除 0x3E800000<=v<=0x40000000 区间;rd() 读失败时会返回 dict 而非 int,需 isinstance 兜底。 十、全量遍历结果(quest_traverse.py / quest_dump.py / quest_detail.py) 1) 基址链 0x0188C61C -> 任务管理器对象 0x214810A0 (vtable 0x10E196C) [管理器]+0x38 -> 激活任务数组 0x54E17C68 0x03C35758 全量任务表(前 256 项【全非空】256/256) 2) 管理器对象 0x214810A0 字段全图(0x00~0x400) +0x000 vtable 0x10E196C +0x008=14 +0x00C=22 +0x010=14 +0x014=0xFFFFFFFF +0x01C=1 +0x038 / +0x03C = 激活数组 begin/end 指针对(0x54E17C68 / 0x54E17C6C) +0x320 / +0x324 = 1.0f(浮点,非指针) +0x3AC ~ +0x3FC = 【20 个子系统对象指针数组】(stride 4),指向 vtable 0x10E8D38 / 0x10E4038 / 0x10EF0BC / 0x10F26CC / 0x10FB820 等 +0x3E0~+0x3EC、+0x3F0~+0x3FC 属同一指针数组区 3) 激活任务数组 0x54E17C68 前置头 6 dword:[0x54E17C48]=24 [0x54E17C4C]=8746 [0x54E17C50]=14(count) [0x54E17C54]=0xFFFFFFFF [0x54E17C58]=0xBE000000(float) [0x54E17C5C]=1 数组内容:362 / 274 / 350 / 300(第 9 槽 0x54E17C8C = 0xFFFF 空哨兵) 4) 任务状态对象结构(全部自证:+0x00C == 自身任务 ID == 表索引) +0x000 vtable +0x004 指针->任务组/运行时对象 +0x008 任务系列号 +0x00C 任务ID(=索引) +0x010 目标数量参数 +0x014 0xFFFFFFFF(未完成标记) +0x018 0 或 float +0x01C 1(状态位) +0x028/0x02C 进度值 +0x030/0x034 子项 +0x038/+0x03C 指针对(vector begin/end,如 0x44B3C348/0x44B3C34C) +0x040 1 +0x04C 前置任务ID(362->361, 274->273, 350->348) 实例: ID362 0x44A1B400 vt0x10F1EE4 +0x008=34 +0x010=19 +0x028=85 +0x02C=178 ID274 0x44A6E560 vt0x10FAE94 +0x008=31 +0x010=14 +0x004=0x400ADD48 ID350 0x44A37990 vt0x10F1EE4 +0x008=34 +0x010=19 +0x028=156 +0x02C=178 ID300 0x44A43710 vt0x10FB388 +0x008=32 +0x010=14 5) 全量表前 256 项 vtable 分布 0x10F1EE4 x108(主体) / 0x10FB388 x64 / 0x10F26CC x28 / 0x10F1F5C x8 / 0x10F2654 x7 / 0x10F1FD4 x5 / 其余几十种少量 同型(vt 0x10F1EE4)对象抽样:[25][26][27][28][29][30][31]… 均 +0x008=34 +0x010=19, ID 严格等于表索引,+0x004 指向同组对象(0x34F75C68 / 0x34F763F8 / 0x35023958 …) 6) 名字仍未解:任务组对象 0x34F75C68 / 0x34F763F8 / 0x35023958 / 共享对象 0x447EFF08 前 0x120 字节均【扫不到可读 Big5 名】→ 再次证实任务名运行时动态构建, 静态指针链止步于"任务 ID + 状态对象",可读名需活体扫 vtable 0x45F642A8 定义对象。 ========================================================================= 十一、任务列表【实际清单】遍历(活体,2026-09-25 19:31 实读) ========================================================================= 新脚本:quest_tasks.py / quest_tasks2.py / quest_tasks3.py / quest_tasks4.py / quest_overview.py(输出 quest_tasks*_out.txt / quest_overview_out.txt) 1) 激活任务数组 0x54E17C68 完整布局(前 64 槽实读) [0]=362 [1]=274 [2]=350 [3]=300 [4]~[8]=0 [9]=0xFFFF(空哨兵) [10..63]=0 → 当前任务共 4 条,数组槽 0..3,容量到槽 9 为止。 数组头元数据:0x54E17C48=24 0x54E17C4C=8746 0x54E17C50=14 0x54E17C54=0xFFFFFFFF 0x54E17C58=0xBE000000 0x54E17C5C=1 2) 当前任务清单(四条,全部未完成 完成位=0xFFFFFFFF) ┌────┬──────┬──────┬──────┬──────────┬──────────┬────────┬────────┐ │# │ ID │ 系列 │ 目标 │ 进度 │ 完成位 │ 前置ID │ vtable │ ├────┼──────┼──────┼──────┼──────────┼──────────┼────────┼────────┤ │ 0 │ 362 │ 34 │ 19 │ 85 / 178 │ 0xFFFFFFFF │ 361 │0x10F1EE4│ │ 1 │ 274 │ 31 │ 14 │ 0 / 0 │ 0xFFFFFFFF │ 273 │0x10FAE94│ │ 2 │ 350 │ 34 │ 19 │ 156/ 178 │ 0xFFFFFFFF │ 348 │0x10F1EE4│ │ 3 │ 300 │ 32 │ 14 │ 0 / 0 │ 0xFFFFFFFF │ 273 │0x10FB388│ └────┴──────┴──────┴──────┴──────────┴──────────┴────────┴────────┘ 任务对象地址:362->0x44A1B400 274->0x44A6E560 350->0x44A37990 300->0x44A43710 3) 任务链的 vector(+0x038/+0x03C,每元素 32 字节) ID362 vector@0x44B3C348 = [362, 95, 220, 300, 0, ...] → 1 个元素 ID350 vector@0x44B2EB28 = [362, 274, 220, 300, 0, ...] → 1 个元素 ID274 / ID300 共用 vector@0x3C0A8520 = [1, 61, 55, 158, 0, ...] 4) 管理器 20 个子系统对象(+0x3AC ~ +0x3FC,vtable 各不相同) 其中 3 个是激活数组的镜像/子集: 0x447EFF08 (vt 0x10E8D38) +0x38 -> [362] 0x58148A70 (vt 0x10F2654) +0x38 -> [362] 0x58144858 (vt 0x10F2654) +0x38 -> [362] ← 与激活数组同一块内存 0x54E17C68 另有两个单元素列表:0x21B3E128 -> [499];0x30498D68 -> [51];0x4653D5E0 -> [612] (均只有 1 个元素,属不同用途的单独任务,不是批量列表) 5) 全量表 0x03C35758 前 2048 项总览(quest_overview.py 实读) 非空 2048 / 2048(全部已实例化) vtable 分布:0x10F1EE4 x847 / 0x10FB388 x312 / 0x10F26CC x242 / 0x10F2654 x197 / 0x10BF4E4 x156 / 0x10F1F5C x77 / 其余零散 +0x014 == 0 的:0 个(全部非完成态) → 结论修正:全量表是【任务模板/定义表】(全局唯一任务定义), 玩家的进度对象是另建的动态实例,模板里没有"玩家进度"概念。 激活 ID 与表索引一一对应(ID362->表第362项 0x3C35D00)。 6) 名字:本轮穷尽尝试,全部失败(再次定案"运行时构建") ① 定义对象(vtable 0x45F642A8)全模块仅 5 个: 0x3C37814 / 0x1E444BFC / 0x30499234 / 0x465C2310 / 0x6C5957C0 仅 0x30499234 能解出名 "來安魂吧"(+0x40),0x1E444BFC 解出 "步蠜/"(偏移非+0x40) ② 定义对象里的 0x45F6xxx 指针串(+0x004~+0x07C)→ 解出目标,无文本 ③ 激活任务模板对象 0x44A1B400 等,0x400 字节全扫 → 无任何可读名串 (+0x38 的 "H籀DL籀D" 是 vector 指针对被误按串解析,非文本) ④ KEYWORD 字符串表扫描(全模块 aob_scan): GBK "任务" 命中 30(其余 消灭/击杀/护送/寻找/报告/收集/委托 全 0) Big5 "委托/收集/打造/采集/清除" 模式 0 命中 Big5-HKSCS "任务" = A5 F4 89 55 → 0 命中 ⑤ 结论:任务名只存在于游戏资源文件(.dat/.pak),由任务 ID 索引后动态构建, 内存中不存在可读的任务名字符串池。要在脚本里出名字,只能: (a) 打开任务面板让 UI 构建字符串后活体抓;或 (b) 直接解包资源文件按 ID 取。 7) 本轮新增踩坑(重要) ★ isptr() 会把 vtable 误判成指针:vtable 值为 0x10EF0BC / 0x10F26CC 等, 恰好落在 0x10000~0x7FFF0000 的指针判据内。做(vector begin/end)配对扫描时 必须显式排除已知 vtable 集合,否则会凭空造出"113/316/488/2177 元素的 vector"。 ★ read_memory_batch 单次上限 100 条(见第10节),所有批量读必须分块。 本轮因此误报过一批假 vector,已修正。 ========================================================================= 十二、任务面板 UI 对证 + 名字机制 + 地图/坐标线索(19:37 用户贴 UI 截图) ========================================================================= UI 截图显示 4 条任务:[4]來安魂吧 [7]狐狸圍巾 [16]特別的狐狸圍巾 [18]關於屬性 → 与激活数组 [362,274,350,300] 顺序一一对应,人工锚定映射: 362=來安魂吧 274=狐狸圍巾 350=特別的狐狸圍巾 300=關於屬性 (方括号数字 4/7/16/18 疑为任务等级/序号,来源字段未定位) 1) 名字在内存中的存在形态(aob 实测) 「來安魂吧」Big5(A8 D3 A6 77 BB EE A7 61) 命中 9 处: 0x22BDE5F8 / 0x339D2D24 / 0x33A25CA4 / 0x7E0F1BB0 / 0x7E2FF4E8 / 0x7E3205A8 / 0x7E3A8D50 / 0x7E3A99C8 (+1) 「狐狸圍巾」「圍巾」40 处、「關於屬性」35 处 —— 名字确实在内存,但都是 渲染链副本:UTF-16 命中 2 处(0x7E3A8960/0x7E3A98E8) 与 Big5 同区,是 UI 层。 2) 0x22BDE208~ 区【UI 字符串池】stride=0x38 固定条目数组 条目混排任务名与 .ANI 资源名(MSG0002.ANI/MFB0122.ANI/MAH0001.ANI…): 0x22BDE400=關於屬性(idx9) 0x22BDE518=特別的狐狸圍巾(idx14) 0x22BDE5F8=來安魂吧(idx18) 0x22BDE668=狐狸圍巾(idx20) 条目内 +0x08 起为杂凑/样式数据,+0x30 处 0x80xxxxxx 句柄。无指针引用 (按索引访问)。UI 顺序索引序列 [18,20,14,9] 搜索 0 命中 → UI 另有结构。 3) 定义对象 0x30499234 +0x40 是【最近渲染名临时缓冲】(会变!) 本轮实读时 +0x40 = 「關於屬性」(上一轮是「來安魂吧」),其后残留 「狐狸圍巾」尾字节 —— 该缓冲被最近渲染的任务名复用。之前"定義对象 +0x40 读名"仅对"最近渲染名"成立,不是稳定存储。 4) 任务对象真实大小 ≈ 0x588 ID362 对象 0x44A1B400 的 +0x588 处出现下一个任务对象的 vtable(0x10F1EE4) + 系列 0x22 —— 激活任务对象连续分配,步长 0x588。ID274 对象 +0x588=0。 5) 任务链节点结构(重要新发现) 状态对象 +0x34C(362/350) / +0x330(274) 指向 vt 0x010F26CC 的链节点: +0x000 vtable +0x004 父对象指针 +0x008=24 +0x00C=节点ID(361/283) +0x010=14 +0x014=0xFFFFFFFF +0x024 起四元组 [X, Y, Z, W](与 +0x038 vector elem[0] 完全一致) 四元组实测: 362: [362, 95, 220, 300] 350: [362, 274, 220, 300] 362 +0x5C0 子对象另有 [190, 75, 200, 300] 274/300: [1, 61, 55, 158] 【推断】W(第4位) 高度疑似 地图ID:34系列两个任务共享 300,31/32系列=158; Y/Z 疑似 NPC ID 或目标坐标(同任务 362 出现 (95,220) 与 (75,200) 两组, 符合"接取NPC/交付NPC各一组"的解释)。待活体验证。 6) 地图/坐标交叉验证失败(基址失效) 基址常量_版本3 中 人物/坐标基址 0x03BF28CC 当前读 0,地图基址 0x011E0084 读 0x610CCF 怪值 —— 两者均标注【未复核】,已失效。修复后可用: 玩家切换地图 → 看四元组 W 是否等于新地图 ID;走到任务 NPC → 看 Y/Z 变化。 7) 本轮新增脚本:quest_tasks4.py / quest_fields.py / quest_locate.py 输出:quest_tasks4_out.txt / quest_fields_out.txt / quest_locate_out.txt quest_fields 是字段对比器(4 任务并列,恒定=结构、差异=特征),可复用。 ================================================== 第十三节 任务奖励分析(狐狸圍巾 274 奖励页对证)0925晚 ================================================== 锚点(用户截图):狐狸圍巾(274) 奖励 = 盛獸項鍊(等級10/項鏈) + 經驗值(500) + 歷練(200) 1) 数值搜索穷尽(全部阴性): dword/word/float 形式的 500(0x1F4) 与 200(0xC8): - 相邻对窗口 0/8/16/32 字节(RW+R)全扫 → 仅命中 UI 热键表(假阳性)、UIA字符串 - 274 与 500 同窗(≤32B) → 0 - 任务面板 UI 堆 0x233D0000~0x233F0000 全区字节级扫 → 0 结论:奖励数值不以数字字段存在于客户端内存, 服务端下发任务详情包时直接格式化成文本 → UI缓存。 2) 奖励文本缓存结构(0x1F10xxxx / 0x233Dxxxx 等多处副本): 记录 = [32字节哈希] [内联Big5串] [4B校验] [4B标志] ... 01 80 结尾 串内容:經驗值(500) / 歷練(200) / 奖励物品名 / 图标动画名(MEF00171.ANI 等) 同槽位会被重绘复用(同一地址先后出现 狐狸圍巾/盛獸項鍊 —— 缓存churn)。 3) 实测缓存中的两组奖励(提取器 quest_reward.py): A组: 經驗值(500) x147 + 歷練(200) x48 → 狐狸圍巾(274),物品=盛獸項鍊【截图锚定】 B组: 經驗值(2000) x49 + 歷練(500) x69 → 上下文物品名=屬性石 x5 → 高度疑似 關於屬性(300)(给属性石,主题吻合,待UI点击确认) 缓存跨任务累积(看过的任务奖励都留副本)。 4) 「盛獸項鍊」串搜:Big5=C646 C37E B6B5 C1E5(注意: 盛=C646 而非直觉编码) 60+ 处命中(0x0FAA/0x181A/0x1E4A 区,stride 0x1108 的文本+哈希条目表)。 之前「盛獸」0命中是编码算错(big5编出 B2B1,实际 C646),大五码生僻字需人工校验。 5) 交付:quest_reward.py —— 奖励文本提取器(面板开着即可跑): 扫 經驗值(/歷練( 模式 → 提数值 → 汇总 + 上下文物品名。 配合激活任务列表(第7节)可做"当前任务+奖励"完整读取。 6) 后续:让用户逐个点击任务面板4条任务,每点一条跑一次提取器, 按"新出现的数值对"绑定 任务ID→奖励;或抓任务详情包(协议层)拿结构化奖励。 ================================================================================ 14. 「獸項鍊」专项搜索 —— 奖励物品名的落点(20:25) ================================================================================ 用户点名搜「獸項鍊」(= C3 7E B6 B5 C1 E5)。全 RW 空间扫描共 **118 处命中**, 聚成两类,性质完全不同: ------------------------------------------------------------------------------ 14.1 A 类:0x2074xxxx —— 条目化定义,静态稳定 【可当表用】 ------------------------------------------------------------------------------ 命中点:0x207460B6(条目A)、0x2074C0E6(条目B) ★ 稳定性实测:间隔 3 秒两次读 0x400 字节,1024/1024 完全一致 → 静态区。 以「名字首字节 − 0x40」为条目起点(条目A = 0x20746076 / 条目B = 0x2074C0A6): +0x02 u8 = 45 两处相同,疑似装备类别/槽位(项鍊?) +0x06 u16 = 404 (A) / 385 (B) ← 两处唯一实质差异,疑似物品ID +0x0C u8 = 32 +0x0E u8 = 32 +0x14 u16 = 40600 (A) / 0x465B (B) +0x1E u16 = 0xFFFF 常见哨兵 +0x26 = 0x186A1 +0x30 u8 = 1 +0x3B 名字 Big5「盛獸項鍊」(首字节 C6) +0x8E u16 = 10 ★★ 等级,与截图「等級 10」完全吻合 A/B 两处其余字段几乎全同,仅 +0x06 与 +0x14 不同 → 疑为同一件物品的两份记录 (基础态 / 另一形态 或 两张不同索引表)。 价值:这是目前唯一一处**能稳定按地址读、且含物品ID+等级字段**的落点, 可作为「任务奖励 → 物品」的绑定锚点。 ------------------------------------------------------------------------------ 14.2 B 类:0x233Dxxxx —— UI 文本节点缓存,会 churn 【只能当快照】 ------------------------------------------------------------------------------ 111 处命中,stride 0x80 的共享节点池。节点内除物品名外还混着: 經驗值 x14 歷練 x4 隨著任務獲得的歷練值。 x3 隨著任務獲得的經驗值。 x1 隨著任務獲得 x2 「盛獸項鍊」(解码显示) x203 ← 同一串出现几百次 = 共享节点池的铁证 判定:这是渲染层复用槽位,随面板刷新而改写,**不能当物品表用**,只能当作 「当前已打开过的任务奖励」的一次性快照。 ------------------------------------------------------------------------------ 14.3 ★ 定论级坑:游戏用的不是标准 Big5 ------------------------------------------------------------------------------ 「盛獸項鍊」正确字节: C6 46 C3 7E B6 B5 C1 E5 用 Python `big5hkscs` 解这串 → 得到 **「靈獸項鍊」**,不是「盛獸項鍊」。 结论(必须遵守): 1. 找字符串一律 aob_scan 搜**原始字节**,绝不"先解码再搜"。 2. 验证某地址是否为某串,也用字节比对,不信解码结果。 3. 常见字(經驗值/歷練/任務)标准码表能解对,生僻字(盛/獸/項/鍊)会错, 所以同一份数据里"能解对"和"解错"混在一起,极易误判。 补充踩坑:自写 Big5 串扫描器时,判中文必须判**原始字节**(hi>=0x81 且 lo>=0x40)。若误判解码后的 Unicode 码位(写成 0xA100~0xF9DC),那是 Big5 的**字节**范围不是码位范围,会导致所有串全部漏掉(本次真实踩到)。 ------------------------------------------------------------------------------ 14.4 交付脚本 ------------------------------------------------------------------------------ quest_item_search.py 多编码变体对比搜索(big5hkscs/big5/UTF16/GBK/raw) quest_item_table.py 稳定性重读对比 + 命中地址聚类 quest_item_final.py 0x80 节点还原 + Big5 串提取 输出:quest_item_out.txt / quest_item_struct_out.txt / quest_item_final_out.txt ------------------------------------------------------------------------------ 14.5 下一步建议 ------------------------------------------------------------------------------ 1. 直接读 A 类条目 +0x06 的 404/385,结合背包/装备区的物品ID口径交叉验证, 确认它是不是热血江湖的装备ID编号。 2. 让用户在游戏里打开「盛獸項鍊」所在背包格 → 看该物品实例对象里是否也带 同一个 ID,把 物品定义 ↔ 物品实例 关联起来。 3. 逐条点击 4 条任务 + 跑 quest_reward.py,完成 任务ID → 奖励 绑定。