挂钩CreateWindowEx函数之后,如果第三方进程不判断窗口是否建立成功,那么很可能会因此引发异常而直接退出,比如内存不能为“read”等等,如果目标进程有异常处理机制还好,就怕它在没判断的情况下直接创建后续的子控件。
以下这个例子还好,我测试了一下不会引发异常,但不能保证大一点的程序同样可以不发生错误。
test.au3(先编译成test.exe)。
Opt("GUIOnEventMode", 1)
$iWindow = 0
$hGUI = GUICreate("Test", 220, 100)
GUISetOnEvent(-3, "_Exit")
GUICtrlCreateButton("Create a new window", 40, 30, 140, 20)
GUICtrlSetOnEvent(-1, "_CreateWindow")
GUISetState(@SW_SHOW, $hGUI)
While 1
Sleep(100)
WEnd
Func _Exit()
Exit
EndFunc
Func _CreateWindow()
GUICreate("Sub window " & $iWindow, 200, 70)
GUISetOnEvent(-3, "_CloseSubWindow")
GUISetState(@SW_SHOW)
$iWindow += 1
EndFunc ;==>_CreateWindow
Func _CloseSubWindow()
GUIDelete(@GUI_WinHandle)
EndFunc ;==>_CloseSubWindow
HookCreateWindow.au3:
#include <RTApiHook32.au3>
$hProcess = _RTOpenProcess("test.exe")
$hCallBack = DllCallBackRegister("_CreateWindowCallBack", "dword", "handle;ptr")
$pCallBack = DllCallBackGetPtr($hCallBack)
$pCreateWindowExW = _RTGetProcAddress("User32.dll", "CreateWindowExW")
$tCreateWindowExW = _RTApiHookEx($hProcess, $pCreateWindowExW, 12, $pCallBack, $APIHOOK_Flags_Default)
OnAutoItExitRegister("_Restore")
While 1
Sleep(100)
WEnd
Func _Restore()
_RTApiUnhook($hProcess, $pCreateWindowExW, DllStructGetData($tCreateWindowExW, "Entrypoint"))
DllCallBackFree($hCallBack)
EndFunc ;==>_Restore
Func _CreateWindowCallBack($hProcess, $pCallInfo)
Local $pClassName = _RTApiHookReadParam($hProcess, $pCallInfo, 2)
Local $sClassName = _RTReadProcessMemory($hProcess, $pClassName, "", 1024, "wstr")
; If ($sClassName = "XXXX") Then
_RTApiHookSetRetVal($hProcess, $pCallInfo, 0)
_RTApiHookSetError($hProcess, $pCallInfo, 1407)
Return $APIHOOK_Flags_Call_Abort
; EndIf
EndFunc ;==>_CreateWinowCallBack
测试时先运行test.exe,然后运行HookCreateWindow.au3。 |