Comb Lao Luo Win32 to compile knowledge about the Seh chapter.
There are two types of exception handling: Filter exception handling and structured exception handling, filters are global, a single exception handling callback function cannot be set for a thread or a subroutine, and structured exception handling (structured Exception Handing) SEH provides an independent exception handling method between each thread.
Here are two examples of how to learn Seh
Example 1: Exception handling without stack expansion (stack unwinding is described in the example two)
.386
. ModelFlat,stdcall
OptionCasemap:none
;>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>
; include
;>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>
IncludeWindows.inc
IncludeUser32.inc
Includelib User32.lib
IncludeKernel32.inc
IncludelibKernel32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>
; Data segment
;>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>
. Data
Lpoldhandler Dd?
. const
Szmsg Db "Exception occurred at:%08x,%08x, exception code:%08X, Flag:%08x", 0
Szsafe Db "Back to the Safe place", 0
SzTitle Db "Example of Seh", 0
;>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>
; Code Snippets
;>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>
. Code
_handler Proc C _lpexceptionrecord,_lpseh,_lpcontext,_lpdispatchercontext
LOCAL@szBuffer [1024]:byte
Pushad
mov Esi,_lpexceptionrecord
mov Edi,_lpcontext
Assume Esi:ptr Exception_record,edi:ptr CONTEXT
mov Eax,[esi]. Exceptioncode
is called because of a stack unwind operation.
. ifEAX = = Status_unwind
Popad
mov Eax,exceptioncontinuesearch
; Access to illegal
. elseif EAX = = Exception_access_violation
; The exceptioncode contains the type of exception, the severity, the setting that triggers the exception, the memory
, or the network, or the CPU, or the interface card, or the multimedia settings
; Exceptionflag whether the table continues execution or stack expansion
Invoke Wsprintf,addr @szBuffer, addr szmsg,\
[Edi].regeip,[esi]. Exceptionaddress,[esi]. Exceptioncode,[esi]. ExceptionFlags
Invoke Messagebox,null,addr @szBuffer, NULL,MB_OK
mov Eax,_lpseh
; mov [Edi].regeip,offset _safeplace
Push [Eax+0ch]
Pop [EDI].REGEBP
Push [Eax+8]
Pop [Edi].regeip
Push fa[
Pop [Edi].regesp
Popad
mov Eax,exceptioncontinueexecution
. else
Popad
mov Eax,exceptioncontinuesearch
. endif
Assume Esi:nothing,edi:nothing
Ret
_handlerEndp
_test Proc
Assume Fs:nothing
Push Ebp
Push Offset _safeplace
Push Offset _handler
; fs:[0] retains the address of the exception_registration structure
Push FS:[0]
Fs:[0], the first 8 fields in the stack just match the ExceptionList field in the exception_registration structure
;p Re Exception_registration
; handler
mov Fs:[0],esp
XorEax,eax
mov DWORD ptr [eax],0
_safeplace:
Invoke Messagebox,null,addr szsafe,addr SZTITLE,MB_OK
Pop FS:[0]
Add Esp,0ch
Ret
_test Endp
Start
Invoke _test
Invoke Exitprocess,null
End Start
Places to be aware of:
1 It is necessary to save the relevant variables of exception handling on the stack before the exception is possible, which is advantageous to modularization on the stack.
2 in the callback function, according to the Exceptioncode exception code to distinguish which exception is processing, can handle the exception return exceptioncontinueexecution, otherwise return exceptioncontinuesearch, Note that the return value of the filter exception handling must be distinguished, although the name is somewhat similar, but the value is completely different, if confused, there will be a callback function is constantly called the problem, because if the return exception_continue_execution, then 1, Indicates that the callback cannot handle the exception (which is not actually the case), and the callback function is called again by the system with the Exception_registration Exceptioncode as Exception_unwind_for_exit.
Example two: Exception handling with stack expansion operations
.386
. ModelFlat,stdcall
OptionCasemap:none
;>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>
; include
;>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>
IncludeWindows.inc
IncludeUser32.inc
Includelib User32.lib
IncludeKernel32.inc
IncludelibKernel32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>
; Data segment
;>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>
. Data
Lpoldhandler Dd?
. const
Szmsg Db "Outer exception occurred location:%08x, Exception code:%08X, Flag:%08x", 0
Szinmsg Db "Internal exception occurred in:%08x, Exception code:%08X, Flag:%08x", 0
Szsafe Db "Back to the Safe place", 0.
Szinsafe Db "Back in the Safe place", 0
SzTitle Db "Example of Seh", 0
Szfsmsg Db "Fs:[0]%08x", 0
;>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>
; Code Snippets
;>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>
. Code
_intest Proc
Assume Fs:nothing
Push Ebp
Push Offset _insafeplace
Push Offset _inhandler
Push FS:[0]
mov Fs:[0],esp
XorEax,eax
mov DWORD ptr [eax],0
_insafeplace:
Invoke Messagebox,null,addr szinsafe,addr SZTITLE,MB_OK
Pop FS:[0]
Add Esp,0ch
Ret
_intest ENDP
_inhandler ProcC _lpexceptionrecord,_lpseh,_lpcontext,_lpdispatchercontext
LOCAL@szBuffer [1024]:byte
Pushad
mov Esi,_lpexceptionrecord
mov Edi,_lpcontext
Assume Esi:ptr Exception_record,edi:ptr CONTEXT
mov Eax,[esi]. Exceptioncode
; The exceptioncode contains the type of exception, the severity, the setting that triggers the exception, the memory
, or the network, or the CPU, or the interface card, or the multimedia device
; What's the use of Exceptionflag?
Invoke Wsprintf,addr @szBuffer, addr szinmsg,\
[Edi].regeip,[esi]. Exceptioncode,[esi]. ExceptionFlags
Invoke Messagebox,null,addr @szBuffer, NULL,MB_OK
Popad
mov Eax,exceptioncontinuesearch
Assume Esi:nothing,edi:nothing
Ret
_inhandlerEndp
_handler Proc C _lpexceptionrecord,_lpseh,_lpcontext,_lpdispatchercontext
LOCAL@szBuffer [1024]:byte
Pushad
mov Esi,_lpexceptionrecord
mov Edi,_lpcontext
Assume Esi:ptr Exception_record,edi:ptr CONTEXT
mov Eax,[esi]. Exceptioncode
is called because of a stack unwind operation.
. ifEAX = = Status_unwind
Popad
mov Eax,exceptioncontinuesearch
; Access to illegal
. elseif EAX = = Exception_access_violation
; The exceptioncode contains the type of exception, the severity, the setting that triggers the exception, the memory
, or the network, or the CPU, or the interface card, or the multimedia settings
; Exceptionflag identifier, continue execution, or stack expansion?
Invoke Wsprintf,addr @szBuffer, addr szmsg,\
[Edi].regeip,[esi]. Exceptioncode,[esi]. ExceptionFlags
Invoke Messagebox,null,addr @szBuffer, NULL,MB_OK
mov Eax,_lpseh
Push [Eax+0ch]
Pop [EDI].REGEBP
Push [Eax+8]
Pop [Edi].regeip
Push eax
Pop [Edi].regesp
Invoke Wsprintf,addr @szBuffer, addr szfsmsg,dword ptr fs:[0]
Invoke Messagebox,null,addr @szBuffer, NULL,MB_OK
Invoke Rtlunwind,_lpseh,null,null,null
Invoke Wsprintf,addr @szBuffer, addr szfsmsg,dword ptr fs:[0]
Invoke Messagebox,null,addr @szBuffer, NULL,MB_OK
Popad
mov Eax,exceptioncontinueexecution
. else
Popad
mov Eax,exceptioncontinuesearch
. endif
Assume Esi:nothing,edi:nothing
Ret
_handlerEndp
_test Proc
Assume Fs:nothing
Push Ebp
Push Offset _safeplace
Push Offset _handler
; fs:[0] retains the address of the exception_registration structure
Push FS:[0]
Fs:[0], the first 8 fields in the stack just match the ExceptionList field in the exception_registration structure
mov Fs:[0],esp
Invoke_intest
_safeplace:
Invoke Messagebox,null,addr szsafe,addr SZTITLE,MB_OK
Pop FS:[0]
Add Esp,0ch
Ret
_test Endp
Start
Invoke _test
Invoke Exitprocess,null
End Start
What is a stack unwind, when back to redeployment stacks, starts with a callback function from Fs:[0], invokes the callback in Exception_unwind code one after the other, and then unloads all previously traversed callbacks, which means fs:[0] points to their exception_ Registration structure. Why stack expansion? Reason one: Let the uninstalled callback have the opportunity to mop up the work. Cause two: The exception will occur, the analysis is as follows: After the function is expanded, the stack will be recovery to the position before the exception, then the previous fs:[0] point to the position beyond the top of the stack, the future will be overwritten by other data, and if the exception occurs again, from fs:[0], the error.
How do I proceed with stack expansion?
Invoke Rtlunwind,lplaststackframe,lpcodelabel,lpexceptionrecord,dwret
Parameter 1:lplaststackframe
If not empty, start with fs:[0] until the callback before the exception_registration is called by the side Laststackframe.
Right is empty, then all registered callbacks are called
Parameter 2:lpcodelabel
If not NULL, the function call is finished and returned to the command area pointed to by the Edge Codelabel
If empty, the normal function return method is used
Parameter 3:lpexceptionrecord
Expands the structure of the simultaneous to each callback, and if it is empty, the system automatically generates the structure
Parameter 4:dwret
Generally not, empty
Some knowledge about SEH (structured exception handling)