Fix: Make the remote chat dialog Unicode and loader-independent
Clients packaged as SC_AES/sRDI shellcode run the payload image as raw shellcode inside the loader stub, so the chat manager was handed the stub's module handle. The stub's resource section only carries a manifest, and Windows resource APIs reject manually mapped images outright, so creating IDD_CHAT failed and the chat thread exited before the window ever existed. The chat window now falls back to an embedded compiled dialog template that is byte-identical to the IDD_CHAT resource, and the title-bar icon is rebuilt directly from the module's own resource directory instead of LoadIcon, bypassing the loader on both paths. The PE walking code checks every offset against SizeOfImage and the resource directory size, so a malformed or truncated image returns NULL instead of faulting. Deployments where the resource lookup already works keep the original code path unchanged. The dialog is now created and driven with the wide-character API. The client is still an MBCS build, but an ANSI dialog renders text with the system code page, so GBK chat text turned into mojibake on German and other non-936 systems. Incoming text is converted CP936 to UTF-16 and outgoing text strictly back to CP936; characters GBK cannot represent (emoji, accented letters) are refused with a visible notice instead of silently becoming '?'. Static labels follow the system UI language, and IDD_CHAT now uses the scalable MS Shell Dlg face so font linking can supply CJK glyphs. The window is now positioned explicitly as well. DS_CENTER in the template put it at the work area origin on the three-monitor host: the centred position came out negative there and Windows clamps out-of-range creation coordinates to that origin. It is centred in the work area of the monitor under the cursor instead, falling back to SPI_GETWORKAREA. Teardown no longer leaves a hidden window behind either. The dialog thread blocked in GetMessageW and never saw m_bRun cleared, while the destructor waited for that thread before sending the message that would have destroyed the window, so a close command that never arrived (the sub-connection already gone, or WaitSendIdle timing out before CancelIO) leaked the window, the dialog thread and the manager loop. The destructor now destroys the window first, the loop checks m_bRun before blocking, and it destroys the window itself if it exits first. Co-Authored-By: deepseek-flash
This commit is contained in:
1 parent
3ae6298746
commit
fff7c67af6
8 files changed
+425
-52
No files matched your search
@@ -0,0 +1,44 @@
|
||||
// ChatDialogTemplate.h: IDD_CHAT 的编译后 DLGTEMPLATEEX(内嵌内存模板)
|
||||
//
|
||||
// 用途:加壳部署(EXE + SC_AES/sRDI)的客户端里,ChatManager 的 hInstance 是外壳进程
|
||||
// 映像(GetModuleHandle(NULL)),其资源里只有清单、没有 IDD_CHAT;而载荷 EXE 以裸
|
||||
// shellcode 在壳进程内运行,未注册进加载器,FindResource/LoadResource/CreateDialogParamW
|
||||
// 一律取不到资源(实测 Win11 26200 返回 err=1812 / 59)。此时用下面的内存模板直接
|
||||
// CreateDialogIndirectParamW 建窗,与部署形态无关。
|
||||
//
|
||||
// 数据来源:client/Script.rc 的 IDD_CHAT(DIALOGEX)。DLGTEMPLATEEX 的字符串字段
|
||||
// 一律是 UTF-16,同一份字节既可用于 A 接口也可用于 W 接口;聊天窗口固定用 W 接口
|
||||
// 创建成 Unicode 对话框,否则 MBCS 客户端在非中文系统(德语等)上会按系统代码页
|
||||
// 渲染 GBK 字节,中文全部乱码。
|
||||
//
|
||||
// 重新生成(改动 Script.rc 的 IDD_CHAT 后必须同步):
|
||||
// 1. rc /fo dlg.res dlg.rc (dlg.rc 只保留与 Script.rc 相同的 IDD_CHAT 块)
|
||||
// 2. link /dll /noentry /machine:x64 /out:dlg.dll dlg.res
|
||||
// 3. 从 dlg.dll 的 RT_DIALOG(5) → 106 → 任意语言 取数据块,按 16 字节一行导出。
|
||||
// 当前块 240 字节:CAPTION "Remote Chat"、FONT 9 "MS Shell Dlg" charset 1、
|
||||
// 控件 ID 1001/1002/1003/1004,与 Script.rc 完全一致。
|
||||
|
||||
#ifndef YAMA_CHAT_DIALOG_TEMPLATE_H
|
||||
#define YAMA_CHAT_DIALOG_TEMPLATE_H
|
||||
|
||||
// DLGTEMPLATEEX 的 DWORD 字段要求模板指针 4 字节对齐;显式声明对齐,避免依赖
|
||||
// 编译器把字节数组放在什么边界上。
|
||||
__declspec(align(4)) static const unsigned char kChatDialogTemplate[] = {
|
||||
0x01, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x08, 0xCA, 0x80,
|
||||
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEB, 0x00, 0x9B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x00,
|
||||
0x65, 0x00, 0x6D, 0x00, 0x6F, 0x00, 0x74, 0x00, 0x65, 0x00, 0x20, 0x00, 0x43, 0x00, 0x68, 0x00,
|
||||
0x61, 0x00, 0x74, 0x00, 0x00, 0x00, 0x09, 0x00, 0x90, 0x01, 0x00, 0x01, 0x4D, 0x00, 0x53, 0x00,
|
||||
0x20, 0x00, 0x53, 0x00, 0x68, 0x00, 0x65, 0x00, 0x6C, 0x00, 0x6C, 0x00, 0x20, 0x00, 0x44, 0x00,
|
||||
0x6C, 0x00, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x44, 0x08, 0xA1, 0x50, 0x03, 0x00, 0x03, 0x00, 0xE5, 0x00, 0x6B, 0x00, 0xE9, 0x03, 0x00, 0x00,
|
||||
0xFF, 0xFF, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x44, 0x00, 0xA1, 0x50, 0x03, 0x00, 0x71, 0x00, 0xAA, 0x00, 0x26, 0x00, 0xEA, 0x03, 0x00, 0x00,
|
||||
0xFF, 0xFF, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x01, 0x50, 0xB2, 0x00, 0x74, 0x00, 0x36, 0x00, 0x0E, 0x00, 0xEB, 0x03, 0x00, 0x00,
|
||||
0xFF, 0xFF, 0x80, 0x00, 0x53, 0x00, 0x65, 0x00, 0x6E, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x50, 0xB2, 0x00, 0x85, 0x00,
|
||||
0x36, 0x00, 0x0E, 0x00, 0xEC, 0x03, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x00, 0x45, 0x00, 0x6E, 0x00,
|
||||
0x64, 0x00, 0x20, 0x00, 0x43, 0x00, 0x68, 0x00, 0x61, 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
#endif // YAMA_CHAT_DIALOG_TEMPLATE_H
|
||||
Reference in new issue
Block a user