;额外的说明,如果要在连接的时候加入一个资源选项,这个资源选项是一个xml文件,功能是在windows 7中以管理员运行,MessageBox可能会运行不会失败,但就是弹不出消息框,可能是我的xml文件写错了。
.386
.model flat,stdcall
option casemap:none
include windows.inc
include kernel32.inc
includelib kernel32.lib
include user32.inc
includelib user32.lib
.code
szSoftModalMessageBox db "SoftModalMessageBox",0
szMessageBoxIndirect db "MessageBoxIndirectA",0
szMessageBoxTimeoutA db "MessageBoxTimeoutA",0
szMessageBoxExA db "MessageBoxExA",0
szuser32 db "user32.dll",0
huser32 dd 0
pMessageBoxExA dd 0
pMessageBoxTimeoutA dd 0
pMessageBoxIndirect dd 0
szcaption db "made by correy",0
sztext db "http://correy.webs.com",0
my_MSGBOXPARAMSA dd 40,0,0,offset sztext,offset szcaption,0,0,0,0,0
msgboxProc proc lparam:LPARAM
invoke MessageBox,0,0,0,MB_TOPMOST ;好像必须加MB_TOPMOST才能显示在csrss.exe进程中。
ret ;另一种办法是在uType参数中加入MB_SERVICE_NOTIFICATION属性。
msgboxProc endp
u_correy dw 'c','o','r','r','e','y',0
MSGBOXDATA struct ;其实SoftModalMessageBox和MessageBoxIndirect一样简单,就是填充好一个结构。为了省事,我不在自己写例子了。
params MSGBOXPARAMS <>
pwndOwner DWORD ?
wLanguageId DWORD ?
pidButton DWORD ? ; // Array of button IDs
ppszButtonText DWORD ? ; // Array of button text strings
cButtons DWORD ?
DefButton DWORD ?
CancelId DWORD ?
Timeout DWORD ?
MSGBOXDATA ends
num equ 10
CallProc proc uses ebx lparam:LPARAM
local mbd:MSGBOXDATA
local bufid[num]:DWORD
local bufstr[num]:DWORD
lea eax,bufid
lea edx,bufstr
xor ecx,ecx
.while ecx!=num
mov ebx,ecx
inc ebx
mov dword ptr[eax+4*ecx],ebx
mov dword ptr[edx+4*ecx],offset u_correy
inc ecx
inc ebx
.endw
mov mbd.params.cbSize,sizeof MSGBOXPARAMS
mov mbd.params.hwndOwner,0
mov mbd.params.lpszText,offset u_correy
mov mbd.params.lpszCaption,offset u_correy
mov mbd.params.dwStyle,MB_ICONQUESTION or MB_SERVICE_NOTIFICATION or MB_TOPMOST or MB_DEFAULT_DESKTOP_ONLY ; or MB_RIGHT
mov mbd.pwndOwner,0
mov mbd.wLanguageId,0
mov mbd.pidButton,eax
mov mbd.ppszButtonText,edx
mov mbd.cButtons,num
mov mbd.DefButton,4
mov mbd.CancelId,0
mov mbd.Timeout,-1
lea eax,mbd
push eax
call lparam ;这其实是正规调用方式的一种变形。
ret
CallProc endp
start:
invoke LoadLibrary,addr szuser32
mov huser32,eax
invoke GetProcAddress,huser32,addr szMessageBoxExA
mov pMessageBoxExA,eax
push 0 ;句柄
push 0
push 0
push 0
push 0
call MessageBoxExA
invoke GetProcAddress,huser32,addr szMessageBoxTimeoutA
mov pMessageBoxTimeoutA,eax
push 3000 ;时间,-1是无限。
push 0 ;句柄
push 0
push 0
push 0
push 0
call pMessageBoxTimeoutA
invoke GetProcAddress,huser32,addr szMessageBoxIndirect
mov pMessageBoxIndirect,eax
push offset my_MSGBOXPARAMSA
call pMessageBoxIndirect ;其实这个变量可以省略。
invoke CreateThread,0,0,offset msgboxProc,0,0,0
invoke CloseHandle,eax
invoke GetProcAddress,huser32,addr szSoftModalMessageBox
;push 0 ;SoftModalMessageBox是有一个参数的。是一个结构的地址。
;call eax ;下面的c++代码是正规的,规范的调用方式。
invoke CallProc,eax
exit:invoke ExitProcess,0
end start
;made at 2011.08.10
;一下代码是c/c++的。
mov eax,11d0
mov edx,7ffeo300
call ntdll.kifastSystemCall
;;;;;;;;;;;;;;;;;;;;;;;;;;
void CMessageBoxesDlg::DoSoftModalMessageBox (DWORD dwFlags)
{
struct MSGBOXDATA
{
MSGBOXPARAMS mbp;
DWORD hwndOwner;
DWORD wLanguageId;
DWORD pidButton;
DWORD ppszButtonText;
DWORD dwButtons;
DWORD dwDefButton;
DWORD dwCancelId;
DWORD dwTimeout;
};
MSGBOXDATA data = {};
data.mbp.cbSize = sizeof (MSGBOXPARAMS);
data.mbp.hInstance = AfxGetInstanceHandle ();
data.mbp.lpszText = MAKEINTRESOURCE (IDS_SOFTMADALMESSAGEBOXTEXT);
data.mbp.lpszCaption = m_caption;
data.mbp.lpfnMsgBoxCallback = SoftModalMessageBoxCallback;
data.mbp.dwStyle = dwFlags;
DWORD pids [5] =
{
1, 2, 3, 4, 5
};
const wchar_t * ppText [5] =
{
L"1", L"2", L"3", L"4", L"5"
};
data.pidButton = (DWORD)pids;
data.ppszButtonText = (DWORD)ppText;
data.dwButtons = 5;
data.dwDefButton = 1;
data.dwCancelId = 1;
data.dwTimeout = 5000;
int res = 0;
HMODULE h = LoadLibrary (L"user32.dll");
if (h != NULL)
{
typedef int (WINAPI *SOFTMODALMESSAGEBOX) (MSGBOXDATA * pMsgData);
SOFTMODALMESSAGEBOX SoftModalMessageBox = (SOFTMODALMESSAGEBOX)GetProcAddress (h, "SoftModalMessageBox");
if (SoftModalMessageBox != NULL)
{
res = SoftModalMessageBox (&data);
}
else
::MessageBoxW (NULL, L"SoftModalMessageBoxW not found in user32.dll", m_caption, MB_ICONSTOP);
FreeLibrary (h);
}
else
::MessageBoxW (NULL, L"Cannot load user32.dll", m_caption, MB_ICONSTOP);
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
以下两个函数由user32.dll导出,只是没有微软官方文档记载,大家在cpp中包含了以下部分,就可以调用MessageBoxTimeout了。
extern "C"
{
int WINAPI MessageBoxTimeoutA(IN HWND hWnd, IN LPCSTR lpText, IN LPCSTR lpCaption, IN UINT uType, IN WORD wLanguageId, IN DWORD dwMilliseconds);
int WINAPI MessageBoxTimeoutW(IN HWND hWnd, IN LPCWSTR lpText, IN LPCWSTR lpCaption, IN UINT uType, IN WORD wLanguageId, IN DWORD dwMilliseconds);
};
#ifdef UNICODE
#define MessageBoxTimeout MessageBoxTimeoutW
#else
#define MessageBoxTimeout MessageBoxTimeoutA
#endif
需要指出的是,Windows 2000的user32.dll没有导出这个函数。
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;补上吧!
;关于函数的返回值,也就是你选择了哪个按钮,有待进一步的研究。
.386
.model flat,stdcall
option casemap:none
include windows.inc
include kernel32.inc
includelib kernel32.lib
include user32.inc
includelib user32.lib
.code
szSoftModalMessageBox db "SoftModalMessageBox",0
szuser32 db "user32.dll",0
huser32 dd 0
pSoftModalMessageBox dd 0
align 4
u_ok dw 'o','k',0
u_no dw 'n','o',0
bufid dword 1,2;,0 ;按钮id的序列,可以增加。也可以一个按钮也没有哟!最多支持有多少个按钮,你可以试一下!
bufstr dword offset u_ok,offset u_no;,0 ;按钮的内容,可以增加。
szCaption dw 'm','a','d','e',' ','b','y',' ','c','o','r','r','e','y',0
szText dw 'W','e','l','l','c','o','m','e',' ','t','o',' ','H','t','t','p',':','/','/','c','o','r','r','e','y','.','w','e','b','s','.','c','o','m',0
align 4 ;最好加上,不加也没有事。
mbd dd 28h ;sizeof MSGBOXPARAMS
dd 0 ;hwndOwner
dd 0 ;hInstance
dd offset szText ;lpszText
dd offset szCaption ;lpszCaption
dd 0 ;dwStyle
dd 0 ;lpszIcon
dd 0 ;dwContextHelpId
dd 0 ;lpfnMsgBoxCallback
dd 0 ;dwLanguageId
;MSGBOXPARAMS 结构结束。一下是附加的定义的结构。
dd 0 ;pwndOwner
dd 0 ;wLanguageId
;dd 0 ;windows 7-64下要加这一行,可能结构变了,不然:不会显示按钮,具体的啥功能我也不知道,还没有实验。
;因为这个,我浪费了大半天的时间。在非windows 7-64操作系统下要去掉这一行。版权归我所有,我的新发现。
dd offset bufid ;pidButton
dd offset bufstr ;ppszButtonText
dd 2 ;cButtons 按钮的数量。
dd 0 ;DefButton 默认的按钮。
dd 1 ;CancelId 0 1
dd -1 ;Timeout
;注释:下面这个是我自己附加的。
dd 0 ;奇哉怪哉,这样点击就不会出错了,下面的加align 4也不行。自己的新发现,必须加这一行。
align 4
start:
align 4
invoke LoadLibrary,addr szuser32
mov huser32,eax
invoke GetProcAddress,huser32,addr szSoftModalMessageBox
mov pSoftModalMessageBox,eax
pushad
;pushf
push offset mbd
call pSoftModalMessageBox
;popf
popad
exit:invoke ExitProcess,0
end start
;made at 2011.08.17
没有评论:
发表评论