转移自之前的博客

judge PE

简单的判断文件是否为pe文件:

  1. pe 指纹: 开头为 4D 5A (MZ); 3C 处为一个值 ; 查找该值的地址为 50 45(PE)。

PE 文件概论

PE(portable Executable)windows系统下的可执行文件格式

1 . 32位可执行文件-PE32 ;

64位可执行文件-PE+/PE32+ ,是PE文件的扩展形式。
  1. 分类:可执行系列 exe scr ;库系列 dll ocx cpl drv ;驱动程序系列 sys vxd ;对象文件系列 obj (唯一不可执行)。

  2. 基本结构

    1

    1

DOS头到节区头是PE的头部分;

文件中使用偏移offset,内存中使用VA(virtual address 虚拟地址)表示位置;

  1. VA指进程虚拟内存的绝对地址,RVA指从某个基准位置开始的相对地址。

RVA+ImageBase=VA

PE头(1)

DOS部分

2

2

  1. DOS头:IMAGE_DOS_HEADER结构体 –0x40个字节
1
2


3

3

1
2
e_magic:DOS签名(4D5A 签名值MZ)
e_lfanew:指示NT头的偏移(小端序标识法)
  1. DOS存根(stub) –可选项,大小不固定/DOS环境才会执行

PE文件头部分

  1. NT头: IMAGE_NT_HEADERS结构体 –32位:0xF8个字节。64位: 0x108
4

4

1
2
3
签名(50450000)
标准PE header: 20个字节
可选头。
  • 标准PE header:IMAGE_FILE_HEADER结构体
    5

    5

    该结构体重要成员(设置不正确,程序无法运行)
6

6

7

7

8

8

  • 可选头: IMAGE_OPTIONAL_HEADER32
    9

    9

    (PE头结构体中最大的)

重要成员

10

10


11

11


12

12

  • 节区头: IMAGE_SECTION_HEADER
    13

    13

    不同内存属性访问权限:code rwx /data rw /resource r
    14

    14

    重要成员

PE头(2)

  1. 内存地址与文件偏移间的映射:RVA to RAW(即file offset)

公式:RAW - PointerToRawData = RVA -VirtualAddress

RAW = RVA -VirtualAddress + PointerToRawData

15

15


eg:

RVA = 5000 位于第一节区(.text),VA = 1000(该节区内存的的起始地址),

PointerToRawData= 400 (该节区文件的起始地址) 。

RAW = 5000 -1000 +400 =4400.

  1. DLL(动态链接库)

不把库包含在程序中,而是单独组成DLL文件,需要时调用即可/更新库时只需要替换DLL文件即可/内存映射使加载后的DLL代码,资源在多个进程中实现共享。

Windows版本不同,环境不同,被调用函数的位置(地址)也不相同。

  • 为了确保在所有环境中都能正常调用被调用函数,编译器保存了被调用函数实际地址的位置。PE装载器将被调用函数的地址写到该位置。

  • DLL重定位。DLL的ImageBase默认为1000000,若某个程序使用a.dll与b.dll时,a已被装载到内存的10000000处,PE装载器只能查找其他空白的内存空间,将b装载进去。

  • PE头表示地址用RVA 而不是VA。

3.IAT(Import Address Table 导入地址表):用来记录程序正在使用库中的哪些函数。