首页
社区
课程
招聘
[原创]C++基于SEH二次封装的异常流程与识别
发表于: 2019-10-20 01:04 5416

[原创]C++基于SEH二次封装的异常流程与识别

2019-10-20 01:04
5416

在茫茫的汇编中,怎么来识别try结构呢?

在看代码之前我们先连简单的看下try的处理流程吧

上面的步骤,就是典型的异常处理的顺序。

光看文字多无趣,上代码 - 实例分析,我们来跑一遍:

函数开始将异常回调函数压栈,在上文结尾的部分将此函数加入SEH中,这里并不讲解SEH相关信息,除了设置异常回调函数,和参数压栈还设置了security_cookie,防止栈溢出的检查数据,在此同样不予讲述。


我们走进SEH_4011A0看下实现:

无疑此项就是编译器产生的异常回调函数。

继续看异常抛出的部分:

熟悉的__CxxThrowException?没错他就是用来抛出异常的函数。

这里的__TI1H就是ThrowInfo结构,那么var_18也就是throw关键字后面跟随的数据。

后面连续的几个throw语句也差不多。

直到抛出对象的时候,代码如下:

这里很在抛出异常之前调用了一个函数sub_401030,这个函数的作用就是设置var_34的值,后面与前面的基本相同。

代码如下:

IDA友情提示,这是一个虚表,这个虚表里有两个函数。

这两个函数代码如下:

在004010C9地址处做了一个判断,根据传入参数来决定是否释放空间(标准的虚析构函数),因为IDA载入了pdb文件,所以通过IDA的注释可以很清晰的理解这个函数是CExcepctionDiv0的析构函数。


另一个函数代码如下:

在以上的代码来看识别throw语句并不困难,只要找到__CxxThrowException函数就可以找到throw语句了,并根据throw传递的参数,可以断定抛出的数据类型。


来看看catch吧:

同样IDA通过pdb文件为我们做出了友好的注释,但是所有的catch语句都会具有以下特点:

 --- 没有平衡函数开始的堆栈

 -- 返回时将eax赋值为一个地址


通过这两个特点来找到catch语句块是不是很轻松呢,毕竟不平衡堆栈就返回的情况可以说是极少数了吧。

其他的catch我们就不看了,代码都是类似的,那么赋值给eax的地址里面保存了何方神圣?

来看一看:

这样看起来是不是合理多了,没错这个地址的代码就是用来恢复函数开始压入到堆栈的数据(平衡堆栈)。


我们也可以通过以下的规则来找出catch语句块:

避免篇幅庞大,将不在列出后续catch代码。


结构体一揽?从ThrowInfo开始看起吧 结构体详情请看《C++基于SEH二次封装的异常处理 - 数据结构篇》 文末放上结构体总览图:

还记得上文中提过的__TI1H吗,这是IDA为我们生成的名字,他就是我们要找的ThrowInfo,双击进去看看

这个结构体是我自己创建的,为了方便观察。

根据ThrowInfo的定义(具体请看我的上一篇文章),第四个参数也就是40F5D0h便是CatchTableTypeArray。

代码如下:

上面代码的第二个dd是识别错误,它实际上是.H代表的是int类型,IDA为ThrowInfo命名的最后一个字母对应的就是这个类型( __TI1H ),当然除了.H还有其他字母例如:

 -- .M = float

 -- .D = char

 -- .N = double

 -- ......

这个HandlerType实际就是_msRttiDscr,根据结构定义,最后一项就是CatchProc,也就是catch语句块起始处的地址。

实际上在0040F570附近定义了此函数中所有的catch块,可以通过这一个msRttiDscr找到此函数中所有msRttiDscr的信息,也就可以找到所有的catch语句块了。


重点汇集:


          识别throw语句并不困难,只要找到__CxxThrowException函数就可以找到throw语句了,并根据throw传递的参数,可以断定抛出的数据类型。

所有的catch语句都会具有以下特点:

 --- 没有平衡函数开始的堆栈

 -- 返回时将eax赋值为一个地址

----------->分割线

同一个catch相关的msRttiDscr结构汇集在一起,找到一个,全部都可以挖出。

----------->分割线

寻找catch规则:



[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2019-10-20 08:49 被Hasic编辑 ,原因:
收藏
免费 2
支持
分享
最新回复 (2)
雪    币: 6124
活跃值: (4666)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
2
不错不错
2019-10-20 14:18
0
雪    币: 432
活跃值: (141)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
你好,请问为什么使用OD调试时候,对于中文系统nseh = "\xeb\x06\x90\x90" 装入内存时候\xeb\x06会变成一个字节\3F,从而不能出发漏洞
2019-11-20 14:25
0
游客
登录 | 注册 方可回帖
返回
//