热血江湖 YGOnline.exe —— 窗口弹出状态 与 窗口信息遍历 版本:2026-09-28 目标:D:\rxjh2025\client\YGOnline.exe(32位,无ASLR,模块基址恒 0x400000) ================================================================================ 【2026-09-28 14:2x 修正】本文第二节"窗口对象 +0x40 == 1 即弹出"的公式已被实测推翻: 窗口对象自身的 +0x40 是"曾激活过"的粘滞标志,关窗不清零(组队窗正显示时它的 +0x40 = 0; 交易窗已关闭时它的 +0x40 仍 = 1)。正确判据是【内容面板 InterWindow(类型码 24)子对象的 +0x40】。 详情与修正后的子程序见《组队窗口7034_7035_与弹出判定修正_0928.txt》。本文其余部分(槽位全表、 子控件全表、点按钮机器码)仍然有效。 【2026-09-28 14:34 再修正】该修正文件里的公式仍保留了一条"窗口对象自身 +0x40 == 1"的或条件, 实测证明它会把【已关闭的交易窗口】判成"还开着"(+0x40 是粘滞标志,关窗不清零)→ 已废。 ★ 最终定稿:只看【类型码 24 = InterWindow 内容面板】的 +0x40;含全窗口面板偏移速查表与 可直接粘贴的易语言子程序 → 见《窗口弹出判定_通用方法_0928.txt》。 一、本次要解决的窗口 = InterExchange(交易窗口) -------------------------------------------------------------------------------- 你给的按钮 ID 6700 / 6701,活体反查结果: 按钮对象 0x5728AE50 id=6700 vt=0x010F1EE4(ButtonClass) pos=85,178 size=18x60 按钮对象 0x57292800 id=6701 vt=0x010F1EE4(ButtonClass) pos=156,178 size=18x60 两者父对象 = 0x47DA8A98 = IFManager + 0x4D4 = ?AVInterExchange@@ 即:你看到的这个窗口是【交易窗口 InterExchange】,不是通知弹窗(通知弹窗是 IFManager+0x404 的 InterNotice→NoticePopup,按钮 ID 是 7026/7027 那一档,两者不是一回事)。 该窗口对象在 IFManager 里的槽偏移: 槽偏移 = 0x4D4 (十进制 1236) ← 交易窗口 (对比:通知 0x404,队伍 0x4E8,背包 0x3B8,主界面 0x3AC) 二、★"窗口是否弹出"的通用判定(本次定稿) -------------------------------------------------------------------------------- 判定公式(对任意接口窗口通用): 窗口对象 = 读整数( 读整数(#IFManager基址) + 槽偏移 ) 已弹出 = ( 窗口对象 > 0 ) 且 ( 读整数(窗口对象 + 64) == 1 ) 其中 64 = 0x40,是每个窗口对象的"显示中"标志。 ★ 活体实测(2026-09-28,双客户端): pid 14256 各窗口 +0x40 == 1 的只有 5 个: InterMAIN(主界面) / InterChat(聊天) / InterMugongHanbigwang(武功栏) / InterMiniMap(小地图) / InterExchange(交易窗口) pid 16164 只有 4 个: InterMAIN / InterChat / InterMiniMap / InterExchange (16164 少了武功栏,因为那号技能栏被收起;其余 100 个接口 +0x40 全部 == 0) 也就是说:常驻 HUD(主界面/聊天/小地图/技能栏)恒为 1,玩家主动打开的窗口(这里=交易窗口) 也为 1,没打开的接口一律 0 —— 规律干净。 注意:这些窗口对象都是【游戏启动时就全部创建好的】(所有槽指针都非 0),所以 "槽指针 != 0"判断不了是否弹出,必须看 +0x40。 三、IFManager 槽位 → 类名 全表(0x0188C61C → IFManager 对象) -------------------------------------------------------------------------------- 0x3AC InterMAIN 0x3B0 InterChat 0x3B4 InterStatus 0x3B8 InterInventory 0x3C0 InterCenterMessage 0x3C4 InterMugongHanbigwang 0x3CC InterOption 0x3D0 InterMiniMap 0x3D4 InterHelp 0x3D8 InterExit 0x3DC InterQuestEx 0x3F0 InterMessenger 0x3F4 InterStatusReply 0x3F8 CInterDye 0x3FC CPinoDeburp 0x400 InterLuckyBox 0x404 InterNotice 0x408 InterNpc 0x40C InterPcRoomBenefit 0x410 InterSendPackage 0x414 InterTimer 0x418 InterPath 0x41C InterCallToGuild 0x420 CBloodBattle 0x424 InterInitiateAbility 0x428 InterServerMove 0x42C InterByulho 0x430 InterAutoPlay 0x434 InterChangeLooksPet 0x438 InterJesukbu 0x43C InterHairdressing 0x440 InterItemRooting 0x444 InterJedanbu 0x448 CInterSaju 0x44C InterLuckyBag 0x450 InterEvent 0x454 InterItemReg 0x458 InterManufacture 0x45C InterCouple 0x460 InterMedicineMaking 0x464 InterMyAging 0x468 InterNameChange 0x46C InterGenderChange 0x470 InterPartySearch 0x474 InterPkPropensityQuestNotice 0x478 InterPremiumCashItem 0x47C InterPremiumSelect 0x480 InterSecretCode 0x484 InterSoulStone 0x488 InterAttributeSoulStone 0x48C InterAttChangeSoulStone 0x490 SoulPetIncubation 0x494 InterGifticon 0x498 InterMaeyuExchangeItem 0x49C InterExcangeHeroWeapon 0x4A0 InterExchangeGroupEquipment 0x4A4 InterExchangeAttributeAccessory 0x4A8 InterWarpToGuild 0x4AC InterWarpToParty 0x4B0 InterGibo 0x4B4 InterNPCUnLock 0x4B8 CPetInven 0x4BC CPetInfo 0x4C0 InterPetNaming 0x4C4 CSajeSystem 0x4C8 InterMunpaWar 0x4CC InterCoatChange 0x4D0 InterEscape 0x4D4 InterExchange ← 交易窗口 0x4D8 InterAttributeJesukbu 0x4DC InterMacro 0x4E0 InterMail 0x4E4 InterMugongLearn 0x4E8 InterParty 0x4EC InterPCStore 0x4F0 InterPremiumCharm 0x4F4 InterPremiumWin 0x4F8 InterWar 0x4FC InterWeb 0x500 InterWebShop 0x504 CInterCharm 0x508 InterMunpa 0x50C InterCastleWar 0x510 InterInGameTotalShop 0x514 InterRaid 0x518 InterUI_Community 0x51C InterUI_CharacterInfo 0x520 InterUI_Manufacture 0x524 InterUI_Option 0x528 InterUI_Quest 0x530 InterUI_AllFunction 0x534 InterSoulPetEvolve 0x538 InterSoulPetReinforce 0x53C InterSoulPetWareHouse 0x540 InterSoulPetSeal 0x544 InterEmoticon 0x548 InterMarbleEvolve 0x54C InterGuildNameChange 0x550 ScriptDungeon (附带查明的全局单例:0x0188C600 CEffectManager / 0x0188C604/608 YBfont / 0x0188C60C Cursor / 0x0188C614 TipMsg / 0x0188C618 WindowManager / 0x0188C61C IFManager) 四、InterExchange 子控件全表(父对象 + 相对偏移 → 子对象) -------------------------------------------------------------------------------- 偏移(hex) 偏移(dec) 类名 控件ID 说明 0x330 816 InterWindow 6707 0x334 820 InterWindow 6696 0x338 824 ButtonClass 6801 0x348 840 TextBox 6710 0x34C 844 TextBox 6749 0x350 848 TextBox 6711 0x354 852 TextBox 6750 0x358 856 ButtonClass 6708 0x35C 860 ButtonClass 6709 0x360 864 ListCtrl 6714 0x364 868 ListCtrl 6753 0x368 872 TextBox 6713 0x36C 876 TextBox 6752 0x370 880 TextBox 6712 0x374 884 TextBox 6751 0x378 888 InterSTATIC 6697 0x37C 892 ButtonClass 6698 0x388 904 InterSTATIC 6699 0x38C 908 ButtonClass 6700 ← 你给的按钮A 0x394 916 ButtonClass 6701 ← 你给的按钮B 0x3A0 928 InterMsgBox 6702 (消息框子对象) 0x3A4 932 InterWindow 6804 0x3A8 936 ButtonClass 6805 0x3AC 940 ButtonClass 6806 0x3B0 944 EditBox 6807 每个控件对象通用字段: +0x00 虚表 / +0x04 父对象 / +0x08 类型码 / +0x0C 控件ID +0x1C 1 / +0x28,+0x2C 位置x,y / +0x30,+0x34 大小cx,cy / +0x40 可见 类型码: 24=InterWindow 31=ListCtrl 32=TextBox 34=ButtonClass 85=InterSTATIC 14=接口基类(InterExchange/InterNotice 本身) 五、常量(加进常量表) -------------------------------------------------------------------------------- .常量 IFManager基址, "25740828", , 0188C61C IFManager对象指针全局 .常量 窗口显示标志, "64", , 0x40 窗口对象"显示中"标志 .常量 交易窗口槽, "1236", , 0x4D4 InterExchange 在 IFManager 里的槽 六、易语言子程序 ================================================================================ .版本 2 .子程序 窗口是否打开, 逻辑型, , 通用:传 IFManager 槽偏移(十进制) 判断该窗口是否弹出 .参数 槽偏移, 整数型 .局部变量 接口管理, 整数型 .局部变量 窗口对象, 整数型 接口管理 = 内存_读整数型 (全局_进程句柄, #IFManager基址) .如果真 (接口管理 ≤ 65536) 返回 (假) .如果真结束 窗口对象 = 内存_读整数型 (全局_进程句柄, 接口管理 + 槽偏移) .如果真 (窗口对象 ≤ 65536) 返回 (假) .如果真结束 返回 (内存_读整数型 (全局_进程句柄, 窗口对象 + #窗口显示标志) = 1) .版本 2 .子程序 交易窗口是否弹出, 逻辑型 返回 (窗口是否打开 (#交易窗口槽)) .版本 2 .子程序 枚举已打开窗口, , , 遍历 IFManager 全部槽,输出所有正在显示的窗口 .局部变量 接口管理, 整数型 .局部变量 i, 整数型 .局部变量 槽, 整数型 .局部变量 窗口对象, 整数型 .局部变量 显示标志, 整数型 接口管理 = 内存_读整数型 (全局_进程句柄, #IFManager基址) .如果真 (接口管理 ≤ 65536) 挂机信息.加入文本 (自定义时间 () + “IFManager 未就绪” + #换行符) 返回 () .如果真结束 挂机信息.加入文本 (自定义时间 () + “------ 已打开窗口 ------” + #换行符) .计次循环首 (113, i) 槽 = 928 + (i - 1) × 4 窗口对象 = 内存_读整数型 (全局_进程句柄, 接口管理 + 槽) .如果真 (窗口对象 > 65536) 显示标志 = 内存_读整数型 (全局_进程句柄, 窗口对象 + #窗口显示标志) .如果真 (显示标志 = 1) 挂机信息.加入文本 (自定义时间 () + “槽 ” + 到文本 (槽) + “ 对象 ” + 到文本 (窗口对象) + “ 控件ID ” + 到文本 (内存_读整数型 (全局_进程句柄, 窗口对象 + 12)) + #换行符) .如果真结束 .如果真结束 .计次循环尾 () .版本 2 .子程序 遍历交易窗口, , , 输出交易窗口本体与全部子控件信息 .局部变量 接口管理, 整数型 .局部变量 交易窗口, 整数型 .局部变量 子对象, 整数型 .局部变量 i, 整数型 .局部变量 偏移表, 整数型, , "25" .局部变量 名称表, 文本型, , "25" 接口管理 = 内存_读整数型 (全局_进程句柄, #IFManager基址) .如果真 (接口管理 ≤ 65536) 挂机信息.加入文本 (自定义时间 () + “IFManager 未就绪” + #换行符) 返回 () .如果真结束 交易窗口 = 内存_读整数型 (全局_进程句柄, 接口管理 + #交易窗口槽) .如果真 (交易窗口 ≤ 65536) 挂机信息.加入文本 (自定义时间 () + “交易窗口对象为空” + #换行符) 返回 () .如果真结束 挂机信息.加入文本 (自定义时间 () + “交易窗口对象:” + 到文本 (交易窗口) + #换行符) 挂机信息.加入文本 (自定义时间 () + “交易窗口状态:” + 选择 (内存_读整数型 (全局_进程句柄, 交易窗口 + #窗口显示标志) = 1, “已弹出”, “未弹出”) + #换行符) 挂机信息.加入文本 (自定义时间 () + “交易窗口ID:” + 到文本 (内存_读整数型 (全局_进程句柄, 交易窗口 + 12)) + #换行符) 偏移表 [1] = 816 名称表 [1] = “框架1” 偏移表 [2] = 820 名称表 [2] = “框架2” 偏移表 [3] = 824 名称表 [3] = “按钮” 偏移表 [4] = 840 名称表 [4] = “文本框1” 偏移表 [5] = 844 名称表 [5] = “文本框2” 偏移表 [6] = 848 名称表 [6] = “文本框3” 偏移表 [7] = 852 名称表 [7] = “文本框4” 偏移表 [8] = 856 名称表 [8] = “按钮” 偏移表 [9] = 860 名称表 [9] = “按钮” 偏移表 [10] = 864 名称表 [10] = “列表1” 偏移表 [11] = 868 名称表 [11] = “列表2” 偏移表 [12] = 872 名称表 [12] = “文本框5” 偏移表 [13] = 876 名称表 [13] = “文本框6” 偏移表 [14] = 880 名称表 [14] = “文本框7” 偏移表 [15] = 884 名称表 [15] = “文本框8” 偏移表 [16] = 888 名称表 [16] = “静态文字1” 偏移表 [17] = 892 名称表 [17] = “按钮” 偏移表 [18] = 904 名称表 [18] = “静态文字2” 偏移表 [19] = 908 名称表 [19] = “按钮A” 偏移表 [20] = 916 名称表 [20] = “按钮B” 偏移表 [21] = 928 名称表 [21] = “消息框” 偏移表 [22] = 932 名称表 [22] = “窗口” 偏移表 [23] = 936 名称表 [23] = “按钮” 偏移表 [24] = 940 名称表 [24] = “按钮” 偏移表 [25] = 944 名称表 [25] = “输入框” .计次循环首 (25, i) 子对象 = 内存_读整数型 (全局_进程句柄, 交易窗口 + 偏移表 [i]) .如果真 (子对象 > 65536) 挂机信息.加入文本 (自定义时间 () + 名称表 [i] + “(+” + 到文本 (偏移表 [i]) + “) 对象 ” + 到文本 (子对象) + “ 类型码 ” + 到文本 (内存_读整数型 (全局_进程句柄, 子对象 + 8)) + “ 控件ID ” + 到文本 (内存_读整数型 (全局_进程句柄, 子对象 + 12)) + “ 可见 ” + 到文本 (内存_读整数型 (全局_进程句柄, 子对象 + #窗口显示标志)) + #换行符) .如果真结束 .计次循环尾 () 挂机信息.加入文本 (自定义时间 () + “------ 交易窗口遍历完成 ------” + #换行符) 七、关于你给的 63133528 -------------------------------------------------------------------------------- 63133528 按十进制 = 0x03C35758 —— 这正是知识库里早就记过的【全局大列表(控件池)】: 15000 槽 dword 指针数组(RVA 0x3835758),空槽=0,-1=哨兵。 它第 1 项就是 0x03C44270(一个 ?AVCharParser@@ 对象);前后那串 (0x0F316B30=Cursor、0x098F4228=WindowManager、0x0DD5FB98=CEffectManager) 是池里的其他对象,和 0x0188C600 那组全局单例指向同一批对象。 结论:它是"控件/对象池",不是"窗口弹出状态"。窗口弹出状态用第二节的 +0x40 公式即可。 (若按十六进制解读 0x63133528,那里读出来是 0xFFFFFFFF,是空的。) 八、按钮点击(静态反汇编定稿) -------------------------------------------------------------------------------- 按钮的点击动作在 ButtonClass::消息处理(虚表 slot1 = 0xCFB4B0)的 msg=8 分支里, 最终做的就一件事:把事件 0x409 + 自己的控件ID 派发给 UI 事件分发器 [0x0188C60C]: 0xCFB623 push 0 ; 参数3 = 0 0xCFB62B push eax ; 参数2 = [按钮+0x0C] 控件ID 0xCFB62C push 0x409 ; 参数1 = 事件号 0x409 0xCFB631 mov ecx,[0x0188C60C] ; 分发器对象 0xCFB637 mov edx,[ecx] 0xCFB639 mov ecx,[0x0188C60C] 0xCFB63F mov eax,[edx+4] 0xCFB642 call eax ; 被调方自清栈(stdcall,3个参数) (0xCFB644 紧跟一条 nop,之后没有 add esp -> 确认是被调方清栈) 所以"点按钮"= 远程执行下面这段(与死亡回城/快捷栏同一套"调用字节集"打法): 机器码: 6A 00 | 68 <控件ID(4字节小端)> | 68 09 04 00 00 | 8B 0D 0C C6 88 01 | 8B 11 | 8B 0D 0C C6 88 01 | 8B 42 04 | FF D0 | C3 易语言: .版本 2 .子程序 按钮点击call, , , 按控件ID点击任意控件(含按钮) .参数 控件ID, 整数型 .局部变量 代码, 字节集 代码 = 机器码到字节集 (“6A0068”) + 取字节集左边 (到字节集 (控件ID), 4) + 机器码到字节集 (“68090400008B0D0CC688018B118B0D0CC688018B4204FFD0C3”) 调用字节集 (全局_进程句柄, 代码) .版本 2 .子程序 点击交易窗口按钮A, , , 交易窗口 +0x38C 那个按钮(当前ID 6700) .局部变量 接口管理, 整数型 .局部变量 交易窗口, 整数型 .局部变量 按钮对象, 整数型 接口管理 = 内存_读整数型 (全局_进程句柄, #IFManager基址) 交易窗口 = 内存_读整数型 (全局_进程句柄, 接口管理 + #交易窗口槽) .如果真 (交易窗口 ≤ 65536) 返回 () .如果真结束 按钮对象 = 内存_读整数型 (全局_进程句柄, 交易窗口 + 908) 按钮点击call (内存_读整数型 (全局_进程句柄, 按钮对象 + 12)) 说明:控件ID 每次开客户端都会变(会话内递增分配),所以要先从对象 +0x0C 读出来再用, 绝不能把 6700/6701 写死进代码。 (注意:这条直达分发器的路会跳过按钮自身的前置检查,正常场景没问题。 消息号→分支已用跳转表核对:msg=2→0xCFBC7B、3→0xCFB64A、6→0xCFBA4F、7→0xCFB839、8→0xCFB4FD(点击)。 若要完整走按钮原逻辑:ecx=按钮对象,push 参数3=0 / push 参数2=0 / push 参数1(msg)=8 / call 0xCFB4B0。) ================================================================================ 实测脚本(D:\ce_mcp\): _vis.py 统计各接口 +0x40 分布(窗口是否显示) _exch.py InterExchange 结构与按钮指针定位 _idfind.py 按控件ID 反查按钮对象 _popscan.py 扫描 NoticePopup 实例 _globals.py 全局单例区 + IFManager 槽位类名 _x4d4.py 静态搜索 [IFManager+0x4D4] 引用 ================================================================================