PE结构

PE格式;应用于32位windows系统(这种结构,每两位组成一个数据,但高位在后,低位于前,如4c01 =14Ch)

PE的基本结构:

 

调试信息

 

 

块表

 

PE文件头

 

DOS部首

 

一.任一个PE文件都以一个DOS部首开始!存在的意义类似于一个if then else结构,判断此PE文件是否适应当前操作系统,将简单地显示一个错误信息,除此之外跳向PE文件头继续执行。PE文件头以下将会是我们着重分析的部分。

二.PE文件头以PE/0/0字串开始!其后是映象文件头,再后是可选映象文件头!

1.PE/0/0:占4位空间,即   5045 0000

2.映象文件头:共长20位!

(1)   可执行文件的CPU类型,长2位。如 4C01   =14Ch

 

机器

 

Intel i386

 

Mips r3000

 

Mips r4000

 

Alpha axp

 

Power  pc

 

标志

 

14Ch

 

162h

 

166h

 

184h

 

1F0h

(2)   块数目,长2位。如 0300   =03h

(3)   时间日期标记,长4位。如 2C97 B83D

(4)   调试信息,长4位。 0000 0000

(5)   符号数,长4位。 0000 0000

(6)   可选部首长度,长2位,在OBJ中,为0, 执行文件中指向可选映象头结构的长度。如 E000   =E0h

(7)   文件属性,长2位,有选择地通过几值的运算得到!如 0F01

 

特征值

 

含义

 

1h

 

重定位信息被除去

 

2h

 

文件可执行

 

4h

 

行号被除去

 

8h

 

符号被除去

 

80h

 

处理机的低位字节是相反的

 

100h

 

32位机器

 

200h

 

.DBG文件的调试信息被除去

 

400h

 

如果映象文件是在可移动媒体中,则先复制到交换文件后再运行

 

800h

 

如果映象文件是在网络中,则复制到交换文件后才运行

 

1000h

 

系统文件

 

2000h

 

文件是DLL文件

 

4000h

 

文件只能运行在单处理器上

 

8000h

 

处理机的高位字节是相反的

所以,我们把所有的映象文件头例子合起来,就是这样

长20位:

4c01 0300 2c97 b83d 0000 0000 0000 0000 e000 0f01

3.可选映象头:(一个可选结构)长112位!

(1)幻数,说明文件是ROM映象,长度2位,一般是0B01    =10Bh 数,说明文件是ROM映象,长度2位,一般是0B01    =10Bh

(2)链接程序的主版本号,长1位, 如  05

(3)链接程序的次版本号,长1位, 如  0C

(4)代码段大小,长度4位,如 0002 0000

(5)已初始化数据块的大小,长度4位,如 0004 0000

(6)未初始化数据块的大小,长度4位,如 0000 0000

(7)程序开始执行的入口地址,长度4位,如 0010 0000

(8)   代码段的入口地址,长度4位,如 0010 0000

(9)   数据段的起始地址,长度4位,如 0020 0000

(10)       可执行文件默认装入的基地址,长4位,如 0000 4000

          所以(10)和(8)组成了我们熟悉的401000

(11)       内存中块的对齐值,长度4位,一般默认为0010 0000  =1000h

(12)       文件块的对齐值,长度4位,如 0002 0000

(13)       要求操作系统的最低版本号的主版本号,长2位,如 0400

(14)       要求操作系统的最低版本号的次版本号,长2位,如 0000

(15)       该可执行文件的主版本号,长2位,如 0400

(16)       该可执行文件的次版本号,长2位,如 0000

(17)       要求最低子系统版本的主版本号,长2位,如 0400

(18)       要求最低子系统版本的次版本号,长2位,如 0400

(19)       保留,长4位,  0000 0000

(20)       映象装入内存后的总尺寸,长4位,如 3830 0000

(21)       部首及块表的大小,长4位,如 0004 0000

(22)       CRC检验和,一般的exe可以为0,但重要的dll必须要有,长4位,           如 A720 0000

(23)       程序使用的用户接口子系统,长2位,如 0200

 

 

子系统

 

 

未知

 

 

不需要子系统

 

 

图形接口子系统

 

 

字符子系统

 

 

OS/2字符子系统

 

 

POSIX字符子系统

 

 

保留

