C++反汇编第六讲,认识C++中的Trycatch语法,以及在反汇编中还原
C++反汇编第六讲,认识C++中的Try catch语法,以及在反汇编中还原
我们以前讲SEH异常处理的时候已经说过了,C++中的Try catch语法只不过是对SEH做了⼀个封装.
如果不懂SEH异常处理,请点击博客链接熟悉⼀下,当然如果不想知道,也可以直接往下看.因为异常处理所以做了封装,但是不影响我们还原.
这⾥有两种解决⽅法,
第⼀种,⼩⽩也能明⽩了还原⽅式,不⽤懂原理
第⼆种,了解其原理,并能在IDA中正确的还原.
SEH异常处理博客链接:
⼀⼂⼩⽩也懂的异常处理还原.
第⼀种,不⽤懂任何原理,(反汇编要懂,最起码的汇编代码知道是什么,不然这个专题讲了你也看不懂)
先看下⾼级代码:
int main(int argc, char* argv[])
{
try
{
throw3;//抛出3整形的异常
}
catch (int)
{
printf("%d\r\n",3);
}
return0;
}
OD调试,观看步骤.
⾸先步骤分两步.
1.SEH异常处理回调.
2.参数多的call下断点
3.最后⼀个是call 寄存器.则到正确的cath位置.
truncated c语言1.到SEH的异常处理回调函数(如果不懂,看下SEH的筛选器异常.)
观看栈参数,可以看到回调函数地址是00410CC0,此时反汇编窗⼝跟过去下断点.
2.观看参数多了call,下断点,然后跟进.
因为层级较多,这⾥⼤家动⼿实战即可.
3.到最后⼀层call⼀个寄存器.
此时则到了我们的cath处理块了.
⼆⼂理解原理进⾏实战.
上⾯说的,不懂原理你也可以做.⽐如以后⼯作了,原理不懂,起码做代码还原的时候还可以混⼝饭吃 ^_^
下⾯讲解原理.
⾸先,我们先寻数据关系.
⼀个函数可以有多个 try 这是没问题的,所以函数和try的关系是⼀对多的关系.
⼀个try有多个catch也是没有问题的.那么对应关系也是⼀对多.
所以操作系统为了管理这些.需要建表.(当然是未公开的),我们可以逆向得知.
1.原理介绍,上半部分表
观看表
看到怎么多表是不是很晕.其实很简单,只是⾥⾯的某个字段对我们有⽤.
1.观看函数信息表FuncInfo,重要字段就是dwTryCount,以及pTryBlockMap,我们说过⼀个函数可以有多个try,所以函数信息就记录了try的个数.以及每个try的try块结构,关于上⾯的成员,都是SEH的异常展开的.要做⾸尾动作的,对于我们还原没有任何阻碍,可以不⽤理解.
2.TryBlockMap表(tyr块信息表),我们还说过,⼀个try可以有多个catch,显然,try块信息表也要记录catch的个数.⼀个catch信息块的结构.
3.cathch信息块的结构体(msRTTIDsrc)msRTTIDsrc这个表是IDA识别的,我们可以⾃⼰说他是catch信息表,msRTTIDsrc的全名是 Microsoft Run Time TypeInfo ....微软运⾏时类型识别.
表结构体中重要字段就是 dwCount,catch信息快的个数,⼀个cathch信息表.
4.catch信息表(msRTTIDsrc),⾥⾯有4个成员, nflag ⼀个标志,表⽰你是常量,还是变量,还是引⽤. ptype,表⽰你的类型是什么类型.是int,还是float什么的,这个有个专门的表格存放着.下⾯重要字段则是catch的函数地址.编译器内部编译的时候,编译的catch是⼀个函数,也是有返回值的,返回值是catch_end的位置.
到这⾥,我们的上半部分就看完了.
总结⼀下:
对于上半部分.主要着重于函数信息表,try块表.catch表.以及catch块表.
为什么说上半部分,是这样的,对于我们还原来说.有两种情况.
1.完整的还原trycatch的异常信息结构
2.到关键的catch匹配函数.
这两种是完全不⼀样的,如果我们还原就看上版本的表.如果我们要那个catch捕获异常,则看下部分的表,(下⾯讲解.)
实战演练.
实战演练的时候,我们就要知道函数信息表在哪,其实我们已经到了,只不过⼤家不知道,按照⼩⽩思路为什么⼀路跟就可以到catch块表.只是我们没讲.
1.到注册异常回调的地⽅,进⼊回调函数内部.
2.看到反汇编.
这个地⽅,给eax赋值的地址就是函数信息表了.我们⽤IDA打开.根据表结构可以很⾃然的就能到.catch块的位置.
IDA实战.
1.到函数信息表点击进去
可以看到MaicNumber等等⼀些列的东西.
,通过最后⼀个成员,可以到Try块信息表.
2.到Try块信息表
可以看到Try块信息表中有⼏个Catch信息.
3.到Catch信息表.
看到最后是catch的回调地址,⾥⾯则是catch的位置.
我们也能看到类型是什么.⾃⼰点击进去看看即可.
4.到Catch函数地址,点击查看.
正确到了Catch块了.
2.下半部分表格详解.
上⾯的部分是针对我们还原做的.下半部分主要就是我要快速定位这个异常是谁接受的,那个catch块处理的.
第⼀个表异常抛出表,重要字段catch数组表
第⼆个表是个数组表,⼀个throw对应多个catch,所以有个数组,这个数组是异常匹配表.表明了有多少个catch可以匹配.
⼀个记录个数,第⼆个成员则是⼆级指针.其内容是⼀个地址,其地址是⼀个cathc信息块的结构.
实战演练.
关于异常抛出表要怎么寻,还记得的我们的⾼级代码有⼀个 throw吗?,其位置就是抛出异常表的位置.
关于抛出异常,我们需要了解的知识.当我们抛出⼀个常量或者变量的时候,不管怎么样,都会建⽴⼀个内存单元来接受我们抛出的值.所以别看你抛出的是常量,其实也成为内存单元了,也相当于⼀个变量了.
1.到异常信息表.
最后⼀个成员是catch表.这个表保存了可以匹配的catch有多少个.
2.到catch异常信息匹配表.
可以看出,值为1,下⾯是⼀个catch表,表明了有⼀个匹配的.
3.到catch信息表.
通过异常信息表的第⼆个参数,也就是类型表,可以看是哪个匹配的.⽽且对类型表做⼀个引⽤,看谁引⽤类类型表,则能到catch的函数地址.当然这⼀步是还原的动作.
4.到类型表.对类型表做⼀个交叉引⽤.
如果引⽤显⽰的太少了,可以⾃⼰百度, IDA引⽤数量调整.看怎么设置的,或者当前位置按 x键查看.
如果按x,跳过去的是try块表,你需要通过try块表可以直接查看.那个catch信息表.
今天讲的主要是表结构.如果想对每⼀个成员都了解,并且想知道怎么跟出来了. 可以看⼀下书籍 <<C++反汇编与逆向分析揭秘>>也就是⼀本⼩黄书.
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论