# 控件表 · 助手面板口径 与 控件池口径 对照 > 整理:2026-09-25 | 依据 9-18 旧表(实机遍历 + 静态反汇编)与 9-25 活体表(CE 桥读控件池)两套独立证据 > 目的:把两套**看起来不一样、实际指向同一批控件**的表对上,以后点按钮不用再扫池子 --- ## 一、已有的控件表在哪 | 文件 | 口径 | 范围 | |---|---|---| | `05_助手UI控件逆向/助手全量控件ID清单.html` | 静态全量 | 58 条控件登记 + 65 个分派命令 ID | | `05_助手UI控件逆向/助手控件实机对照表.md` | 实机遍历(易语言) | 助手窗口 74 个(21:22 二次实测 75 个),偏移→ID→功能名 | | `05_助手UI控件逆向/助手0x3F4分派机制与控件ID实现表.md` | 静态反汇编 | 虚表槽1 动作码 + 154 项跳转表 + 公共尾部区间 | | `05_助手UI逆向_偏移总表.html` | 内存结构统计 | 238/496 槽控件对象转储后的偏移语义统计 | | `05_助手UI控件逆向/06_偏移0x364全量反汇编分析.html` | 偏移考古 | 全 exe 879 处 / 约 300 个函数 | **范围必须分清**:上面五份全部是**助手面板(InterAutoPlay)这一个窗口**的控件表,**不是控件池 0x3C35758 的 15000 槽全量表**。 控件池的全量清单目前还没有 —— 只能靠跑 `控件_搜名字 ("", 0)` 或开 CE 桥导出。 --- ## 二、★ 两套口径的对应关系(本轮核心发现) **9-18 那套记的是「助手窗口 + 相对偏移」**(`助手窗口 + 0x3938` 这种); **9-25 那套记的是「控件池槽号」**(池 `[槽号]`,槽 4231 这种)。 两套完全不同的寻址方式,但底下是同一批控件对象。逐条对上: | 控件 | 9-18 偏移(助手窗口相对) | 9-18 ID | 9-18 名称 | 9-18 资源名 | **9-25 池槽** | **9-25 ID** | **9-25 名称** | |---|---|---|---|---|---|---|---| | 启动内挂丸 | — | `0x31` | 开始挂机 | `auto_play.bmp` | **4231** | **49** | 启动内挂丸 | | 停止内挂丸 | — | `0x32` | 停止挂机 | `auto_stop.bmp` | **4232** | **50** | 停止内挂丸 | | 设定内挂丸 | `0x37F8` | `0x33` | 设置 | `auto_setup.bmp` | **4233** | **51** | 设定内挂丸 | | 关闭内挂丸 | `0x37FC` | `0x34` | 关闭窗口 | `auto_close.bmp` | **4234** | **52** | 关闭内挂丸 | | 设定内挂(收缩) | `0x3800` | `0x36` | 取消 | `cancel_click.bmp` | — | — | — | | 攻击行动范围 | — | — | — | — | **4270** | 0 | 设定内挂丸的攻击行动范围。 | **ID 数值巧合同号(0x31=49 / 0x32=50 / 0x33=51 / 0x34=52),功能一一对应,不是巧合** —— 控件工厂 `InterUI_Manufacture`(`0x75B230`)构造控件时就是往 `[控件+0x364]` 写这个 ID,两边读的同一个字段。 ### 这意味着什么 1. **昨天活体定案的「槽 4231 = 启动内挂丸」被 9-18 那份独立证据链证实**。昨天那个结论只有单条证据(CE 活体读池),现在有了第二条(易语言实机遍历 + 静态反汇编)。 2. **点按钮用的命令字 0x31 / 0x32 是对的**。我们给的代码里 push 的就是 49 / 50,与 9-18 表中的 `0x31 开始挂机 / 0x32 停止挂机` 完全同号。 3. **以后不用扫池子找按钮了**。已知槽号(4231/4232/4233/4234)和已知命令字(0x31~0x34),两套可以互查。 4. 9-18 那份表里的 `+0x364` 就是我们这两天反复确认的 **`控件 + 868`(十进制)** —— 昨天把它定为"此前一直读 860 是错的",跟 9-18 的静态结论完全闭环。 --- ## 三、需要修正的一条:`+0x368` 不是计数,是字符串 `05_助手UI控件逆向/助手UI逆向_偏移总表.html` 里写: > 「编辑框文字不在对象体内:+0x368/+0x380 只是计数,文本在共享组件指针指向的堆缓冲区」 **这条对 9-18 那批样本成立,对我们这批不适用,且已被活体推翻。** | 证据 | 结论 | |---|---| | 9-18 偏移总表 | `+0x368/+0x380` = 编辑框文字长度计数 | | 9-25 活体读槽 4231 的 `+0x368` | 直接读出字符串 **`启动内挂丸`**(BIG5 10 字节 + `00`) | | 9-25 活体读槽 4270 的 `+0x368` | 直接读出 **`设定内挂丸的攻击行动范围。`** | **判断**:`+0x368` 是**内联字符串缓冲**(字面量写在对象体里),不是指针、不是计数。这也解释了为什么静态反汇编在 `.text` 里搜不到任何 `[reg+0x368]` 形式的引用(全 `.text` 仅 1 处且是误解码的 `inc dword [0x368]`)—— 名称由引擎运行时写进对象,代码里不以固定偏移形式引用。 同文档那句「⚠ 语义随类而变」是对的:`+0x364` 在 `Inter*` 窗口上是「当前活动子对象指针」,在**控件对象**上是控件 ID。用之前先认清对象属于哪一类。 --- ## 四、虚表值三处不一致(存疑,待活体复核) | 出处 | 虚表 | 槽1 | |---|---|---| | 9-18《0x3F4 分派机制》§二 | `0x010A20F8` | `0xA3F3D0` | | 9-18《实机对照表》踩坑记录 | `0x01079A6C` | `0x68B2B0` | | 9-25 活体读槽 4231 控件 | `0x10F1EE4` | `0xCFB4B0` | | 9-25 活体读 `[控件+4]`(槽 4229 容器) | `0x10E3050` | `0xA82550` | 四个值两两不同。**结合"语义随类而变",合理推测是不同 C++ 类各自有虚表** —— 助手窗口(`InterAutoPlay`)是一个类,池里的通用控件对象是另一个类,而 `[控件+4]` 指向的容器又是一个类。 **对开发的实际影响**:这不影响「按槽号 + 命令字」点控件,因为控件 ID 和 `ecx=控件+4` 已经实测闭合。但如果哪天点某个控件没反应,先查虚表落点,比盲调快。 --- ## 五、速查:内挂丸四键 | 动作 | 池槽号 | 命令字(push 的值) | 9-18 偏移口径 | 备注 | |---|---|---|---|---| | 开 | **4231** | `49`(0x31) | `0x3938` | handler `0xA406B4` | | 关 | **4232** | `50`(0x32) | `0x393C` | handler `0xA40CA9` | | 设定 | **4233** | `51`(0x33) | `0x37F8` | handler `0xA40D4E` | | 关闭面板 | **4234** | `52`(0x34) | `0x37FC` | handler `0xA40DA5` | 易语言侧: ```e 内存_读整数型 (句柄, 控件 + 868) ' 控件ID,读出来就是 49/50/51/52 ``` 机器码 push 的就是这个 ID;`6A imm8` 写法只对 1 字节立即数成立,**9-18 踩过的坑:命令字 ≤0xFF 用 `{ 106, 49 }` 是对的,但 `push 0x3F4` 必须用 `{ 104, 244, 3, 0, 0 }`**(`68 imm32`),写成 `106` 会吃掉落后的整段指令流。 --- ## 六、还没做的一件事 控件池 15000 槽的**全量名称清单**还没导出。要拿到它只有两条路: 1. 跑 `控件_搜名字 ("", 0)`(上次给的只读子程序,全列); 2. 开 Cheat Engine 并加载 `D:\ce_mcp\ce_mcp_bridge.lua`,我直接读出来导成 CSV。 拿到后可以把助手面板的 75 个控件跟池里其余近万个控件对上,判断哪些面板已经开过、还有哪些没被发现。