(24)       DllMain()函数何时被调用,长2位,默认为0000

(25)       为线程保留的堆栈大小,长4位,如 0000 1000

(26)       当线程初始化时提交堆栈的大小,长4位, 如 0010 0000

(27)       为进程的默认堆栈保留的内存,长4位, 如 0000 1000

(28)       进程初始化时提交的默认堆大小,长4位,如 0010 0000

(29)       与调试无关,长4位,默认为 0000 0000

(30)       数据目录的项数,长4位,如 1000 0000

(31)       数据目录表,长8×16位,如其名,是数据的目录表,包含16组数据目录,每组长8位,前4位是地址,后4位是大小!

 

 

序号

 

成员

 

长度

 

示例

 

1

 

Export table

 

8

 

0000 0000 0000 0000

 

2

 

Import table

 

8

 

4020 3c00 0000 0000

 

3

 

Resources table

 

8

 

0000 0000 0000 0000

 

4

 

Exception table

 

8

 

0000 0000 0000 0000

 

5

 

Security table

 

8

 

0000 0000 0000 0000

 

6

 

Base relocation table

 

8

 

0000 0000 0000 0000

 

7

 

Debug

 

8

 

0000 0000 0000 0000

 

8

 

Copyright

 

8

 

0000 0000 0000 0000

 

9

 

Global ptr

 

8

 

0000 0000 0000 0000

 

10

 

Thread local strorage(TLS)

 

8

 

0000 0000 0000 0000

 

11

 

Load configuration

 

8

 

0000 0000 0000 0000

 

12

 

Bound import

 

8

 

0000 0000 0000 0000

 

13

 

Import address table(IAT)

 

8

 

0020 0000 4000 0000

 

14

 

Delay import

 

8

 

0000 0000 0000 0000

 

15

 

Com escriptor

 

8

 

0000 0000 0000 0000

 

16

 

保留

 

8

 

0000 0000 0000 0000

本次示例中表无输出表,输入表地址0x2040 大小0x3C,输入地址表(IAT)地址0x2000 大小0x40[看得出来,输入地址表刚好就是输入表前面的那0x40空间,:]]

 

于是,我们把可选映象头所有31项例子组合起来,将是一个完整的可先映象头在PE体中的结构:长6x16+8x16位

0b01 050c 0002 0000 0004 0000 0000 0000 0010 0000 0010 0000 0020 0000 0000 4000 0010 0000 0002 0000 0400 0000 0400 0000 0400 0000 0000 0000 3830 0000 0004 0000 a720 0000 0200 0000 0000 1000 0010 0000 0000 1000 0010 0000 0000 0000 1000 0000 0000 0000 0000 0000 4020 0000 3c00 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0020 0000 4000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000

 

4.接下来是块表:块表将是不定总长度的了,但块单项长度是定的,长20位,总长将是块数x20!

(1)块名,是长8位的ASCII码名,如 2E74 6578 7400 0000       =[.text]

(2)该块的真实长度,长4位,如 9A01 0000

(3)该块装载到内存中的RVA,长4位, exe中默认为1000h 即 0010 0000

(4)该块在磁盘文件中所占的在小,长4位, 如 00002 00000

(5)该块在磁盘文件中的偏移,长4位,如 0004 0000

(6)此部分在exe中无意义,占4位, 0000 0000

(7)行号表在文件中的偏移值,是文件的调试信息,占4位,如 0000 0000

(8)exe中无意义,长2位,0000

(9)该块在行号表中的行号数目,长2位, 可以如 0000 0000

(10)块属性,长4位,是多个标志值求或的值

 

字段值

 

用途

 

00000020h

 

包含执行代码,常与10000000h一起设置

 

00000040h

 

包含已初始代的数据

 

00000080h

 

包含未初始化的数据

 

02000000h

 

可丢弃块属性

 

10000000h

 

共享块属性

 

20000000h

 

可执行块属性

 

40000000h

 

可读

 

80000000h

 

可写

常用的主要以

C0000040h     可读可写,包含初始化数据

E0000020h   可读可写并可执行

60000020h   可读可执行 

所以,块表单项属性20位为:(以.text块表为例)

2e74 6578 7400 000 9a01 0000 0010 0000 0002 0000 0004 0000 0000 0000 0000 0000 0000 0000 2000 00060

 

