了解PE结构是多么的重要,不管你是想加密程序,还是想编写病毒,逆向等。
下面就结合具体PE文件,剖析一下结构,以前也见过不少,但都没有把具体实例联系起来,因时间关系,不可能一下子就写的很完善,如可行,以后再慢慢补来。
对于本文件,红色外框将文件分成4个部分,各部分的内容是:
Ⅰ - 文件头;
Ⅱ - 代码段;.text section
Ⅲ - 引入表;.rdata section
Ⅳ - 数据段;.data section
可以看出,每部分都有大量的垃圾数据,用绿色的叉号进行标注。
我们先从整体看一下文件的结构:(要结合PE剖析图来看)
----------------------------------------------------------
1、IMAGE_DOS_HEADER
虽然你这是Windows下的程序,但保不准别人会拿它到DOS下执行,当然肯定不是想象的结果啦。该文件头和DOS下可执行文件的文件头基本上是一样的,所以你也可以认为它是一个标准的DOS下的EXE文件,只不过程序执行的结果是显示一个错误信息:This program cannot be run in DOS mode.,意思是这是Windows下的程序,到Windows下用吧!
该结构的最后一个元素e_lfanew指示PE文件头的位置,是个重要的数据。
对本例,该元素位于文件偏移量是3C的位置,其值是000000B0。
2、dos下执行时的程序部分
3、dos执行时显示的错误信息
4、垃圾数据
-----------------------------------------------------------
就是PE文件头啦,它是一个IMAGE_NT_HEADERS STRUCT结构
5、PE文件标记,db 'PE',0,0
6、是一个IMAGE_FILE_HEADER结构
7、是一个IMAGE_OPTIONAL_HEADER结构
8、是一个IMAGE_DATA_DIRECTORY结构数组,共16项
9、是一个IMAGE_SECTION_HEADER结构数据,项数由结构6中 NumberOfSections 确定。
本例中位于偏移量B6处,其值是0003
-------------------------------------------------------------
10、程序的代码部分,也就是.text section的内容
-------------------------------------------------------------
下面是.rdata section的内容,注意这里的指针值都是“虚拟地址”,即在内存执行时的地址。
11、IDA (Import Address table)用来存放函数的地址值。加载器执行文件时会重写该部分内容,程序中调用dll中的函数就是通过这里转到函数的真正位置的。
12、是一个IMAGE_IMPORT_DESCRIPTOR结构数组,项数怎么定呢?
这么说吧,假如你的程序中要调用N个动态链接库中的函数,那么项数就是N+1,总后一项结构中的数据全0,表示结束。
本例中的程序仅调用Kernell32.dll中的函数,所以此处有两个这样的结构。
13、是一个IMAGE_THUNK_DATA结构数组,该结构实际就是一个DWORD值,每个DWORD值指示一个IMAGE_IMPORT_BY_NAME结构,反应程序要调用的函数名。最后一个DWORD值为0,表示结束。
14、数据,由12、13中的内容指定。
=========================================================
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)