【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 运行结果

  1. MessageBoxTimeoutW:
  2. MessageBoxWorker:
    可以看到两个函数都可以正常执行。MessageBoxWorker()有两个更改按钮语言的语句,其中有一个是无效的。无效的原因在本文其实已经能够看到,但请允许我留到最后一篇再去说明。

0x02 函数细解

2.1 前篇回顾

MessageBox细解(一)中我们介绍了三个微软公开的主要创建消息盒子的函数。分别是:

  1. MessageBox()
  2. MessageBoxEx()
  3. 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()的反汇编代码,分析拆分核心代码,基本都是检测当前线程状态的代码。核心代码只有两个部分:

  1. 69E7EDF7 ~ 69E7EE40。
  2. 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

  1. 初始化局部变量enCloseButtonFlag为0。
  2. 将MSGBOXDATA.mbparams.dwStyle的值给寄存器ebx。

核心代码B:69E7E1F0~69E7E203

  1. 如果dwMilliseconds为0则改为-1。
  2. 判断dwStyle低4位是否小于等于6,小于则正常执行。

在当前版本的系统ButtonType一共只有7种。

核心代码C:69E7E212~69E7E244

  1. 全局数组mpTypeCcmd存放的是各ButtonType的按钮数。
  2. dwStyle右移14位判断是否具有MB_HELP标志,如果有按钮数量+1。
  3. dwStyle右移8位低4位具有默认(输入焦点)按钮的值。
  4. 将按钮数量和默认按钮存入全局变量。

核心代码D:69E7E280~69E7E308

  1. 判断MSGBOXDATA.mbparams.lpszCaption是否为空指针。
  2. 如果是则通过LoadStringBaseExW()函数,获取一个标题字符串与MSGBOXDATA.wLanguageId对应的“错误”字符串。

核心代码E:69E7E30B~69E7E350

  1. 判断dwStyle是否具有MB_TOPMOST。
  2. 如果有则改为MB_SERVICE_NOTIFICATION。
  3. 判断是否具有MB_SERVICE_NOTIFICATION或者MB_DEFAULT_DESKTOP_ONLY标志。
  4. 有则执行ServiceMessageBox,无则继续。

核心代码F:69E7E352~69E7E368

  1. 调用ServiceMessageBox()。

核心代码G:69E7E372~69E7E45E

  1. 判断MSGBOXDATA.mbparams.hwndOwner是否为空或者为一个窗口。是则继续否则结束。
  2. mpTypeIich是按钮ID数组的索引数组。
  3. SEBbuttons是按钮ID数组。
  4. 按钮循环:根据MSGBOXDATA.wLanguageId获取每个按钮的字符串以及每个按钮的ID分别存入局部数组中。

核心代码H:69E7E46A~69E7E4AC

  1. 将MSGBOXDATA的某些字段赋值。
  2. 获取关闭按钮状态。
  3. 调用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);

测试代码执行结果如下:

  1. SoftModalMessageBox():

    按钮正常显示五个自定义文字的按钮,帮助按钮正常回调。

  2. ServiceMessageBox():

    消息窗口在锁屏界面依然正常显示。

0x03 总结

以上就是第二部分的全部内容了,看到这里我相信各位已经能够明白为什么MSGBOXPARAMS的dwLanguageId没有效果了。同时我们对于MSGBOXDATA有了更加进一步的了解。第三部分我将继续讲述ServiceMessageBox()和SoftModalMessageBox()的相关内容。各位请多多期待哦。

!!刚刚开始发布文章,有很多不清楚的地方,如果有什么不对或者违反规定的地方,请第一时间联系作者哦。

