# 助手控件实机对照表(内存遍历实测) > 生成:2026-09-18 | 分析对象:`D:\rxjh2025\client\YGOnline.exe` > 数据来源:易语言子程序 `遍历助手控件` 实机内存遍历(2026-09-18 14:07 采集,共 74 个控件) ## 一、结论先说 | 项目 | 结果 | |---|---| | 两步链是否成立 | **成立**。实测 `助手窗口=1172743136`、`开始按钮=1258421128`、`父窗口=1172743136` | | 父窗口是谁 | **就是助手窗口本身**(两值完全相同)→ 按钮直接挂在助手窗口下,虚表槽 #1 即分派函数 | | 静态偏移命中率 | 静态登记表里 8 个带存放偏移的控件,**偏移与实机 100% 一致** | | 控件总数 | 74 个(ID 从 0x01 到 0x4DE) | | 可直发命令的 ID | 34 个在 `0x68B2B0` 分派表内 | ### 静态 vs 实机 逐条对照 | 控件 | 静态预测偏移 | 实机偏移 | 实机 ID | 结果 | |---|---|---|---|---| | 开始挂机 auto_play.bmp | 0x3938 | 0x3938 | 0x31 | 命中 | | 停止挂机 auto_stop.bmp | 0x393c | 0x393c | 0x32 | 命中 | | 设置 auto_setup.bmp | 0x37f8 | 0x37f8 | 0x33 | 命中 | | 关闭 auto_close.bmp | 0x37fc | 0x37fc | 0x34 | 命中 | | 保存 auto_btn_save_over.bmp | 0x3940 | 0x3940 | 0x35 | 命中 | | 取消 cancel_over.bmp | 0x3800 | 0x3800 | 0x36 | 命中 | | 弹窗确定 ok_over.bmp | 0x39e8 | 0x39e8 | 0xA3 | 命中 | | 弹窗取消 cancel_over.bmp | 0x39ec | 0x39ec | 0xA4 | 命中 | 8 / 8 全部命中,说明静态扫描提取的 `store_off` 方法可靠,可继续用同样方法挖其它窗口。 ## 二、实机控件全表(74 个) ### 主区域 · 容器/页签(4 个,局部 ID 均为 0x01) | 偏移 | ID | 说明 | |---|---|---| | 0x36C8 / 0x36CC / 0x36D0 / 0x36D4 | 0x01 | 4 个同 ID 的容器槽,疑为背景页 / 页签容器 | ### 功能按钮簇(20 个) | 偏移 | ID | 偏移 | ID | 偏移 | ID | |---|---|---|---|---|---| | 0x36E8 | 0x37 | 0x3704 | 0x4A | 0x3794 | 0x53 | | 0x36F0 | 0x3B | 0x3708 | 0x4B | 0x3798 | 0x54 | | 0x36F4 | 0x46 | 0x370C | 0x4C | 0x379C | 0x55 | | 0x36F8 | 0x47 | 0x3710 | 0x4D | 0x37A0 | 0x56 | | 0x36FC | 0x48 | 0x3714 | 0x4E | 0x37E0 | 0x39 | | 0x3700 | 0x49 | 0x3718 | 0x4F | | | | | | 0x371C | 0x50 | | | | | | 0x3720 | 0x51 | | | | | | 0x3724 | 0x52 | | | ### 核心按钮区(已确认名称) | 偏移 | ID | 名称 | 资源 | |---|---|---|---| | 0x37F8 | 0x33 | 设置 | auto_setup.bmp | | 0x37FC | 0x34 | 关闭 | auto_close.bmp | | 0x3800 | 0x36 | 取消 | cancel_over.bmp | | 0x3938 | 0x31 | **开始挂机** | auto_play.bmp | | 0x393C | 0x32 | **停止挂机** | auto_stop.bmp | | 0x3940 | 0x35 | 保存 | auto_btn_save_over.bmp | | 0x39E8 | 0xA3 | 弹窗确定 | ok_over.bmp | | 0x39EC | 0xA4 | 弹窗取消 | cancel_over.bmp | ### 其余散件 | 偏移 | ID | 偏移 | ID | 偏移 | ID | |---|---|---|---|---|---| | 0x3804 | 0x2B | 0x38F0 | 0x1C | 0x3954 | 0x9A | | 0x3808 | 0x2C | 0x38F4 | 0x1D | 0x399C | 0x9B | | 0x380C | 0x2D | 0x38F8 | 0x1E | 0x39A0 | 0x9C | | 0x3814 | 0x2F | 0x38FC | 0x1F | 0x39A8 | 0x9D | | 0x381C | 0x98 | 0x3900 | 0x20 | 0x39AC | 0x9E | | 0x38C4 | 0x0B | 0x3904 | 0x21 | 0x39B0 | 0x9F | | 0x38C8 | 0x0C | 0x3908 | 0x22 | 0x39B4 | 0xA0 | | 0x38CC | 0x0D | 0x390C | 0x23 | 0x39BC | 0xA1 | | 0x38D0 | 0x0E | 0x3910 | 0x24 | 0x39C0 | 0xA2 | | 0x38E0 | 0x12 | 0x3914 | 0x25 | 0x3944 | 0x425(1061) | | 0x38E4 | 0x13 | 0x3918 | 0x26 | 0x39F8 | 0x01 | | 0x38E8 | 0x14 | 0x391C | 0x27 | 0x3A10 | 0x4DE(1246) | | 0x38EC | 0x15 | 0x3920 | 0x28 | 0x3A68 | 0x1C9(457) | | | | 0x3928 | 0x29 | | | | | | 0x3930 | 0x2A | | | ### 连续 ID 段(0x0B~0x2A)解读 0x38C4~0x3930 这一段 24 个控件 ID 连续递增(0x0B~0x0E、0x12~0x15、0x1C~0x2A),是**同一批批量创建的格子/列表项**(典型的设置面板选项按钮阵列),不是独立功能按钮。 ## 三、命令 ID 可直发范围 **在 `0x68B2B0` 分派表内(共 34 个,可直接用虚表直调)** ``` 0x01、0x0B~0x0E、0x1E、0x1F、0x28~0x2C、0x31~0x36、0x37、0x39、0x3B、0x46、0x4F~0x56 ``` **不在分派表内**(0x47~0x4E、0x12~0x15、0x20~0x27、0x2D、0x2F、0x98~0xA2、0xA3、0xA4、0x425、0x4DE、0x1C9 等):这些控件多属于子窗口 / 列表项,由各自的 WndProc 或跳转表处理,直接按主窗口槽 #1 发命令可能无反应,需要先确认其父窗口实例。 ## 四、本次踩到的坑(必看) ### 1. `push 0x3F4` 的机器码字节写错 ```text 错:置入代码 ({ 106, 244, 3, 0, 0 }) 106 = 0x6A 是 push imm8 → 实际压入 0xFFFFFFF4(-12) 后续字节 03 00 被解码成 add eax,[eax],整段指令流从此错位, mov ecx,[ebp-4] / mov edx,[ecx] 两条被吞掉, call [edx+4] 用的是垃圾寄存器 → 点击无任何反应。 对:置入代码 ({ 104, 244, 3, 0, 0 }) 104 = 0x68 是 push imm32 → 68 F4 03 00 00 = push 0x3F4 ``` 规则:**立即数 > 0x7F 或超过 1 字节时,必须用 imm32 操作码(push=0x68)**。例如 `push 0x31` 用 106 是对的(1 字节),`push 0x3F4` 必须用 104。 ### 2. 链路自检加在日志里 修正后的子程序在发命令前会打印父窗口的虚表与槽 #1: ```text 链路【助手窗口=… 按钮=… 父窗口=… 虚表=1079A6C 槽1=68B2B0】 ``` `虚表=0x1079A6C`、`槽1=0x68B2B0` 两个值正常即代表父窗口选对、分派函数可达;不符则说明取到的不是助手窗口,不要发命令。 ## 五、测试流程 1. 游戏里先打开助手窗口(`[NPC基址值+0x414]` 才是有效指针) 2. `遍历助手控件` → 应输出 74 个控件(已实测) 3. `小助手开_新路` → 应开始挂机 4. `小助手关_新路` → 应停止挂机 5. `小助手_点控件 (偏移)` 通用版 → 换偏移即可点其它按钮