Windows异常世界历险记(五)——VC6中结构化异常处理机制的反汇编分析(下)

在本系列的上一篇文章Windows异常世界历险记(四)——VC6中结构化异常处理机制的反汇编分析(中)中,给出了针对VC6的异常处理机制进行逆向后得到的伪码。在本文中,我们仍然以之前写的小程序为例,通过调试的方式结合我们得到的VC6结构化异常处理的伪码,对其运行机制进行分析。

破局

在RaiseExcept中,即将触发异常时的情形如下:

0:000> p
eax=cccccccc ebx=003ea000 ecx=00000000 edx=00694687 esi=00401540 edi=0019fe5c
eip=00401143 esp=0019fe0c ebp=0019fe74 iopl=0         nv up ei pl nz na pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000207
SEHTest1!RaiseExcept+0x43:
00401143 c7050000000000000000 mov dword ptr ds:[0],0  ds:002b:00000000=????????

先看看SEH链:

0:000> dd fs:[0]
0053:00000000  0019fe64 001a0000 0019c000 00000000
0:000> dt _EXCEPTION_REGISTRATION_RECORD 0019fe64
ntdll!_EXCEPTION_REGISTRATION_RECORD
   +0x000 Next             : 0x0019fed0 _EXCEPTION_REGISTRATION_RECORD
   +0x004 Handler          : 0x00401460     _EXCEPTION_DISPOSITION  SEHTest1!_except_handler3+0
0:000> dt _EXCEPTION_REGISTRATION_RECORD 0x0019fed0
ntdll!_EXCEPTION_REGISTRATION_RECORD
   +0x000 Next             : 0x0019ff60 _EXCEPTION_REGISTRATION_RECORD
   +0x004 Handler          : 0x00401460     _EXCEPTION_DISPOSITION  SEHTest1!_except_handler3+0
0:000> dt _EXCEPTION_REGISTRATION_RECORD 0x0019ff60
ntdll!_EXCEPTION_REGISTRATION_RECORD
   +0x000 Next             : 0x0019ffcc _EXCEPTION_REGISTRATION_RECORD
   +0x004 Handler          : 0x00401460     _EXCEPTION_DISPOSITION  SEHTest1!_except_handler3+0
0:000> dt _EXCEPTION_REGISTRATION_RECORD 0x0019ffcc
ntdll!_EXCEPTION_REGISTRATION_RECORD
   +0x000 Next             : 0x0019ffe4 _EXCEPTION_REGISTRATION_RECORD
   +0x004 Handler          : 0x775286d0     _EXCEPTION_DISPOSITION  ntdll!_except_handler4+0
0:000> dt _EXCEPTION_REGISTRATION_RECORD 0x0019ffe4
ntdll!_EXCEPTION_REGISTRATION_RECORD
   +0x000 Next             : 0xffffffff _EXCEPTION_REGISTRATION_RECORD
   +0x004 Handler          : 0x7753518e     _EXCEPTION_DISPOSITION  ntdll!FinalExceptionHandlerPad14+0

由上述结果可得出结论:目前一共安装有5个SEH异常处理函数,其中前3个是VC6自己的,后两个是系统的。对于前3个VC6安装的SEH节点,是在标准的SEH链结构EXCEPTION_REGISTRATION_RECORD的基础上“加了料”形成的,在上篇文章中已经给出了其结构,我们将其暂且命名为VC6_EXCEPTION_REGISTRATION_RECORD吧:

typedef struct VC6_EXCEPTION_REGISTRATION_RECORD
{
	DWORD	dwCurrentESP;						// 保存的ESP值
	PVC6_EXCEPTION_INFORMATION pExceptInfo;		// 异常信息结构指针
	EXCEPTION_REGISTRATION_RECORD pSEHNode;		// 经典的异常链节点
	PVC6_SCOPETABLE	pScopeTable;			// VC的惯用伎俩——表结构
	DWORD	dwTryLevel;					// 当前try的层级
	DWORD	dwEBP;			// 这个其实不是本结构的成员,只是本结构在栈上挨着函数入口处压入的EBP而已
}VC6_EXCEPTION_REGISTRATION_RECORD, *PVC6_EXCEPTION_REGISTRATION_RECORD;

需要指出的是,VC6_EXCEPTION_REGISTRATION_RECORD结构中最后一个成员dwEBP是我们根据栈结构添加进去的,因为在except_handler3中会用到。下面就按VC6_EXCEPTION_REGISTRATION_RECORD结构对前3个属于VC6的异常处理节点进行解析:

结构 第一节点 第二节点 第三节点
dwCurrentESP 0019fe0c 0019fe7c 0019ffcc
pExceptInfo(此时还没填) 00000800 0019fee0 00401460
pSEHNode.Next 0019fed0 0019ff60 00422248
pSEHNode.Handler 00401460 00401460 00000000
pScopeTable 004220c8 00422138 0019ff80
dwTryLevel 00000001 00000001 74d6fe09
dwEBP 0019fee0 0019ff70 003ea000

OK了,下面主要来看下各节点的ScopeTable,ScopeTable的结构定义在上一篇中被我们命名为了


                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值