【WINAPI】MessageBox细解(二)相关推荐

  1. Silverlight实用窍门系列:35.细解Silverlight冒泡路由事件和注册冒泡路由事件【附带实例源码】...

    Silverlight中的事件分为普通事件和冒泡路由事件,它并没有包括WPF中的隧道路由事件,在本章中将详细讲解冒泡路由事件和如何注册一个冒泡路由事件. 一.细解冒泡路由事件 冒泡路由事件可以比喻为: ...

  2. Win32开发之Format MessageBox 详解

    本文介绍在Windows程序开发中的MessageBox详解.   我们在在Windows程序设计中经常会涉及到一个格式化消息框,其代码如下: #include <windows.h> # ...

  3. PopUpWindow使用详解(二)——进阶及答疑

    相关文章: 1.<PopUpWindow使用详解(一)--基本使用> 2.<PopUpWindow使用详解(二)--进阶及答疑> 上篇为大家基本讲述了有关PopupWindow ...

  4. HijackThis日志细解【简明教程增强版】(一)

    转的贴(偶是怕以后看不到了,所以保存下来的),原文章(By 风之咏者)地址:http://bbs.kingsoft.com/viewthread.php?tid=407983&sid=8miH ...

  5. HijackThis日志细解--清净网络(复杂详尽)

    一.说在前面的提示(请原谅我啰嗦) 提示一:本文目的 本文的目的是帮助您进一步解读HijackThis扫描日志.如果您只是想知道HijackThis的使用方法,下面列出的2篇文章可以满足您的要求: 1 ...

  6. 揪出狐狸的尾巴,HijackThis日志细解【附反劫持一般建议】

    HijackThis日志细解[附反劫持一般建议] 一.说在前面的提示(请原谅我啰嗦) 提示一:本文目的 本文的目的是帮助您进一步解读HijackThis扫描日志.如果您只是想知道HijackThis的 ...

  7. Android系统分区理解及目录细解

    Android系统分区 分区种类 Android 通常有以下分区: System分区: 就是我们刷ROM的分区 Data分区:   分区就是我们装APK的分区 Catch分区:是缓存分区 SDCard ...

  8. 安卓 linux init.rc,[原创]Android init.rc文件解析过程详解(二)

    Android init.rc文件解析过程详解(二) 3.parse_new_section代码如下: void parse_new_section(struct parse_state *state ...

  9. [转]文件IO详解(二)---文件描述符(fd)和inode号的关系

    原文:https://www.cnblogs.com/frank-yxs/p/5925563.html 文件IO详解(二)---文件描述符(fd)和inode号的关系 ---------------- ...

最新文章

  1. 不用软件,对回收站删除文件后的恢复(windows 高级技巧)
  2. DRDB的安装配置与使用(第二版)
  3. HttpServlet类简介和简单用法
  4. 移动网页如何实现发送短信和拨打电话的功能
  5. 计算机管理没有打印机列队,在Windows清除打印队列如果打印机被卡住,也没有打印输出...
  6. 【C语言】又是排序(指针专题)
  7. Linux内存管理--基本概念【转】
  8. android 辐射动画_Android 四种动画效果的调用实现代码
  9. 笔记系列------sqlloader的使用
  10. 源支付5.18源码/三网免挂/带云端/附源码搭建教程
  11. Kaggle教程 机器学习中级4 Pipeline
  12. 开闭原则、迪米特法则、合成复用原则
  13. 今天开始正式认认真真学习Python,以上!
  14. 键盘事件keydown、keypress、keyup随笔整理总结
  15. UIQ 3 概念认识
  16. 【MQTT从入门到提高系列 | 01】从0到1快速搭建MQTT测试环境
  17. Fireeye前副总裁卜峥 :不知攻焉知防,打造“3C的安全体系结构”
  18. LTC流程概述与核心要点--华为LTC流程专家许浩明老师分享心得体会
  19. 就靠这一篇文章,我就弄懂了 Python Django 的 django-admin 命令行工具集
  20. ?xml version=1.0 encoding=utf-8?appcommand time=1494385110doa

热门文章

  1. 基于51单片机的全自动洗衣机控制系统仿真设计
  2. EOS Contract 合约
  3. Vijos 雷曼兔(csapc)
  4. 看大佬的时时AI抠图项目
  5. 读《DeepChannel: Salience Estimation by Contrastive Learning for Extractive Document Summarization》
  6. mesos+marathon+docker
  7. threejs gltf 修改materail材质颜色与贴图 贴图不生效
  8. 一周热图|进博会展馆异彩纷呈;易烊千玺代言欧乐-B;宋祖儿张雪迎助阵声光展...
  9. CCCCCCCCCCCCCCCCCC
  10. matlab中利用xy求取多项式z,将(x y z)^10展开为多项式,经过合并同类项