前几天写的处理程序异常的演示代码。
#include <Thread.au3>
Const $EXCEPTION_CONTINUE_EXECUTION = -1
Const $EXCEPTION_CONTINUE_SEARCH = 0
Const $EXCEPTION_EXECUTE_HANDLER = 1
Const $INVALID_POINTER = 1
Const $tagSTACK = "ptr ReturnAddress;ptr CallAddress;ptr Parameters[64]" ; 堆栈结构
Const $tagEXCEPTION_POINTERS = "ptr ExceptionRecord;ptr ContextRecord"
Const $tagEXCEPTION_RECORD = "dword Code;dword Flags;ptr Record;ptr Address;dword NumberofParams;ulong_ptr Params[15]"
$sFormat = "An exception has occured during the execution, " & _
"the following lists the detailed information:" & @CRLF & @CRLF & _
@Tab & "Exception code:" & @Tab & @Tab & "0x%08X" & @CRLF & _
@Tab & "Exception flags:" & @Tab & @Tab & "0x%08X" & @CRLF & _
@Tab & "Exception address:" & @Tab & @Tab & "0x%08X" & @CRLF & _
@Tab & "Excepction link:" & @Tab & @Tab & "0x%08X" & @CRLF & _
@Tab & "Exception reason:" & @Tab & @Tab & "0x%08X" & @CRLF & _
@Tab & "Device address:" & @Tab & @Tab & "0x%08X" & @CRLF & _
@Tab & "Coefficient:" & @Tab & @Tab & "0x%08X" & @CRLF & @CRLF & _
@Tab & "Eax: 0x%08X" & @Tab & "Ecx: 0x%08X" & @Tab & "Edx: 0x%08X" & @CRLF & _
@Tab & "Ebx: 0x%08X" & @Tab & "Esp: 0x%08X" & @Tab & "Ebp: 0x%08X" & @CRLF & _
@Tab & "Esi: 0x%08X" & @Tab & "Edi: 0x%08X" & @Tab & "Eip: 0x%08X" & @CRLF & @CRLF & _
"Do you want to fix this problem and process circuit to jump back the safe address?"
; 注册异常处理回调函数。
$hCallBack = DllCallBackRegister("_ExceptionCallBack", "dword", "ptr")
$pFilter = DllCallBackGetPtr($hCallBack)
; 要恢复并跳转到的安全地址。
$hSafeAddress = DllCallBackRegister("_SafeAddress", "none", "")
$pSafeAddress = DllCallBackGetPtr($hSafeAddress)
$pPrevFilter = _SetUnhandledExceptionFilter($pFilter)
; 构造一个具有非法指针的结构体。
$tExceptionTest = DllStructCreate("dword ExceptionTest", $INVALID_POINTER)
; 引发程序异常,跳转至_ExceptionCallBack函数。
DllStructSetData($tExceptionTest, "ExceptionTest", 1)
Func _ExceptionCallBack($pExceptionInfo)
Local $tExceptionInfo, $tContext, $tException, $iCode, $sMsg, $tStack
$tExceptionInfo = DllStructCreate($tagEXCEPTION_POINTERS, $pExceptionInfo)
$tContext = DllStructCreate($tagRT_THREADCONTEXT, DllStructGetData($tExceptionInfo, "ContextRecord"))
$tException = DllStructCreate($tagEXCEPTION_RECORD, DllStructGetData($tExceptionInfo, "ExceptionRecord"))
$iCode = DllStructGetData($tException, "Code")
#cs
$iCode 标志位:
0 ~ 15: 异常原因。
16 ~ 27: 异常位置。
28: 保留。
29 ~ 定义者,0 - Microsoft定义;1 - 应用程序定义。
30 ~ 31: 严重系数,0 - 成功;1 - 信息;2 - 警告;3 - 错误。
#ce
$sMsg = StringFormat($sFormat, _
DllStructGetData($tException, "Code"), _
DllStructGetData($tException, "Flags"), _
DllStructGetData($tException, "Address"), _
DllStructGetData($tException, "ExceptionRecord"), _
BitAnd($iCode, 0xFFFF), _
BitAnd(BitShift($iCode, 16), 0xFFF), _
BitAnd(BitShift($iCode, 30), 3), _
DllStructGetData($tContext, "Eax"), _
DllStructGetData($tContext, "Ecx"), _
DllStructGetData($tContext, "Edx"), _
DllStructGetData($tContext, "Ebx"), _
DllStructGetData($tContext, "Esp"), _
DllStructGetData($tContext, "Ebp"), _
DllStructGetData($tContext, "Esi"), _
DllStructGetData($tContext, "Edi"), _
DllStructGetData($tContext, "Eip"))
Switch MsgBox(51, "Exception", $sMsg)
Case 6 ; 恢复异常
$tStack = DllStructCreate($tagSTACK, DllStructGetData($tContext, "Esp"))
; 安全函数_SafeAdress的返回地址。
DllStructSetData($tStack, "ReturnAddress", _RTGetProcAddress("Kernel32.dll", "ExitProcess"))
; 调用_SafeAddress函数的调用者地址。
DllStructSetData($tStack, "CallAddress", DllStructGetData($tContext, "Eip"))
; 返回地址函数(ExitProcess)的参数。
DllStructSetData($tStack, "Parameters", 1, 1) ; Kernel32.ExitProcess.ExitCode
; 设置EIP指针,异常处理函数返回后将跳转到安全函数_SafeAddress中。
DllStructSetData($tContext, "Eip", $pSafeAddress)
Return $EXCEPTION_CONTINUE_EXECUTION
Case 7 ; 退出程序,但不显示错误对话框。
Return $EXCEPTION_EXECUTE_HANDLER
EndSwitch
; 由操作系统处理异常。
Return $EXCEPTION_CONTINUE_SEARCH
EndFunc ;==>_ExceptionCallBack
Func _SafeAddress()
MsgBox(64, "OK~!", "I've back the safe address.")
Opt("TrayIconHide", 1)
EndFunc ;==>_SafeAddress
Func _SetUnhandledExceptionFilter($pCallBack)
Local $iResult
$iResult = DllCall("Kernel32.dll", "ptr", "SetUnhandledExceptionFilter", "ptr", $pCallBack)
Return $iResult[0]
EndFunc ;==>_SetUnhandledExceptionFilter
|