首页 > Win32 ASM > Windows SEH汇编版

Windows SEH汇编版

SEH,即Structured Exception Handling,中文为结构化异常处理。是Windows操作系统提供给程序设计者的强有力的处理程序错误或异常的武器。Ring3下fs:[0]指向TEB(Thread Environment Block)结构,打开WinDbg,查看_TEB结构:

nt!_TEB
   +0x000 NtTib            : _NT_TIB
   +0x01c EnvironmentPointer : Ptr32 Void
   +0x020 ClientId         : _CLIENT_ID
   +0x028 ActiveRpcHandle  : Ptr32 Void
   +0x02c ThreadLocalStoragePointer : Ptr32 Void
   // ... 省略部分TEB成员信息 ...
   +0xfb0 ActiveFrame      : Ptr32 _TEB_ACTIVE_FRAME
   +0xfb4 SafeThunkCall    : UChar
   +0xfb5 BooleanSpare     : [3] UChar

可以看到TEB头部就是一个_NT_TIB结构,再在WinDbg中查看_NT_TIB结构体:

kd> dt _NT_TIB
nt!_NT_TIB
   +0x000 ExceptionList    : Ptr32 _EXCEPTION_REGISTRATION_RECORD
   +0x004 StackBase        : Ptr32 Void
   +0x008 StackLimit       : Ptr32 Void
   +0x00c SubSystemTib     : Ptr32 Void
   +0x010 FiberData        : Ptr32 Void
   +0x010 Version          : Uint4B
   +0x014 ArbitraryUserPointer : Ptr32 Void
   +0x018 Self             : Ptr32 _NT_TIB

可以看到_NT_TIB的首部是_EXCEPTION_REGISTRATION_RECORD类型的ExceptionList,实际上这是一个异常处理链。_EXCEPTION_REGISTRATION_RECORD的结构解析如下:

kd> dt _EXCEPTION_REGISTRATION_RECORD
nt!_EXCEPTION_REGISTRATION_RECORD
   +0x000 Next             : Ptr32 _EXCEPTION_REGISTRATION_RECORD
   +0x004 Handler          : Ptr32     _EXCEPTION_DISPOSITION

其中Next成员为指向异常处理链中下一个节点的指针,Handler指向为当前异常程序。如果Next为0xFFFFFFFF,则该节点为最后一个处理节点。
在汇编中,我们可以构造这样一个异常处理节点:先压入异常处理函数,然后压入fs:[0],最后把esp存入fs:[0]。
这样在发生异常的时候就会调用我们的异常处理函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
; Windows SEH Asm Edition
; Reference: 《Windows环境下32位汇编语言程序设计》By罗云彬
; Author: 代码疯子
; Blog: http://www.programlife.net/
				.386
				.model flat, stdcall
				option casemap:none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include			windows.inc
include			user32.inc
includelib		user32.lib
include			kernel32.inc
includelib		kernel32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
				.const
szCaption		db		'[Exception Info]', 0
szTextErr		db		'Its impossible to show this MessageBox!', 0
szTextOK		db		'EIP register has been set to safe place!', 0
szMsg			db		'Place: 0x%08X, Code: 0x%08X, Flag: 0x%08X', 0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
				.code
_ErrHandler		proc	C _lpExceptionRecord, _lpSEH, \
						_lpContext, _lpDispatchContext
				local	@szBuffer[256]:byte
 
				pushad
				mov		esi, _lpExceptionRecord
				mov		edi, _lpContext
				assume	esi:ptr EXCEPTION_RECORD, edi:ptr CONTEXT
				invoke	wsprintf, addr @szBuffer, addr szMsg, [edi].regEip, \
						[esi].ExceptionCode, [esi].ExceptionFlags
				invoke	MessageBox, NULL, addr @szBuffer, addr szCaption, \
						MB_ICONINFORMATION
				mov		[edi].regEip, offset _SafePlace
				assume	esi:nothing, edi:nothing
				popad
				mov		eax, ExceptionContinueExecution
				ret
 
_ErrHandler		endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
				assume	fs:nothing
				push	offset _ErrHandler
				push	fs:[0]
				mov		fs:[0], esp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
				xor		eax, eax
				mov		dword ptr [eax], 0
				invoke	MessageBox, NULL, addr szTextErr, addr szCaption, MB_OK
_SafePlace:
				invoke	MessageBox, NULL, addr szTextOK, addr szCaption, MB_OK
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
				pop		fs:[0]
				pop		eax
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
				invoke	ExitProcess, 0
				end		start

程序自己构造了一个SEH异常处理链节点,然后往0内存处写入值,会引发违规访问。然后就会调用我们的SEH异常处理函数,该函数更改了EIP寄存器的指向,是的程序跳转到正常的位置继续执行。

违规内存访问被SEH异常处理程序捕捉到

SEH异常处理程序重新设置EIP寄存器指向


觉得文章还不错?点击此处对作者进行打赏!


本文地址: 程序人生 >> Windows SEH汇编版
作者:代码疯子(Wins0n) 本站内容如无声明均属原创,转载请保留作者信息与原文链接,谢谢!


更多



分类: Win32 ASM 标签: , , ,
  1. 本文目前尚无任何评论.