第十章:加载配置信息
加载配置信息表最初是用来存放附加信息,后来用来存放SEH各种导演句柄变成“异常处理表”
异常与中断类似,中断有点外部(键盘)发出,异常由软件,异常发生时跑到异常处理函数,这个函数存放在中断描述符表(IDT)的数据结构中。
异常:硬异常(系统异常)和软异常(程序自己抛出的异常)
;------------------------
; 测试异常处理
; 戚利
; 2011.1.19
;------------------------
.386
.model flat,stdcall
option casemap:none
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
;数据段
.data
szText db 'HelloWorldPE',0
szErr db 'SEH Error',0
;代码段
.code
_handler proc _lpException,_lpSEH,\
_lpContext,_lpDispatcherContext
nop
pushad
mov esi,_lpException
mov edi,_lpContext
assume edi:ptr CONTEXT
invoke MessageBox,NULL,addr szErr,NULL,MB_OK ;111
mov [edi].regEip,offset _safePlace
assume edi:nothing
popad
;测试一
;发生的异常已被该函数接管
mov eax,ExceptionContinueExecution
;测试二
;发生的异常未被该函数接管
;mov eax,ExceptionContinueSearch
ret
_handler endp
start:
assume fs:nothing
push offset _handler
push fs:[0]
mov fs:[0],esp
xor eax,eax
mov dword ptr [eax],eax
_safePlace:
pop fs:[0]
pop eax
invoke MessageBox,NULL,addr szText,NULL,MB_OK ;222
invoke ExitProcess,NULL
end start
//111,222两处弹框
<pre class="plain" name="code">;------------------------
; 测试异常处理
; 戚利
; 2011.1.19
;------------------------
.386
.model flat,stdcall
option casemap:none
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
;数据段
.data
szText db 'HelloWorldPE',0
szErr db 'SEH Error',0
;代码段
.code
_handler proc _lpException,_lpSEH,\
_lpContext,_lpDispatcherContext
nop
pushad
mov esi,_lpException
mov edi,_lpContext
assume edi:ptr CONTEXT
invoke MessageBox,NULL,addr szErr,NULL,MB_OK ;111
mov [edi].regEip,offset _safePlace
assume edi:nothing
popad
;测试一
;发生的异常已被该函数接管
;mov eax,ExceptionContinueExecution
;测试二
;发生的异常未被该函数接管
mov eax,ExceptionContinueSearch
ret
_handler endp
start:
assume fs:nothing
push offset _handler
push fs:[0]
mov fs:[0],esp
xor eax,eax
mov dword ptr [eax],eax
_safePlace:
pop fs:[0]
pop eax
invoke MessageBox,NULL,addr szText,NULL,MB_OK ;222
invoke ExitProcess,NULL
end start
//111弹两次,222弹一次
<pre class="plain" name="code">;------------------------
; 测试异常处理
; 指定了一个safe SEH Handler
; 并测试该异常处理函数,运行后会显示两个提示信息
; 一个是异常处理函数的提示信息,
; 另外一个是异常被处理后主程序的提示信息
; 戚利
; 2011.2.15
;------------------------
.386
.model flat,stdcall
option casemap:none
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
;数据段
.data
szText1 db 'safeHandler!',0
szText2 db 'nosafeHandler!',0
szText db 'HelloWorldPE',0
;代码段
.code
;IMAGE_LOAD_CONFIG_STRUCT STRUCT
Characteristics dd 00000048h
TimeDateStamp dd 0
MajorVersion dw 0
MinorVersion dw 0
GlobalFlagsClear dd 0
GlobalFlagsSet dd 0
CriticalSectionDefaultTimeout dd 0
DeCommitFreeBlockThreshold dd 0
DeCommitTotalFreeThreshold dd 0
LockPrefixTable dd 0
MaximumAllocationSize dd 0
VirtualMemoryThreshold dd 0
ProcessHeapFlags dd 0
ProcessAffinityMask dd 0
CSDVersion dw 0
Reserved1 dw 0
EditList dd 0
SecurityCookie dd 00000000h
SEHandlerTable dd offset safeHandler ;(VA地址)
SEHandlerCount dd 00000001h
;IMAGE_LOAD_CONFIG_STRUCT ENDS
;构造RVA
safeHandler dd offset _handler1-00400000h
dd 0
;-------------------------------------------
; 已注册的异常回调函数
;-------------------------------------------
_handler1 proc _lpException,_lpSEH,\
_lpContext,_lpDispatcherContext
nop
pushad
mov esi,_lpException
mov edi,_lpContext
assume edi:ptr CONTEXT
invoke MessageBox,NULL,addr szText1,NULL,MB_OK ;111
mov [edi].regEip,offset _safePlace
assume edi:nothing
popad
mov eax,ExceptionContinueExecution
ret
_handler1 endp
;-------------------------------------------
; 未注册的异常回调函数
;-------------------------------------------
_handler2 proc _lpException,_lpSEH,\
_lpContext,_lpDispatcherContext
nop
pushad
mov esi,_lpException
mov edi,_lpContext
assume edi:ptr CONTEXT
invoke MessageBox,NULL,addr szText2,NULL,MB_OK
mov [edi].regEip,offset _safePlace
assume edi:nothing
popad
mov eax,ExceptionContinueExecution
ret
_handler2 endp
start:
assume fs:nothing
push offset _handler1
push fs:[0]
mov fs:[0],esp
xor eax,eax ;引发越界异常
mov dword ptr [eax],eax
_safePlace:
pop fs:[0]
pop eax
invoke MessageBox,NULL,addr szText,NULL,MB_OK ;222
invoke ExitProcess,NULL
end start
//111,222各弹一次
<p>;------------------------
; 测试异常处理
; 与exception4.asm不同之处,注册的异常处理程序为_handler2
; safe Handler列表中两个函数都进行了注册
; 戚利
; 2011.1.19
;------------------------
.386
.model flat,stdcall
option casemap:none</p><p>include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib</p><p>;数据段
.data
szText1 db 'safeHandler!',0
szText2 db 'Second safeHandler!',0
szText db 'HelloWorldPE',0</p><p>;代码段
.code</p><p>;IMAGE_LOAD_CONFIG_STRUCT STRUCT
Characteristics dd 00000048h
TimeDateStamp dd 0
MajorVersion dw 0
MinorVersion dw 0
GlobalFlagsClear dd 0
GlobalFlagsSet dd 0
CriticalSectionDefaultTimeout dd 0
DeCommitFreeBlockThreshold dd 0
DeCommitTotalFreeThreshold dd 0
LockPrefixTable dd 0
MaximumAllocationSize dd 0
VirtualMemoryThreshold dd 0
ProcessHeapFlags dd 0
ProcessAffinityMask dd 0
CSDVersion dw 0
Reserved1 dw 0
EditList dd 0
SecurityCookie dd 00000000h
SEHandlerTable dd offset safeHandler ;(VA地址)
SEHandlerCount dd 00000002h
;IMAGE_LOAD_CONFIG_STRUCT ENDS</p><p>;构造RVA
safeHandler dd offset _handler1-00400000h
dd offset _handler2-00400000h
dd 0</p><p>
;-------------------------------------------
; 已注册的异常回调函数1
;-------------------------------------------
_handler1 proc _lpException,_lpSEH,\
_lpContext,_lpDispatcherContext
nop
pushad
mov esi,_lpException
mov edi,_lpContext
assume edi:ptr CONTEXT</p><p> invoke MessageBox,NULL,addr szText1,NULL,MB_OK</p><p> mov [edi].regEip,offset _safePlace
assume edi:nothing</p><p> popad </p><p> mov eax,ExceptionContinueExecution
ret
_handler1 endp</p><p>;-------------------------------------------
; 以注册的异常回调函数2
;-------------------------------------------
_handler2 proc _lpException,_lpSEH,\
_lpContext,_lpDispatcherContext
nop
pushad
mov esi,_lpException
mov edi,_lpContext
assume edi:ptr CONTEXT</p><p> invoke MessageBox,NULL,addr szText2,NULL,MB_OK ;111</p><p> mov [edi].regEip,offset _safePlace
assume edi:nothing</p><p> popad
mov eax,ExceptionContinueExecution
ret
_handler2 endp</p><p>start:
assume fs:nothing
push offset _handler2
push fs:[0]
mov fs:[0],esp</p><p> xor eax,eax ;引发越界异常
mov dword ptr [eax],eax</p><p>_safePlace:</p><p> pop fs:[0]
pop eax</p><p> invoke MessageBox,NULL,addr szText,NULL,MB_OK ;222
invoke ExitProcess,NULL
end start</p>
///111,222各弹一次
<p>;------------------------
; 测试异常处理
; 与exception4.asm相比,该程序中调用了未注册的异常处理函数_handler2
; 戚利
; 2011.1.19
;------------------------
.386
.model flat,stdcall
option casemap:none</p><p>include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib</p><p>;数据段
.data
szText1 db 'safeHandler!',0
szText2 db 'nosafeHandler!',0
szText db 'HelloWorldPE',0</p><p>;代码段
.code</p><p>;IMAGE_LOAD_CONFIG_STRUCT STRUCT
Characteristics dd 00000048h
TimeDateStamp dd 0
MajorVersion dw 0
MinorVersion dw 0
GlobalFlagsClear dd 0
GlobalFlagsSet dd 0
CriticalSectionDefaultTimeout dd 0
DeCommitFreeBlockThreshold dd 0
DeCommitTotalFreeThreshold dd 0
LockPrefixTable dd 0
MaximumAllocationSize dd 0
VirtualMemoryThreshold dd 0
ProcessHeapFlags dd 0
ProcessAffinityMask dd 0
CSDVersion dw 0
Reserved1 dw 0
EditList dd 0
SecurityCookie dd 00000000h
SEHandlerTable dd offset safeHandler ;(VA地址)
SEHandlerCount dd 00000001h
;IMAGE_LOAD_CONFIG_STRUCT ENDS</p><p>;构造RVA
safeHandler dd offset _handler1-00400000h
dd 0</p><p>
;-------------------------------------------
; 已注册的异常回调函数
;-------------------------------------------
_handler1 proc _lpException,_lpSEH,\
_lpContext,_lpDispatcherContext
nop
pushad
mov esi,_lpException
mov edi,_lpContext
assume edi:ptr CONTEXT</p><p> invoke MessageBox,NULL,addr szText1,NULL,MB_OK</p><p> mov [edi].regEip,offset _safePlace
assume edi:nothing</p><p> popad </p><p> mov eax,ExceptionContinueExecution
ret
_handler1 endp</p><p>;-------------------------------------------
; 未注册的异常回调函数
;-------------------------------------------
_handler2 proc _lpException,_lpSEH,\
_lpContext,_lpDispatcherContext
nop
pushad
mov esi,_lpException
mov edi,_lpContext
assume edi:ptr CONTEXT</p><p> invoke MessageBox,NULL,addr szText2,NULL,MB_OK</p><p> mov [edi].regEip,offset _safePlace
assume edi:nothing</p><p> popad
mov eax,ExceptionContinueExecution
ret
_handler2 endp</p><p>start:
assume fs:nothing
push offset _handler2
push fs:[0]
mov fs:[0],esp</p><p> xor eax,eax ;引发越界异常
mov dword ptr [eax],eax</p><p>_safePlace:</p><p> pop fs:[0]
pop eax</p><p> invoke MessageBox,NULL,addr szText,NULL,MB_OK
invoke ExitProcess,NULL
end start</p>//一个都不弹 因为没有加入SEH框架中的异常处理函数未在PE映像的加载配置信息表中定义。
;------------------------
; 测试异常处理
; 戚利
; 2011.1.19
;------------------------
.386
.model flat,stdcall
option casemap:none
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
;数据段
.data
szText db 'HelloWorldPE',0
szErr db 'SEH Error',0
;代码段
.code
_handler proc _lpException,_lpSEH,\
_lpContext,_lpDispatcherContext
nop
pushad
mov esi,_lpException
mov edi,_lpContext
assume edi:ptr CONTEXT
invoke MessageBox,NULL,addr szErr,NULL,MB_OK ;111
mov [edi].regEip,offset _safePlace
assume edi:nothing
popad
;测试一
;发生的异常已被该函数接管
;mov eax,ExceptionContinueExecution
;测试二
;发生的异常未被该函数接管
mov eax,ExceptionContinueSearch
ret
_handler endp
start:
assume fs:nothing
push offset _handler
push fs:[0]
mov fs:[0],esp
xor eax,eax
mov dword ptr [eax],eax
_safePlace:
pop fs:[0]
pop eax
invoke MessageBox,NULL,addr szText,NULL,MB_OK ;222
invoke ExitProcess,NULL
end start
//111弹两次,222弹一次