最近学习了《加密与解密 第三版》的第10章和第11章,书上的例子基本上看了一遍,但是总觉得学得不深入,还有些内容没有理解。于是就想找个题目来练练手。

下面附件里面是我学习之后的笔记。

注意:这里的笔记并不是书本上的例子的再次介绍,而是我另外找了一个程序来练习之后的笔记。

希望能对大家的学习有所帮助。

=================================
PE文件格式和结构化异常处理 学习后记

最近学习了《加密与解密 第三版》的第10章和第11章,书上的例子基本上看了一遍,但是总觉得学得不深入,还有些内容没有理解。于是就想找个题目来练练手。偶然间整理电脑上的文件,找到了一个程序(见附件)EraseDrx。从程序名称上来看,应该是反调试的。。。

双击程序,似乎没有任何动静,但是调出任务管理器后,就会发现进程EraseDrx,看来这个程序有问题。我就OD载入。
程序很短,肯定是用汇编语言编写的,一个图就把可以全部代码贴出来(注释很清楚,直接看代码就可以明白程序的功能)。

 

程序很简单,首先安装一个异常处理函数,然后在00401013处故意产生异常未定义指令,进入SEH handle00401026(需要事先在此处按F2下INT 3断点)。在这个异常处理函数中,修改了由回调函数的第三个参数指向的CONTEXT结构,具体来说,就是清零了5个调试寄存器iDr0~iDr3和iDr7,并且修改了regEip的值。回调函数返回后,先是执行一段系统代码,然后就会返回00401015,最后卸载异常处理函数。这个程序就这么简单,只是演示了如何利用SEH来清除硬件断点。

可是你如果OD调试这个程序的话,就会发现一个问题程序执行完00401025后不会退出,OD显示程序一直在运行。(程序都返回了,还运行哪里的代码???)我猜想:程序没有调用ExitProcess函数就不会退出,而会一直运行下去(至于程序现在到底在运行哪里的代码,我就不知道了,希望高人指点)。从程序的反汇编代码上看,的确没有调用任何API。使用Stud_PE分析,发现这个程序竟然没有输入表!!!

为了使程序能够正常退出,我想到可以用刚刚学到的知识,给这个程序手动添加输入表,并且调用ExitProcess函数。
又看了下书本上关于输入表的知识。准备动手了。本来打算用WinHex来编辑PE的,但是电脑上这个程序不知道放到哪里了,现在又懒得去下载,就直接使用OD修改了。后来才发现,其实使用OD修改有很多方便之处的,比如说IID数组,INT数组里面的指针,都是RVA,OD里面可以直接看到VA,这样就省掉了RVA和File offset之间的转换这一步。当然,其实两者之间的转换也并不复杂。
下面说一下修改的过程:
由于只有一个区段,并且这个区段有很多空闲的地方,所以我就把IID,IAT,INT,以及一些字符串都放在这个区段了。然后修改区段(OD反汇编面板里面右键---二进制---编辑),构造出IID数组,INT数组,IAT数组(这里我将INT数组和IAT数组当作同一个数组),以及字符串kernel32.dll,ExitProcess。需要注意的是,IID数组,INT数组,IAT数组都是以一个全零的元素结束的,字符串ExitProcess前面两个字节填充0(IMAGE_IMPORT_BY_NAME.hint)。然后还要修改程序的代码,最后00401025处的ret指令需要改为jmp XXXXXX,由于一个字节空间不够容纳jmp XXXXXX的机器码,刚好前面还有一些可有可无的NOP,于是把代码向前移动,这样就可以腾出足够的空间了。

 

然后还要修改PE的文件头,其实只用修改数据目录表里面的输入表就可以了。好了,就说这么多了。修改后的程序(EraseDrx--.exe)也在附件里面。
总结一下,通过这个程序,我们学习了异常处理SEH和PE输入表。希望我的文章能给大家带来帮助。

上传的附件 EraseDrx.rar