ok, 从PE/0/0到块的长度是定的,所以

PE结构体实例代码如下:

 

Dos部首

 

if then else结构的东东!

 

PE/0/0

 

5045 0000

 

映象文件头

 

4c01 0300 2c97 b83d 0000 0000 0000 0000 e000 0f01

 

可选映象文件头(不含数据目录表)

 

0b01 050c 0002 0000 0004 0000 0000 0000 0010 0000 0010 0000 0020 0000 0000 4000 0010 0000 0002 0000 0400 0000 0400 0000 0400 0000 0000 0000 3830 0000 0004 0000 a720 0000 0200 0000 0000 1000 0010 0000 0000 1000 0010 0000 0000 0000 1000 0000

 

可选映象文件头之数据目录表

 

0000 0000 0000 0000 4020 0000 3c00 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0020 0000 4000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000

 

块表(单项,以text块为例)

 

2e74 6578 7400 000 9a01 0000 0010 0000 0002 0000 0004 0000 0000 0000 0000 0000 0000 0000 2000 00060

 

 

真正执行的程序功能代码

连起来就是:

 

……从PE/0/0标志开始

5045 0000 4c01 0300 2c97 b83d 0000 0000 0000 0000 e000 0f01 0b01 050c 0002 0000 0004 0000 0000 0000 0010 0000 0010 0000 0020 0000 0000 4000 0010 0000 0002 0000 0400 0000 0400 0000 0400 0000 0000 0000 3830 0000 0004 0000 a720 0000 0200 0000 0000 1000 0010 0000 0000 1000 0010 0000 0000 0000 1000 0000 0000 0000 0000 0000 4020 0000 3c00 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0020 0000 4000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 2e74 6578 7400 000 9a01 0000 0010 0000 0002 0000 0004 0000 0000 0000 0000 0000 0000 0000 2000 00060到第一块属性表例

……

这就是所谓的PE结构,并不复杂!

 

怎么才叫已知PE格式呢,看完这一PE通俗篇!

 

 

附带1.输入表结构通俗性理解篇

 

输入地址表

 

输入表

 

函数名表

输入表和输入地址表位置在上面PE格式中的可选映象头之数据目录表中可以找到,这里不再重复(现在也可回头去看看,小学时的老师就说过了:不清楚的查字典!)。

1.  输入表:

故名思意,一张表,跟块表一样,是一张表,由多个单项组成,但所有单项是结构是统一 的,相同。输入表,有多少函数输入,就有多少项,结果相同!

表数据各4位,共20位!

实例:

 

指向函数对应地址

 

时间标志(可忽略)

 

链接索引(一般为0)

 

指向dll名

 

指向函数名

 

8C20 0000

 

0000 0000

 

0000 0000

 

7421 0000

 

1020 0000

 

指向输入地址表空间

 

 

 

 

 

 

 

指向函数名表空间

 

77DFBD20

 

 

 

 

 

 

 

LoadIconA

即:   8c20 0000 0000 0000 0000 7421 0000这样就表示一项输入函数信息!

用简单的汇编指令来表示(还是那句话,不清楚的查字典):

dword ptr DS:[208C]=‘77DFBD20’

dword ptr DS:[2174]=‘user32.dll’

dword ptr DS:[2010]=‘LoadIconA’

另外,这种表示法在汇编里面基本上是不成立的,只是借指令意思来说明!:)

即通过这张表把函数名与地址联系在一起来了!

2.输入地址表就是一些4位长的表示地址的数据组成的一张表!

2.  存贮函数名的空间!

 

 

附带2.绑定输入

算是绑定dll吧,可选映象头之数据目录表中有绑定输入项,指向绑定输入起始地址!

 

结构:

 

绑定结构表

 

Dll名表

1.  绑定结构名表,是表,由单项或多项组成,有多少Dll引入就有多少项,每一项结构一样!长8位,前4位是时间/日期戳,第5、6位指向dll名表中相应dll名(是相对偏移,相对于绑定输入起始地址的偏移),最后2位保留。

例:

 

时间/日期戳

 

指向dll名表中相应dll名

 

保留

 

75DA 3837

 

3800

 

0000

即75da 3837 3800 0000

2.Dll名表是dll名存贮空间!

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值