C++异常处理机制反汇编(二):32位下基本类型异常分析
上一篇文章分析了异常处理时遇到的一些结构,现在我们来通过实例分析来加深对那些表的理解。
示例分析

注册异常回调函数
下面的代码用于注册异常回调函数:
asm
00401010 55 push ebp
00401011 8B EC mov ebp,esp
00401013 6A FF push 0FFh
00401015 68 60 34 41 00 push offset __ehhandler$_main (00413460)
0040101A 64 A1 00 00 00 00 mov eax,fs:[00000000]
00401020 50 push eax
00401021 64 89 25 00 00 00 00 mov dword ptr fs:[0],esp
收集异常信息
对于__ehhandler$_main:

其中eax是___CxxFrameHandler函数的参数,是FuncInfo的地址。该函数是对异常信息进行获取的,我们进一步查看该函数的代码:

CxxFrameHandler函数原型如下:
cpp
int cdecl CxxFrameHandler (
EXCEPTION_RECORD *pExcept,
EHRegistrationNode *pRN,
struct _CONTEXT *pContext,
void *pDC);
对异常进行分类处理
上图中的_InternalCxxFrameHandler这个函数是对异常进行分类处理,完成了标记检查、展开、查找和派发等工作。该函数原型如下:
cpp
int cdecl InternalCxxFrameHandler(
EXCEPTION_RECORD *pExcept,
EHRegistrationNode *pRN,
struct _CONTEXT *pContext,
void *pDC,
struct FuncInfo *pFuncInfo,
int CatchDepth,
int pMarkerRN,
int recursive
);
从上图可以看到,该函数有几个结构体参数,我们来看看其中的具体字段。
cpp
typedef struct _EXCEPTION_RECORD {
DWORD ExceptionCode;
DWORD ExceptionFlags;
struct _EXCEPTION_RECORD *ExceptionRecord;
PVOID ExceptionAddress;
DWORD NumberParameters;
ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
} EXCEPTION_RECORD;
再来看看EHRegistrationNode:
txt
EHRegistrationNode struc ; (sizeof=0x10)
pNext dd ? ; 指向链表的上一个节点EHRegistrationNode*
HandlerProc dd ? ; 记录当前函数栈帧的异常回调函数
dwState dd ? ; 记录当前函数栈帧的状态值
dwEbp dd ? ; 记录当前函数栈帧的ebp值
EHRegistrationNode ends
InternalCxxFrameHandler函数反汇编代码较长,这里不列出,我们需要知道的是函数__InternalCxxFrameHandler的主要功能是完成异常类型的检查,最终调用查找try块和catch块的函数FindHandler。
二FindHandler利用TypeMatch函数完成了对异常匹配的判定并得到了结果,又调用CatchIt完成了异常处理。
总结
这里说得很简单,如何利用先前提到的各种结构完成对异常处理没有细讲。