【WINAPI】MessageBox细解(二)
【WINAPI】MessageBox细解(二)
- 0x00 简介
- 0.1 关于
- 0.2 工具
- 0x01 程序对象
- 0.1 程序源码
- 1.2 运行结果
- 0x02 函数细解
- 2.1 前篇回顾
- 2.2 静态分析
- 2.2.1 程序源码
- 2.2.2 MessageBoxTimeoutW()
- 2.2.3 MessageBoxWorker()
- 核心代码A:69E7E1B7~69E7E1C6
- 核心代码B:69E7E1F0~69E7E203
- 核心代码C:69E7E212~69E7E244
- 核心代码D:69E7E280~69E7E308
- 核心代码E:69E7E30B~69E7E350
- 核心代码F:69E7E352~69E7E368
- 核心代码G:69E7E372~69E7E45E
- 核心代码H:69E7E46A~69E7E4AC
- 0x03 总结
0x00 简介
0.1 关于
MessageBox细解(一)发布到现在已经过去两天有余了,想着也该更新第二部分了。第一部分讲述了基础的三个微软公开的消息盒子的函数。这一部分就好好研究一下未被公开的两个函数MessageBoxTimeoutW()和MessageBoxWorker()。相信各能够更加理解消息盒子的实现原理。预告:《MessageBox细解》系列还有第三部分和第四部分。
0.2 工具
操作系统:Windows10。
调试器:Ollydbg以及IDA。
编译器:VS2019
0x01 程序对象
0.1 程序源码
同第一部分,0x02的程序。
#include <Windows.h>
#include "resource.h"#define MSGBOXSP_TIME 0//设置预编译选项typedef struct _MSGBOXDATA {MSGBOXPARAMSW mbparams;BYTE unknown[0X68 - sizeof(MSGBOXPARAMSW)];
}MSGBOXDATA, *LPMSGBOXDATA;typedef int (WINAPI *MSGTIMEPROC)(HWND, LPCWSTR, LPCWSTR, UINT, WORD, DWORD);
typedef int (_fastcall *MSGWORKERPROC)(LPMSGBOXDATA);VOID CALLBACK MsgBoxCallback(LPHELPINFO lpHelpInfo);//消息盒子帮助回调函数int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nShowCmd) {HMODULE hDllUser32;#ifdef MSGBOXSP_TIMEMSGTIMEPROC MessageBoxTimeout;#elif defined(MSGBOXSP_WORKER)MSGBOXDATA mbdata;MSGBOXPARAMSW mbparams;MSGWORKERPROC MessageBoxWorker;#endif#ifdef MSGBOXSP_TIMEif((hDllUser32 = LoadLibrary(TEXT("user32.dll"))) != NULL) {MessageBoxTimeout = (MSGTIMEPROC)GetProcAddress(hDllUser32, "MessageBoxTimeoutW");MessageBoxTimeout(NULL, TEXT("Hello World!"), TEXT("Test"), MB_OKCANCEL,MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 3000);}#elif defined(MSGBOXSP_WORKER)if((hDllUser32 = LoadLibrary(TEXT("user32.dll"))) != NULL) {//这个是10.0.19041.610的user32偏移,昨天系统自动更新了,凑合着吧。MessageBoxWorker = (MSGWORKERPROC)((DWORD)hDllUser32 + (DWORD)0x0007E5BD);memset(&mbparams, 0, sizeof(MSGBOXPARAMSW));mbparams.cbSize = sizeof(MSGBOXPARAMSW);mbparams.dwStyle = MB_OKCANCEL | MB_USERICON | MB_HELP;mbparams.lpszText = TEXT("Hello World!");mbparams.lpszCaption = TEXT("Test");//设置自定义图标mbparams.hInstance = hInstance;mbparams.lpszIcon = TEXT("USERICON");//设置帮助回文ID和回调函数mbparams.dwContextHelpId = 0x1;mbparams.lpfnMsgBoxCallback = MsgBoxCallback;//设置显示语言mbparams.dwLanguageId = MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US);memset(&mbdata, 0, sizeof(MSGBOXDATA));memcpy(&mbdata, &mbparams, sizeof(MSGBOXPARAMSW));MessageBoxWorker(&mbdata);}#endifreturn 0;
}//帮助回调函数
VOID CALLBACK MsgBoxCallback(LPHELPINFO lpHelpInfo) {switch(lpHelpInfo->dwContextId) {case 0x1:MessageBox(NULL, TEXT("这是0x1的帮助"), TEXT("帮助"), MB_OK);break;case 0x100:MessageBox(NULL, TEXT("这是0x100的帮助"), TEXT("帮助"), MB_OK);break;default:MessageBox(NULL, TEXT("这是默认帮助"), TEXT("帮助"), MB_OK);break;}
}
本例的user32.dll版本为10.0.19041.610。如果需要兼容性的场合请根据特征码获取函数偏移。
1.2 运行结果
- MessageBoxTimeoutW:
- MessageBoxWorker:
可以看到两个函数都可以正常执行。MessageBoxWorker()有两个更改按钮语言的语句,其中有一个是无效的。无效的原因在本文其实已经能够看到,但请允许我留到最后一篇再去说明。
0x02 函数细解
2.1 前篇回顾
MessageBox细解(一)中我们介绍了三个微软公开的主要创建消息盒子的函数。分别是:
- MessageBox()
- MessageBoxEx()
- MessageBoxIndirect()
并详细分析了三个函数的具体实现原理,并找到了底层调用的MessageBoxTimeoutW()和MessageBoxWorker(),还发现了MessageBoxIndirect()无法更改显示语言的问题。
2.2 静态分析
2.2.1 程序源码
#include <Windows.h>
#include "resource.h"#define MSGBOXSP_SOFT 0//设置预编译选项enum close_button_flag {button_gray,button_enable_ID1,button_enable_ID2
};typedef struct _MSGBOXDATA {MSGBOXPARAMSW mbparams;BYTE unknown[8];WORD wLanguageId;BYTE unknown1[2];PDWORD pdwButtonID;LPCWSTR *pszButtonTextTable;DWORD dwButtonSum;DWORD dwButtonDef;close_button_flag enCloseButtonFlag;DWORD dwMilliseconds;BYTE unknown2[28];
}MSGBOXDATA, *LPMSGBOXDATA;typedef int(_stdcall *MSGSOFTPROC)(LPMSGBOXDATA);
typedef int(_fastcall *MSGSERVICEPROC)(LPCWSTR,LPCWSTR,UINT,DWORD);VOID CALLBACK MsgBoxCallback(LPHELPINFO lpHelpInfo);//消息盒子帮助回调函数int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nShowCmd) {HMODULE hDllUser32;#ifdef MSGBOXSP_SOFTMSGBOXDATA mbdata;MSGBOXPARAMSW mbparams;MSGSOFTPROC SoftModalMessageBox;DWORD dwButtonIdTable[5] = {1,2,3,4,9};LPCWSTR szButtonTextTable[5] ={TEXT("利雅"),TEXT("出品"),TEXT("必属"),TEXT("精品"),TEXT("帮助")};#elif defined(MSGBOXSP_SERVICE)MSGSERVICEPROC ServiceMessageBox;#endif#ifdef MSGBOXSP_SOFTif((hDllUser32 = LoadLibrary(TEXT("user32.dll"))) != NULL) {//这个是10.0.19041.610的user32偏移,昨天系统自动更新了,凑合着吧。SoftModalMessageBox = (MSGSOFTPROC)((DWORD)hDllUser32 + (DWORD)0x0007F410);memset(&mbparams, 0, sizeof(MSGBOXPARAMSW));mbparams.cbSize = sizeof(MSGBOXPARAMSW);mbparams.dwStyle = MB_USERICON;mbparams.lpszText = TEXT("Hello World!");mbparams.lpszCaption = TEXT("Test");//设置自定义图标mbparams.hInstance = hInstance;mbparams.lpszIcon = TEXT("USERICON");//设置帮助回文ID和回调函数mbparams.dwContextHelpId = 0x1;mbparams.lpfnMsgBoxCallback = MsgBoxCallback;//设置显示语言//mbparams.dwLanguageId = MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US);memset(&mbdata, 0, sizeof(MSGBOXDATA));memcpy(&mbdata, &mbparams, sizeof(MSGBOXPARAMSW));//设置显示语言(真)mbdata.wLanguageId = MAKELANGID(LANG_JAPANESE, SUBLANG_JAPANESE_JAPAN);//设置自动关闭时间mbdata.dwMilliseconds = 10000;//设置按钮mbdata.dwButtonSum = 5;mbdata.pdwButtonID = dwButtonIdTable;mbdata.pszButtonTextTable = szButtonTextTable;mbdata.dwButtonDef = 0;mbdata.enCloseButtonFlag = button_enable_ID2;SoftModalMessageBox(&mbdata);}#elif defined(MSGBOXSP_SERVICE)if((hDllUser32 = LoadLibrary(TEXT("user32.dll"))) != NULL) {//这个是10.0.19041.610的user32偏移,昨天系统自动更新了,凑合着吧。ServiceMessageBox = (MSGSERVICEPROC)((DWORD)hDllUser32 + (DWORD)0x0007E986);ServiceMessageBox(TEXT("Hello World"),TEXT("Test"), MB_OKCANCEL | MB_HELP | MB_ICONWARNING,5000);OpenThreadToken(0, 0, 0, 0);}#endifreturn 0;
}//帮助回调函数
VOID CALLBACK MsgBoxCallback(LPHELPINFO lpHelpInfo) {switch(lpHelpInfo->dwContextId) {case 0x1:MessageBox(NULL, TEXT("这是0x1的帮助"), TEXT("帮助"), MB_OK);break;case 0x100:MessageBox(NULL, TEXT("这是0x100的帮助"), TEXT("帮助"), MB_OK);break;default:MessageBox(NULL, TEXT("这是默认帮助"), TEXT("帮助"), MB_OK);break;}
}
示例代码分别调用了ServiceMessageBox()和SoftModalMessageBox(),它们都是属于MessageBoxWorker()下更底层的调用。
2.2.2 MessageBoxTimeoutW()
.text:69E7EDE0 ; __stdcall MessageBoxTimeoutW(x, x, x, x, x, x)
.text:69E7EDE0 public _MessageBoxTimeoutW@24
.text:69E7EDE0 _MessageBoxTimeoutW@24 proc near ; CODE XREF: DisplayExitWindowsWarnings(x)+20F↑p
.text:69E7EDE0 ; MessageBoxExW(x,x,x,x,x)+16↑p ...
.text:69E7EDE0
.text:69E7EDE0 mbdata = _MSGBOXDATA ptr -70h
.text:69E7EDE0 var_4 = dword ptr -4
.text:69E7EDE0 hwnd = dword ptr 8
.text:69E7EDE0 lptext = dword ptr 0Ch
.text:69E7EDE0 lpCaption = dword ptr 10h
.text:69E7EDE0 uType = dword ptr 14h
.text:69E7EDE0 wLanguageId = word ptr 18h
.text:69E7EDE0 dwMilliseconds = dword ptr 1Ch
.text:69E7EDE0
.text:69E7EDE0 mov edi, edi
.text:69E7EDE2 push ebp
.text:69E7EDE3 mov ebp, esp
.text:69E7EDE5 and esp, 0FFFFFFF8h
.text:69E7EDE8 sub esp, 74h
.text:69E7EDEB mov eax, ___security_cookie
.text:69E7EDF0 xor eax, esp
.text:69E7EDF2 mov [esp+74h+var_4], eax
.text:69E7EDF6 push ebx
.text:69E7EDF7 mov ebx, [ebp+lpCaption]
.text:69E7EDFA lea eax, [esp+78h+mbdata]
.text:69E7EDFE push esi
.text:69E7EDFF mov esi, [ebp+hwnd]
.text:69E7EE02 push edi ; struct _MSGBOXDATA *
.text:69E7EE03 mov edi, [ebp+lptext]
.text:69E7EE06 push 68h ; 'h' ; Size
.text:69E7EE08 push 0 ; Val
.text:69E7EE0A push eax ; Dst
.text:69E7EE0B call _memset
.text:69E7EE10 mov eax, [ebp+uType]
.text:69E7EE13 add esp, 0Ch
.text:69E7EE16 mov [esp+80h+mbdata.mbparams.dwStyle], eax
.text:69E7EE1A mov ax, [ebp+wLanguageId]
.text:69E7EE1E mov [esp+80h+mbdata.mbparams.hwndOwner], esi
.text:69E7EE22 xor esi, esi
.text:69E7EE24 mov [esp+80h+mbdata.wLanguageId], ax
.text:69E7EE29 mov eax, [ebp+dwMilliseconds]
.text:69E7EE2C mov [esp+80h+mbdata.mbparams.cbSize], 28h ; '('
.text:69E7EE34 mov [esp+80h+mbdata.mbparams.hInstance], esi
.text:69E7EE38 mov [esp+80h+mbdata.mbparams.lpszText], edi
.text:69E7EE3C mov [esp+80h+mbdata.mbparams.lpszCaption], ebx
.text:69E7EE40 mov [esp+80h+mbdata.dwMilliseconds], eax
.text:69E7EE44 cmp ?gfEMIEnable@@3HA, esi ; int gfEMIEnable
.text:69E7EE4A jz short loc_69E7EE6E
.text:69E7EE4C mov eax, large fs:18h
.text:69E7EE52 mov edx, offset ?gdwEMIThreadID@@3PAXA ; void * gdwEMIThreadID
.text:69E7EE57 mov ecx, [eax+24h]
.text:69E7EE5A xor eax, eax
.text:69E7EE5C lock cmpxchg [edx], ecx
.text:69E7EE60 test eax, eax
.text:69E7EE62 jnz short loc_69E7EE6E
.text:69E7EE64 mov ?gpReturnAddr@@3PAXA, 1 ; void * gpReturnAddr
.text:69E7EE6E
.text:69E7EE6E loc_69E7EE6E: ; CODE XREF: MessageBoxTimeoutW(x,x,x,x,x,x)+6A↑j
.text:69E7EE6E ; MessageBoxTimeoutW(x,x,x,x,x,x)+82↑j
.text:69E7EE6E cmp ?gfForcedDialogsDpiScaling@@3HA, esi ; int gfForcedDialogsDpiScaling
.text:69E7EE74 jnz loc_69E7EF65
.text:69E7EE7A push 12h
.text:69E7EE7C pop ebx
.text:69E7EE7D cmp _gfServerProcess, esi
.text:69E7EE83 jnz short loc_69E7EEE5
.text:69E7EE85 mov eax, large fs:18h
.text:69E7EE8B mov ecx, [eax+0FDCh]
.text:69E7EE91 test ecx, ecx
.text:69E7EE93 jns short loc_69E7EE97
.text:69E7EE95 add eax, ecx
.text:69E7EE97
.text:69E7EE97 loc_69E7EE97: ; CODE XREF: MessageBoxTimeoutW(x,x,x,x,x,x)+B3↑j
.text:69E7EE97 add eax, 800h
.text:69E7EE9C jnz short loc_69E7EEAA
.text:69E7EE9E push 0Eh
.text:69E7EEA0 call ds:__imp__NtUserGetThreadState@4 ; NtUserGetThreadState(x)
.text:69E7EEA6 test eax, eax
.text:69E7EEA8 jz short loc_69E7EEE5
.text:69E7EEAA
.text:69E7EEAA loc_69E7EEAA: ; CODE XREF: MessageBoxTimeoutW(x,x,x,x,x,x)+BC↑j
.text:69E7EEAA mov eax, large fs:18h
.text:69E7EEB0 mov ecx, [eax+0FDCh]
.text:69E7EEB6 test ecx, ecx
.text:69E7EEB8 jns short loc_69E7EEBC
.text:69E7EEBA add eax, ecx
.text:69E7EEBC
.text:69E7EEBC loc_69E7EEBC: ; CODE XREF: MessageBoxTimeoutW(x,x,x,x,x,x)+D8↑j
.text:69E7EEBC cmp [eax+8E8h], esi
.text:69E7EEC2 jnz short loc_69E7EECB
.text:69E7EEC4 mov eax, _gDefaultDpiContext
.text:69E7EEC9 jmp short loc_69E7EEE7
.text:69E7EECB ; ---------------------------------------------------------------------------
.text:69E7EECB
.text:69E7EECB loc_69E7EECB: ; CODE XREF: MessageBoxTimeoutW(x,x,x,x,x,x)+E2↑j
.text:69E7EECB mov eax, large fs:18h
.text:69E7EED1 mov ecx, [eax+0FDCh]
.text:69E7EED7 test ecx, ecx
.text:69E7EED9 jns short loc_69E7EEDD
.text:69E7EEDB add eax, ecx
.text:69E7EEDD
.text:69E7EEDD loc_69E7EEDD: ; CODE XREF: MessageBoxTimeoutW(x,x,x,x,x,x)+F9↑j
.text:69E7EEDD mov eax, [eax+8E8h]
.text:69E7EEE3 jmp short loc_69E7EEE7
.text:69E7EEE5 ; ---------------------------------------------------------------------------
.text:69E7EEE5
.text:69E7EEE5 loc_69E7EEE5: ; CODE XREF: MessageBoxTimeoutW(x,x,x,x,x,x)+A3↑j
.text:69E7EEE5 ; MessageBoxTimeoutW(x,x,x,x,x,x)+C8↑j
.text:69E7EEE5 mov eax, ebx
.text:69E7EEE7
.text:69E7EEE7 loc_69E7EEE7: ; CODE XREF: MessageBoxTimeoutW(x,x,x,x,x,x)+E9↑j
.text:69E7EEE7 ; MessageBoxTimeoutW(x,x,x,x,x,x)+103↑j
.text:69E7EEE7 and al, 0Fh
.text:69E7EEE9 cmp al, 2
.text:69E7EEEB jnz short loc_69E7EF5D
.text:69E7EEED cmp _gfServerProcess, esi
.text:69E7EEF3 jnz short loc_69E7EF55
.text:69E7EEF5 mov eax, large fs:18h
.text:69E7EEFB mov ecx, [eax+0FDCh]
.text:69E7EF01 test ecx, ecx
.text:69E7EF03 jns short loc_69E7EF07
.text:69E7EF05 add eax, ecx
.text:69E7EF07
.text:69E7EF07 loc_69E7EF07: ; CODE XREF: MessageBoxTimeoutW(x,x,x,x,x,x)+123↑j
.text:69E7EF07 add eax, 800h
.text:69E7EF0C jnz short loc_69E7EF1A
.text:69E7EF0E push 0Eh
.text:69E7EF10 call ds:__imp__NtUserGetThreadState@4 ; NtUserGetThreadState(x)
.text:69E7EF16 test eax, eax
.text:69E7EF18 jz short loc_69E7EF55
.text:69E7EF1A
.text:69E7EF1A loc_69E7EF1A: ; CODE XREF: MessageBoxTimeoutW(x,x,x,x,x,x)+12C↑j
.text:69E7EF1A mov eax, large fs:18h
.text:69E7EF20 mov ecx, [eax+0FDCh]
.text:69E7EF26 test ecx, ecx
.text:69E7EF28 jns short loc_69E7EF2C
.text:69E7EF2A add eax, ecx
.text:69E7EF2C
.text:69E7EF2C loc_69E7EF2C: ; CODE XREF: MessageBoxTimeoutW(x,x,x,x,x,x)+148↑j
.text:69E7EF2C cmp [eax+8E8h], esi
.text:69E7EF32 jnz short loc_69E7EF3C
.text:69E7EF34 mov ebx, _gDefaultDpiContext
.text:69E7EF3A jmp short loc_69E7EF55
.text:69E7EF3C ; ---------------------------------------------------------------------------
.text:69E7EF3C
.text:69E7EF3C loc_69E7EF3C: ; CODE XREF: MessageBoxTimeoutW(x,x,x,x,x,x)+152↑j
.text:69E7EF3C mov ebx, large fs:18h
.text:69E7EF43 mov eax, [ebx+0FDCh]
.text:69E7EF49 test eax, eax
.text:69E7EF4B jns short loc_69E7EF4F
.text:69E7EF4D add ebx, eax
.text:69E7EF4F
.text:69E7EF4F loc_69E7EF4F: ; CODE XREF: MessageBoxTimeoutW(x,x,x,x,x,x)+16B↑j
.text:69E7EF4F mov ebx, [ebx+8E8h]
.text:69E7EF55
.text:69E7EF55 loc_69E7EF55: ; CODE XREF: MessageBoxTimeoutW(x,x,x,x,x,x)+113↑j
.text:69E7EF55 ; MessageBoxTimeoutW(x,x,x,x,x,x)+138↑j ...
.text:69E7EF55 and bl, 0F0h
.text:69E7EF58 cmp bl, 20h ; ' '
.text:69E7EF5B jz short loc_69E7EF65
.text:69E7EF5D
.text:69E7EF5D loc_69E7EF5D: ; CODE XREF: MessageBoxTimeoutW(x,x,x,x,x,x)+10B↑j
.text:69E7EF5D cmp _gfServerProcess, esi
.text:69E7EF63 jz short loc_69E7EF6E
.text:69E7EF65
.text:69E7EF65 loc_69E7EF65: ; CODE XREF: MessageBoxTimeoutW(x,x,x,x,x,x)+94↑j
.text:69E7EF65 ; MessageBoxTimeoutW(x,x,x,x,x,x)+17B↑j
.text:69E7EF65 push 0FFFFFFFEh
.text:69E7EF67 call _SetThreadDpiAwarenessContext@4 ; SetThreadDpiAwarenessContext(x)
.text:69E7EF6C mov esi, eax
.text:69E7EF6E
.text:69E7EF6E loc_69E7EF6E: ; CODE XREF: MessageBoxTimeoutW(x,x,x,x,x,x)+183↑j
.text:69E7EF6E lea ecx, [esp+80h+mbdata] ; struct _MSGBOXDATA *
.text:69E7EF72 call ?MessageBoxWorker@@YGHPAU_MSGBOXDATA@@@Z ; MessageBoxWorker(_MSGBOXDATA *)
.text:69E7EF77 mov edi, eax
.text:69E7EF79 test esi, esi
.text:69E7EF7B jz short loc_69E7EF83
.text:69E7EF7D push esi
.text:69E7EF7E call _SetThreadDpiAwarenessContext@4 ; SetThreadDpiAwarenessContext(x)
.text:69E7EF83
.text:69E7EF83 loc_69E7EF83: ; CODE XREF: MessageBoxTimeoutW(x,x,x,x,x,x)+19B↑j
.text:69E7EF83 mov ecx, [esp+80h+var_4]
.text:69E7EF87 mov eax, edi
.text:69E7EF89 pop edi
.text:69E7EF8A pop esi
.text:69E7EF8B pop ebx
.text:69E7EF8C xor ecx, esp
.text:69E7EF8E call @__security_check_cookie@4 ; __security_check_cookie(x)
.text:69E7EF93 mov esp, ebp
.text:69E7EF95 pop ebp
.text:69E7EF96 retn 18h
.text:69E7EF96 _MessageBoxTimeoutW@24 endp
这个就是MessageBoxTimeoutW()的反汇编代码,分析拆分核心代码,基本都是检测当前线程状态的代码。核心代码只有两个部分:
- 69E7EDF7 ~ 69E7EE40。
- 69E7EF6E ~ 69E7EF72。
初始化MSGBOXDATA结构,赋值特定成员后,调用MessageBoxWorker()。
根据第一段代码我们可以更加完善MSGBOXDATA结构,如下:
typedef struct _MSGBOXDATA {MSGBOXPARAMSW mbparams;BYTE unknown[8];WORD wLanguageId;BYTE unknown1[22];DWORD dwMilliseconds;BYTE unknown2[28];
}MSGBOXDATA, *LPMSGBOXDATA;
细心的人一定发现了wLanguageId和mbparams.dwLanguageId这里有两个语言有关的字段。显然MessageBoxTimeout用的是前者。
第二段代码便直接将初始化后的代码给了MessageBoxWorker()调用。
编写测试代码并运行:
可以看到按钮文字发生了改变,3秒后消息盒子自动关闭。
2.2.3 MessageBoxWorker()
高长度注意!!
?MessageBoxWorker@@YGHPAU_MSGBOXDATA@@@Z proc near
.text:69E7E19D ; CODE XREF: MessageBoxIndirectA(x)+E6↓p
.text:69E7E19D ; MessageBoxIndirectW(x)+64↓p ...
.text:69E7E19D
.text:69E7E19D enCloseButtonFlag= dword ptr -140h
.text:69E7E19D dwButtonDef = dword ptr -13Ch
.text:69E7E19D index = dword ptr -138h
.text:69E7E19D dwButtonType = dword ptr -134h
.text:69E7E19D dwButtonSum = dword ptr -130h
.text:69E7E19D pvTemp = dword ptr -12Ch
.text:69E7E19D pdwButtonID = dword ptr -128h
.text:69E7E19D pszButtonTextTable= dword ptr -118h
.text:69E7E19D szButtonBuffer = word ptr -108h
.text:69E7E19D szCaptionBuffer = word ptr -88h
.text:69E7E19D dwCheckSum = dword ptr -4
.text:69E7E19D
.text:69E7E19D mov edi, edi
.text:69E7E19F push ebp
.text:69E7E1A0 mov ebp, esp
.text:69E7E1A2 sub esp, 144h
.text:69E7E1A8 mov eax, ___security_cookie
.text:69E7E1AD xor eax, ebp
.text:69E7E1AF mov [ebp+dwCheckSum], eax
.text:69E7E1B2 push ebx
.text:69E7E1B3 push esi ; unsigned int
.text:69E7E1B4 push edi ; unsigned int
.text:69E7E1B5 mov edi, ecx
.text:69E7E1B7 xor edx, edx
.text:69E7E1B9 mov ecx, large fs:18h
.text:69E7E1C0 mov [ebp+enCloseButtonFlag], edx
.text:69E7E1C6 mov ebx, [edi+_MSGBOXDATA.mbparams.dwStyle]
.text:69E7E1C9 mov eax, [ecx+0FDCh]
.text:69E7E1CF test eax, eax
.text:69E7E1D1 jns short loc_69E7E1D5
.text:69E7E1D3 add ecx, eax
.text:69E7E1D5
.text:69E7E1D5 loc_69E7E1D5: ; CODE XREF: MessageBoxWorker(_MSGBOXDATA *)+34↑j
.text:69E7E1D5 mov eax, [ecx+78h]
.text:69E7E1D8 or eax, [ecx+7Ch]
.text:69E7E1DB jnz short loc_69E7E1F2
.text:69E7E1DD push 0Eh
.text:69E7E1DF call ds:__imp__NtUserGetThreadState@4 ; NtUserGetThreadState(x)
.text:69E7E1E5 test eax, eax
.text:69E7E1E7 jnz short loc_69E7E1F0
.text:69E7E1E9
.text:69E7E1E9 loc_69E7E1E9: ; CODE XREF: MessageBoxWorker(_MSGBOXDATA *)+73↓j
.text:69E7E1E9 xor eax, eax
.text:69E7E1EB jmp loc_69E7E4F0
.text:69E7E1F0 ; ---------------------------------------------------------------------------
.text:69E7E1F0
.text:69E7E1F0 loc_69E7E1F0: ; CODE XREF: MessageBoxWorker(_MSGBOXDATA *)+4A↑j
.text:69E7E1F0 xor edx, edx
.text:69E7E1F2
.text:69E7E1F2 loc_69E7E1F2: ; CODE XREF: MessageBoxWorker(_MSGBOXDATA *)+3E↑j
.text:69E7E1F2 cmp [edi+_MSGBOXDATA.dwMilliseconds], edx
.text:69E7E1F5 jnz short loc_69E7E1FB
.text:69E7E1F7 or [edi+_MSGBOXDATA.dwMilliseconds], 0FFFFFFFFh
.text:69E7E1FB
.text:69E7E1FB loc_69E7E1FB: ; CODE XREF: MessageBoxWorker(_MSGBOXDATA *)+58↑j
.text:69E7E1FB mov esi, ebx
.text:69E7E1FD and esi, 0Fh
.text:69E7E200 cmp esi, 6
.text:69E7E203 jbe short loc_69E7E212
.text:69E7E205 push 59Eh ; LastError
.text:69E7E20A
.text:69E7E20A loc_69E7E20A: ; CODE XREF: MessageBoxWorker(_MSGBOXDATA *)+1B7↓j
.text:69E7E20A ; MessageBoxWorker(_MSGBOXDATA *)+1E8↓j
.text:69E7E20A call ds:__imp__RtlSetLastWin32Error@4 ; RtlSetLastWin32Error(x)
.text:69E7E210 jmp short loc_69E7E1E9
.text:69E7E212 ; ---------------------------------------------------------------------------
.text:69E7E212
.text:69E7E212 loc_69E7E212: ; CODE XREF: MessageBoxWorker(_MSGBOXDATA *)+66↑j
.text:69E7E212 movzx ecx, ds:?mpTypeCcmd@@3QBEB[esi] ; uchar const * const mpTypeCcmd
.text:69E7E219 mov eax, ebx
.text:69E7E21B shr eax, 0Eh
.text:69E7E21E and eax, 1
.text:69E7E221 add ecx, eax
.text:69E7E223 mov eax, ebx
.text:69E7E225 shr eax, 8
.text:69E7E228 and eax, 0Fh
.text:69E7E22B mov [ebp+dwButtonSum], ecx
.text:69E7E231 cmp eax, ecx
.text:69E7E233 sbb ecx, ecx
.text:69E7E235 and ecx, eax
.text:69E7E237 cmp ?gfEMIEnable@@3HA, 0 ; int gfEMIEnable
.text:69E7E23E mov [ebp+dwButtonDef], ecx
.text:69E7E244 jz short loc_69E7E255
.text:69E7E246 mov ecx, edi
.text:69E7E248 call ?ErrorMessageInst@@YGHPAU_MSGBOXDATA@@@Z ; ErrorMessageInst(_MSGBOXDATA *)
.text:69E7E24D mov ecx, [ebp+dwButtonDef]
.text:69E7E253 xor edx, edx
.text:69E7E255
.text:69E7E255 loc_69E7E255: ; CODE XREF: MessageBoxWorker(_MSGBOXDATA *)+A7↑j
.text:69E7E255 cmp ?gfDMREnable@@3HA, 0 ; int gfDMREnable
.text:69E7E25C jz short loc_69E7E280
.text:69E7E25E movzx eax, ds:?mpTypeIich@@3QBEB[esi] ; uchar const * const mpTypeIich
.text:69E7E265 add eax, ecx
.text:69E7E267 imul ecx, ds:?SEBbuttons@@3QBIB[eax*4], 28h ; uint const * const SEBbuttons
.text:69E7E26F mov eax, _gpsi
.text:69E7E274 mov eax, [ecx+eax+3C4h]
.text:69E7E27B jmp loc_69E7E4F0
.text:69E7E280 ; ---------------------------------------------------------------------------
.text:69E7E280
.text:69E7E280 loc_69E7E280: ; CODE XREF: MessageBoxWorker(_MSGBOXDATA *)+BF↑j
.text:69E7E280 mov eax, [edi+_MSGBOXDATA.mbparams.lpszCaption]
.text:69E7E283 test eax, eax
.text:69E7E285 jnz loc_69E7E30B
.text:69E7E28B cmp ?szERROR@@3PAGA, 0 ; ushort * szERROR
.text:69E7E293 mov eax, offset ?szERROR@@3PAGA ; ushort * szERROR
.text:69E7E298 mov [ebp+pvTemp], eax
.text:69E7E29E jnz short loc_69E7E2C2
.text:69E7E2A0 mov esi, ?pfnLoadStringBaseExW@@3P6GHPAUHINSTANCE__@@IPAGHG@ZA ; int (*pfnLoadStringBaseExW)(HINSTANCE__ *,uint,ushort *,int,ushort)
.text:69E7E2A6 mov ecx, esi
.text:69E7E2A8 push edx
.text:69E7E2A9 push 0Ah
.text:69E7E2AB push eax
.text:69E7E2AC push 2
.text:69E7E2AE push _hmodUser
.text:69E7E2B4 call ds:___guard_check_icall_fptr ; _guard_check_icall_nop(x)
.text:69E7E2BA call esi ; int (*pfnLoadStringBaseExW)(HINSTANCE__ *,uint,ushort *,int,ushort)
.text:69E7E2BC mov eax, [ebp+pvTemp]
.text:69E7E2C2
.text:69E7E2C2 loc_69E7E2C2: ; CODE XREF: MessageBoxWorker(_MSGBOXDATA *)+101↑j
.text:69E7E2C2 movzx ecx, [edi+_MSGBOXDATA.wLanguageId]
.text:69E7E2C6 test cx, cx
.text:69E7E2C9 jz short loc_69E7E308
.text:69E7E2CB mov esi, ?pfnLoadStringBaseExW@@3P6GHPAUHINSTANCE__@@IPAGHG@ZA ; int (*pfnLoadStringBaseExW)(HINSTANCE__ *,uint,ushort *,int,ushort)
.text:69E7E2D1 lea eax, [ebp+szCaptionBuffer]
.text:69E7E2D7 push ecx
.text:69E7E2D8 push 40h ; '@'
.text:69E7E2DA push eax
.text:69E7E2DB push 2
.text:69E7E2DD push _hmodUser
.text:69E7E2E3 mov ecx, esi
.text:69E7E2E5 call ds:___guard_check_icall_fptr ; _guard_check_icall_nop(x)
.text:69E7E2EB call esi ; int (*pfnLoadStringBaseExW)(HINSTANCE__ *,uint,ushort *,int,ushort)
.text:69E7E2ED cmp [ebp+szCaptionBuffer], 0
.text:69E7E2F5 jz short loc_69E7E302
.text:69E7E2F7 lea eax, [ebp+szCaptionBuffer]
.text:69E7E2FD mov [edi+_MSGBOXDATA.mbparams.lpszCaption], eax
.text:69E7E300 jmp short loc_69E7E30B
.text:69E7E302 ; ---------------------------------------------------------------------------
.text:69E7E302
.text:69E7E302 loc_69E7E302: ; CODE XREF: MessageBoxWorker(_MSGBOXDATA *)+158↑j
.text:69E7E302 mov eax, [ebp+pvTemp]
.text:69E7E308
.text:69E7E308 loc_69E7E308: ; CODE XREF: MessageBoxWorker(_MSGBOXDATA *)+12C↑j
.text:69E7E308 mov [edi+_MSGBOXDATA.mbparams.lpszCaption], eax
.text:69E7E30B
.text:69E7E30B loc_69E7E30B: ; CODE XREF: MessageBoxWorker(_MSGBOXDATA *)+E8↑j
.text:69E7E30B ; MessageBoxWorker(_MSGBOXDATA *)+163↑j
.text:69E7E30B test ebx, MB_TOPMOST
.text:69E7E311 jz short loc_69E7E343
.text:69E7E313 mov ecx, large fs:18h
.text:69E7E31A mov edx, [ecx+0FDCh]
.text:69E7E320 test edx, edx
.text:69E7E322 jns short loc_69E7E326
.text:69E7E324 add ecx, edx
.text:69E7E326
.text:69E7E326 loc_69E7E326: ; CODE XREF: MessageBoxWorker(_MSGBOXDATA *)+185↑j
.text:69E7E326 mov edx, 400h
.text:69E7E32B cmp [ecx+810h], dx
.text:69E7E332 jnb short loc_69E7E343
.text:69E7E334 and ebx, 0FFFBFFFFh
.text:69E7E33A or ebx, MB_SERVICE_NOTIFICATION
.text:69E7E340 mov [edi+_MSGBOXDATA.mbparams.dwStyle], ebx
.text:69E7E343
.text:69E7E343 loc_69E7E343: ; CODE XREF: MessageBoxWorker(_MSGBOXDATA *)+174↑j
.text:69E7E343 ; MessageBoxWorker(_MSGBOXDATA *)+195↑j
.text:69E7E343 mov ecx, [edi+_MSGBOXDATA.mbparams.hwndOwner]
.text:69E7E346 test ebx, 220000h
.text:69E7E34C jz short loc_69E7E372
.text:69E7E34E test ecx, ecx
.text:69E7E350 jz short loc_69E7E359
.text:69E7E352 push 57h ; 'W'
.text:69E7E354 jmp loc_69E7E20A
.text:69E7E359 ; ---------------------------------------------------------------------------
.text:69E7E359
.text:69E7E359 loc_69E7E359: ; CODE XREF: MessageBoxWorker(_MSGBOXDATA *)+1B3↑j
.text:69E7E359 push [edi+_MSGBOXDATA.dwMilliseconds] ; dwStyle
.text:69E7E35C mov ecx, [edi+_MSGBOXDATA.mbparams.lpszText]
.text:69E7E35F and ebx, 0FFDFFFFFh
.text:69E7E365 push ebx ; dwMilliseconds
.text:69E7E366 mov edx, eax
.text:69E7E368 call ?ServiceMessageBox@@YGHPBG0IK@Z ; ServiceMessageBox(ushort const *,ushort const *,uint,ulong)
.text:69E7E36D jmp loc_69E7E4F0
.text:69E7E372 ; ---------------------------------------------------------------------------
.text:69E7E372
.text:69E7E372 loc_69E7E372: ; CODE XREF: MessageBoxWorker(_MSGBOXDATA *)+1AF↑j
.text:69E7E372 test ecx, ecx
.text:69E7E374 jz short loc_69E7E38A
.text:69E7E376 push ecx ; hWnd
.text:69E7E377 call _IsWindow@4 ; IsWindow(x)
.text:69E7E37C test eax, eax
.text:69E7E37E jnz short loc_69E7E38A
.text:69E7E380 push 578h
.text:69E7E385 jmp loc_69E7E20A
.text:69E7E38A ; ---------------------------------------------------------------------------
.text:69E7E38A
.text:69E7E38A loc_69E7E38A: ; CODE XREF: MessageBoxWorker(_MSGBOXDATA *)+1D7↑j
.text:69E7E38A ; MessageBoxWorker(_MSGBOXDATA *)+1E1↑j
.text:69E7E38A and [ebp+index], 0
.text:69E7E391 and ebx, 0Fh
.text:69E7E394 mov esi, [ebp+dwButtonSum]
.text:69E7E39A mov [ebp+dwButtonType], ebx
.text:69E7E3A0 movzx eax, ds:?mpTypeIich@@3QBEB[ebx] ; uchar const * const mpTypeIich
.text:69E7E3A7 test esi, esi
.text:69E7E3A9 jz loc_69E7E46A
.text:69E7E3AF lea edx, ?SEBbuttons@@3QBIB[eax*4] ; uint const * const SEBbuttons
.text:69E7E3B6 mov [ebp+pvTemp], edx
.text:69E7E3BC
.text:69E7E3BC loc_69E7E3BC: ; CODE XREF: MessageBoxWorker(_MSGBOXDATA *)+2C1↓j
.text:69E7E3BC imul ebx, [edx], 28h ; '('
.text:69E7E3BF movzx eax, [edi+_MSGBOXDATA.wLanguageId]
.text:69E7E3C3 add ebx, _gpsi
.text:69E7E3C9 test ax, ax
.text:69E7E3CC jnz short loc_69E7E3D6
.text:69E7E3CE lea eax, [ebx+3A4h]
.text:69E7E3D4 jmp short loc_69E7E423
.text:69E7E3D6 ; ---------------------------------------------------------------------------
.text:69E7E3D6
.text:69E7E3D6 loc_69E7E3D6: ; CODE XREF: MessageBoxWorker(_MSGBOXDATA *)+22F↑j
.text:69E7E3D6 mov esi, ?pfnLoadStringBaseExW@@3P6GHPAUHINSTANCE__@@IPAGHG@ZA ; int (*pfnLoadStringBaseExW)(HINSTANCE__ *,uint,ushort *,int,ushort)
.text:69E7E3DC mov ecx, esi
.text:69E7E3DE push eax
.text:69E7E3DF push 40h ; '@'
.text:69E7E3E1 lea eax, [ebp+szButtonBuffer]
.text:69E7E3E7 push eax
.text:69E7E3E8 push dword ptr [ebx+3C8h]
.text:69E7E3EE push _hmodUser
.text:69E7E3F4 call ds:___guard_check_icall_fptr ; _guard_check_icall_nop(x)
.text:69E7E3FA call esi ; int (*pfnLoadStringBaseExW)(HINSTANCE__ *,uint,ushort *,int,ushort)
.text:69E7E3FC cmp [ebp+szButtonBuffer], 0
.text:69E7E404 lea ecx, [ebp+szButtonBuffer]
.text:69E7E40A jnz short loc_69E7E412
.text:69E7E40C lea ecx, [ebx+3A4h] ; Src
.text:69E7E412
.text:69E7E412 loc_69E7E412: ; CODE XREF: MessageBoxWorker(_MSGBOXDATA *)+26D↑j
.text:69E7E412 call _TextAlloc@4 ; TextAlloc(x)
.text:69E7E417 mov edx, [ebp+pvTemp]
.text:69E7E41D mov esi, [ebp+dwButtonSum]
.text:69E7E423
.text:69E7E423 loc_69E7E423: ; CODE XREF: MessageBoxWorker(_MSGBOXDATA *)+237↑j
.text:69E7E423 mov ecx, [ebp+index]
.text:69E7E429 mov [ebp+ecx*4+pszButtonTextTable], eax
.text:69E7E430 mov eax, [ebx+3C4h]
.text:69E7E436 mov [ebp+ecx*4+pdwButtonID], eax
.text:69E7E43D cmp eax, 2
.text:69E7E440 jnz short loc_69E7E44C
.text:69E7E442 mov [ebp+enCloseButtonFlag], 1
.text:69E7E44C
.text:69E7E44C loc_69E7E44C: ; CODE XREF: MessageBoxWorker(_MSGBOXDATA *)+2A3↑j
.text:69E7E44C inc ecx
.text:69E7E44D add edx, 4
.text:69E7E450 mov [ebp+index], ecx
.text:69E7E456 mov [ebp+pvTemp], edx
.text:69E7E45C cmp ecx, esi
.text:69E7E45E jb loc_69E7E3BC
.text:69E7E464 mov ebx, [ebp+dwButtonType]
.text:69E7E46A
.text:69E7E46A loc_69E7E46A: ; CODE XREF: MessageBoxWorker(_MSGBOXDATA *)+20C↑j
.text:69E7E46A push 0
.text:69E7E46C push 1
.text:69E7E46E call ds:__imp__NtUserModifyUserStartupInfoFlags@8 ; NtUserModifyUserStartupInfoFlags(x,x)
.text:69E7E474 mov [edi+_MSGBOXDATA.dwButtonSum], esi
.text:69E7E477 lea eax, [ebp+pdwButtonID]
.text:69E7E47D mov [edi+_MSGBOXDATA.pdwButtonID], eax
.text:69E7E480 lea eax, [ebp+pszButtonTextTable]
.text:69E7E486 mov [edi+_MSGBOXDATA.pszButtonTextTable], eax
.text:69E7E489 mov eax, [ebp+dwButtonDef]
.text:69E7E48F mov [edi+_MSGBOXDATA.dwButtonDef], eax
.text:69E7E492 test ebx, ebx
.text:69E7E494 jnz short loc_69E7E49B
.text:69E7E496 xor eax, eax
.text:69E7E498 inc eax
.text:69E7E499 jmp short loc_69E7E4A8
.text:69E7E49B ; ---------------------------------------------------------------------------
.text:69E7E49B
.text:69E7E49B loc_69E7E49B: ; CODE XREF: MessageBoxWorker(_MSGBOXDATA *)+2F7↑j
.text:69E7E49B mov eax, [ebp+enCloseButtonFlag]
.text:69E7E4A1 neg eax
.text:69E7E4A3 sbb eax, eax
.text:69E7E4A5 and eax, 2
.text:69E7E4A8
.text:69E7E4A8 loc_69E7E4A8: ; CODE XREF: MessageBoxWorker(_MSGBOXDATA *)+2FC↑j
.text:69E7E4A8 push edi
.text:69E7E4A9 mov [edi+_MSGBOXDATA.enCloseButtonFlag], eax
.text:69E7E4AC call _SoftModalMessageBox@4 ; SoftModalMessageBox(x)
.text:69E7E4B1 mov ebx, eax
.text:69E7E4B3 xor eax, eax
.text:69E7E4B5 mov [ebp+dwButtonType], ebx
.text:69E7E4BB cmp [edi+_MSGBOXDATA.wLanguageId], ax
.text:69E7E4BF jz short loc_69E7E4EE
.text:69E7E4C1 mov edi, [ebp+dwButtonSum]
.text:69E7E4C7 mov esi, eax
.text:69E7E4C9 test edi, edi
.text:69E7E4CB jz short loc_69E7E4EE
.text:69E7E4CD xor ebx, ebx
.text:69E7E4CF
.text:69E7E4CF loc_69E7E4CF: ; CODE XREF: MessageBoxWorker(_MSGBOXDATA *)+349↓j
.text:69E7E4CF push [ebp+esi*4+pszButtonTextTable] ; P
.text:69E7E4D6 push ebx ; Flags
.text:69E7E4D7 push _pUserHeap ; HeapHandle
.text:69E7E4DD call ds:__imp__RtlFreeHeap@12 ; RtlFreeHeap(x,x,x)
.text:69E7E4E3 inc esi
.text:69E7E4E4 cmp esi, edi
.text:69E7E4E6 jb short loc_69E7E4CF
.text:69E7E4E8 mov ebx, [ebp+dwButtonType]
.text:69E7E4EE
.text:69E7E4EE loc_69E7E4EE: ; CODE XREF: MessageBoxWorker(_MSGBOXDATA *)+322↑j
.text:69E7E4EE ; MessageBoxWorker(_MSGBOXDATA *)+32E↑j
.text:69E7E4EE mov eax, ebx
.text:69E7E4F0
.text:69E7E4F0 loc_69E7E4F0: ; CODE XREF: MessageBoxWorker(_MSGBOXDATA *)+4E↑j
.text:69E7E4F0 ; MessageBoxWorker(_MSGBOXDATA *)+DE↑j ...
.text:69E7E4F0 mov ecx, [ebp+dwCheckSum]
.text:69E7E4F3 pop edi
.text:69E7E4F4 pop esi
.text:69E7E4F5 xor ecx, ebp
.text:69E7E4F7 pop ebx
.text:69E7E4F8 call @__security_check_cookie@4 ; __security_check_cookie(x)
.text:69E7E4FD leave
.text:69E7E4FE retn
.text:69E7E4FE ?MessageBoxWorker@@YGHPAU_MSGBOXDATA@@@Z endp
MessageBoxWorker()是MesageBox系列的第一个分水岭。从这里开始确确实实的对MessaegBox的窗口进行了初步的构建。下面我将一步步分析这个函数里的核心代码。
核心代码A:69E7E1B7~69E7E1C6
- 初始化局部变量enCloseButtonFlag为0。
- 将MSGBOXDATA.mbparams.dwStyle的值给寄存器ebx。
核心代码B:69E7E1F0~69E7E203
- 如果dwMilliseconds为0则改为-1。
- 判断dwStyle低4位是否小于等于6,小于则正常执行。
在当前版本的系统ButtonType一共只有7种。
核心代码C:69E7E212~69E7E244
- 全局数组mpTypeCcmd存放的是各ButtonType的按钮数。
- dwStyle右移14位判断是否具有MB_HELP标志,如果有按钮数量+1。
- dwStyle右移8位低4位具有默认(输入焦点)按钮的值。
- 将按钮数量和默认按钮存入全局变量。
核心代码D:69E7E280~69E7E308
- 判断MSGBOXDATA.mbparams.lpszCaption是否为空指针。
- 如果是则通过LoadStringBaseExW()函数,获取一个标题字符串与MSGBOXDATA.wLanguageId对应的“错误”字符串。
核心代码E:69E7E30B~69E7E350
- 判断dwStyle是否具有MB_TOPMOST。
- 如果有则改为MB_SERVICE_NOTIFICATION。
- 判断是否具有MB_SERVICE_NOTIFICATION或者MB_DEFAULT_DESKTOP_ONLY标志。
- 有则执行ServiceMessageBox,无则继续。
核心代码F:69E7E352~69E7E368
- 调用ServiceMessageBox()。
核心代码G:69E7E372~69E7E45E
- 判断MSGBOXDATA.mbparams.hwndOwner是否为空或者为一个窗口。是则继续否则结束。
- mpTypeIich是按钮ID数组的索引数组。
- SEBbuttons是按钮ID数组。
- 按钮循环:根据MSGBOXDATA.wLanguageId获取每个按钮的字符串以及每个按钮的ID分别存入局部数组中。
核心代码H:69E7E46A~69E7E4AC
- 将MSGBOXDATA的某些字段赋值。
- 获取关闭按钮状态。
- 调用SoftModalMessageBox()。
以上就是MessageBoxWorker()核心部分的分析。我们可以进一步完善MSGBOXDATA结构如下:
enum close_button_flag {button_gray, //关闭按钮灰键button_enable_ID1, //关闭按钮不灰键button_enable_ID2 //关闭按钮不灰键MB_OK
};typedef struct _MSGBOXDATA {MSGBOXPARAMSW mbparams;BYTE unknown[8];WORD wLanguageId; //MessageBox显示语言BYTE unknown1[2]; //姑且不明,大概率只是对齐PDWORD pdwButtonID; //按钮ID数组的指针,按钮ID同MessageBox返回值。(ID_HELP是9)LPCWSTR *pszButtonTextTable; //按钮字符串数组的指针。DWORD dwButtonSum; //按钮的数量DWORD dwButtonDef; //默认按钮close_button_flag enCloseButtonFlag; //关闭按钮状态,其实我觉得应该是bool类型才对DWORD dwMilliseconds; //窗口等待时间BYTE unknown2[28]; //仍然不明
}MSGBOXDATA, *LPMSGBOXDATA;
其中ServiceMessageBox()的函数声明如下:
typedef int(_fastcall *MSGSERVICEPROC)(LPCWSTR,LPCWSTR,UINT,DWORD);
参数1:输出字符串。
参数2:标题字符串。
参数3:消息盒子风格。
参数4:窗口等待时间。
其中SoftModalMessageBox()的函数声明如下:
typedef int(_stdcall *MSGSOFTPROC)(LPMSGBOXDATA);
测试代码执行结果如下:
SoftModalMessageBox():
按钮正常显示五个自定义文字的按钮,帮助按钮正常回调。ServiceMessageBox():
消息窗口在锁屏界面依然正常显示。
0x03 总结
以上就是第二部分的全部内容了,看到这里我相信各位已经能够明白为什么MSGBOXPARAMS的dwLanguageId没有效果了。同时我们对于MSGBOXDATA有了更加进一步的了解。第三部分我将继续讲述ServiceMessageBox()和SoftModalMessageBox()的相关内容。各位请多多期待哦。
!!刚刚开始发布文章,有很多不清楚的地方,如果有什么不对或者违反规定的地方,请第一时间联系作者哦。
【WINAPI】MessageBox细解(二)相关推荐
- Silverlight实用窍门系列:35.细解Silverlight冒泡路由事件和注册冒泡路由事件【附带实例源码】...
Silverlight中的事件分为普通事件和冒泡路由事件,它并没有包括WPF中的隧道路由事件,在本章中将详细讲解冒泡路由事件和如何注册一个冒泡路由事件. 一.细解冒泡路由事件 冒泡路由事件可以比喻为: ...
- Win32开发之Format MessageBox 详解
本文介绍在Windows程序开发中的MessageBox详解. 我们在在Windows程序设计中经常会涉及到一个格式化消息框,其代码如下: #include <windows.h> # ...
- PopUpWindow使用详解(二)——进阶及答疑
相关文章: 1.<PopUpWindow使用详解(一)--基本使用> 2.<PopUpWindow使用详解(二)--进阶及答疑> 上篇为大家基本讲述了有关PopupWindow ...
- HijackThis日志细解【简明教程增强版】(一)
转的贴(偶是怕以后看不到了,所以保存下来的),原文章(By 风之咏者)地址:http://bbs.kingsoft.com/viewthread.php?tid=407983&sid=8miH ...
- HijackThis日志细解--清净网络(复杂详尽)
一.说在前面的提示(请原谅我啰嗦) 提示一:本文目的 本文的目的是帮助您进一步解读HijackThis扫描日志.如果您只是想知道HijackThis的使用方法,下面列出的2篇文章可以满足您的要求: 1 ...
- 揪出狐狸的尾巴,HijackThis日志细解【附反劫持一般建议】
HijackThis日志细解[附反劫持一般建议] 一.说在前面的提示(请原谅我啰嗦) 提示一:本文目的 本文的目的是帮助您进一步解读HijackThis扫描日志.如果您只是想知道HijackThis的 ...
- Android系统分区理解及目录细解
Android系统分区 分区种类 Android 通常有以下分区: System分区: 就是我们刷ROM的分区 Data分区: 分区就是我们装APK的分区 Catch分区:是缓存分区 SDCard ...
- 安卓 linux init.rc,[原创]Android init.rc文件解析过程详解(二)
Android init.rc文件解析过程详解(二) 3.parse_new_section代码如下: void parse_new_section(struct parse_state *state ...
- [转]文件IO详解(二)---文件描述符(fd)和inode号的关系
原文:https://www.cnblogs.com/frank-yxs/p/5925563.html 文件IO详解(二)---文件描述符(fd)和inode号的关系 ---------------- ...
最新文章
- 不用软件,对回收站删除文件后的恢复(windows 高级技巧)
- DRDB的安装配置与使用(第二版)
- HttpServlet类简介和简单用法
- 移动网页如何实现发送短信和拨打电话的功能
- 计算机管理没有打印机列队,在Windows清除打印队列如果打印机被卡住,也没有打印输出...
- 【C语言】又是排序(指针专题)
- Linux内存管理--基本概念【转】
- android 辐射动画_Android 四种动画效果的调用实现代码
- 笔记系列------sqlloader的使用
- 源支付5.18源码/三网免挂/带云端/附源码搭建教程
- Kaggle教程 机器学习中级4 Pipeline
- 开闭原则、迪米特法则、合成复用原则
- 今天开始正式认认真真学习Python,以上!
- 键盘事件keydown、keypress、keyup随笔整理总结
- UIQ 3 概念认识
- 【MQTT从入门到提高系列 | 01】从0到1快速搭建MQTT测试环境
- Fireeye前副总裁卜峥 :不知攻焉知防,打造“3C的安全体系结构”
- LTC流程概述与核心要点--华为LTC流程专家许浩明老师分享心得体会
- 就靠这一篇文章,我就弄懂了 Python Django 的 django-admin 命令行工具集
- ?xml version=1.0 encoding=utf-8?appcommand time=1494385110doa
热门文章
- 基于51单片机的全自动洗衣机控制系统仿真设计
- EOS Contract 合约
- Vijos 雷曼兔(csapc)
- 看大佬的时时AI抠图项目
- 读《DeepChannel: Salience Estimation by Contrastive Learning for Extractive Document Summarization》
- mesos+marathon+docker
- threejs gltf 修改materail材质颜色与贴图 贴图不生效
- 一周热图|进博会展馆异彩纷呈;易烊千玺代言欧乐-B;宋祖儿张雪迎助阵声光展...
- CCCCCCCCCCCCCCCCCC
- matlab中利用xy求取多项式z,将(x y z)^10展开为多项式,经过合并同类项