PE格式详解讲解1

这篇文章主要转载自小甲鱼的加密解密部分,然后补充加上我自己的少许内容,原文地址–>传送门
下面的内容主要是围绕这个图来进行
这里写图片描述

MS-DOS头部

这个头部是为了兼容早期的DOS系统,PE文件的第一个字节起始于一个传统的MS-DOS头,被称为IMAGE_DOS_HEADER,这个结构体完整的定义如下:

(注:最左边是文件头的偏移量。) 
IMAGE_DOS_HEADER STRUCT 
{ 
+0h WORD    e_magic        //   Magic DOS signature MZ(4Dh 5Ah)     DOS可执行文件标记 
+2h     WORD    e_cblp     //   Bytes on last page of file            
+4h WORD    e_cp       //   Pages in file                   
+6h WORD    e_crlc     //   Relocations                     
+8h WORD    e_cparhdr   //  Size of header in paragraphs        
+0ah    WORD    e_minalloc   // Minimun extra paragraphs needs      
+0ch    WORD    e_maxalloc  //  Maximun extra paragraphs needs  
+0eh    WORD    e_ss            //  intial(relative)SS value        DOS代码的初始化堆栈SS 
+10h    WORD    e_sp        //  intial SP value                       DOS代码的初始化堆栈指针SP 
+12h    WORD    e_csum      //  Checksum 
+14h    WORD    e_ip        // intial IP value                    DOS代码的初始化指令入口[指针IP] 
+16h    WORD    e_cs        //  intial(relative)CS value         DOS代码的初始堆栈入口 
+18h    WORD    e_lfarlc        //  File Address of relocation table 
+1ah    WORD    e_ovno         // Overlay number 
+1ch    WORD    e_res[4]         // Reserved words 
+24h    WORD    e_oemid          // OEM identifier(for e_oeminfo) 
+26h    WORD    e_oeminfo   // OEM information;e_oemid specific  
+29h    WORD    e_res2[10]   // Reserved words 
+3ch    DWORD   e_lfanew     //  Offset to start of PE header      指向PE文件头 
} IMAGE_DOS_HEADER ENDS

这个头中只有两个需要重点关注:
e_magic:DOS可执行文件的标记,一般是两个字节,标记值是固定的,只有当其值是4D5A的时候,这个文件才被识别为可执行文件,这个结构在文件头位置
e_lfanew:指向PE文件头的指针,这个在偏移3c处
利用UE来分析可以看到,这两个在文件中的位置如下:
这里写图片描述

PE文件头

PE Header 是PE相关结构NT映像头(IMAGE_NT_HEADER)的简称,里边包含着许多PE装载器用到的重要字段。装载到内存中时,PE状态器将从IMAGE_DOS_HEADER结构中的e_lfanew字段中岛PE Header的起始偏移量,加上基地址就得到PE文件的头指针PEHeader = ImageBase + DosHeader->e_lfnew

IMAGE_NT_HEADERS STRUCT 
{
+0h       DWORDSignature  
+4h       IMAGE_FILE_HEADER FileHeader 
+18h      IMAGE_OPTIONAL_HEADER32OptionalHeader   
} IMAGE_NT_HEADERS ENDS

Signature字段

在一个有效的 PE 文件里,Signature 字段被设置为00004550h, ASCII 码字符是“PE00”。标志这 PE 文件头的开始。
“PE00” 字符串是 PE 文件头的开始,DOS 头部的 e_lfanew 字段正是指向这里。一般如果需要验证一个文件是否为PE文件就要验证这个标志是否为这个值

FileHeader字段

这个字段是一个IMAGE_FILE_HEADER结构,他的定义如下:

struct IMAGE_FILE_HEADER
{
    WORD Machine; //运行平台
    WORD NumberOfSections; //区块表的个数
    DWORD TimeDataStamp;//文件创建时间,是从1970年至今的秒数
    DWORD PointerToSymbolicTable;//指向符号表的指针
    DWORD NumberOfSymbols;//符号表的数目
    WORD SizeOfOptionalHeader;//IMAGE_NT_HEADERS结构中OptionHeader成员的大小,对于win32平台这个值通常是0x00e0
    WORD Characteristics;//文件的属性值
}

(1)Machine:可执行文件的目标CPU类型,记载可执行文件的目标CPU类型,各个值表示的平台如下:

Value Meaning
IMAGE_FILE_MACHINE_I386 0x014c x86
IMAGE_FILE_MACHINE_IA64 0x0200 Intel Itanium
IMAGE_FILE_MACHINE_AMD64 0x8664 x64

(2)NumberOfSection: 区块的数目。(注:区块表是紧跟在 IMAGE_NT_HEADERS 后边的)
(3)TimeDataStamp: 表明文件是何时被创建的。
这个值是自1970年1月1日以来用格林威治时间(GMT)计算的秒数,这个值是比文件系统(FILESYSTEM)的日期时间更加精确的指示器。
(4)PointerToSymbolTable: COFF 符号表的文件偏移位置,现在基本没用了。
(5)NumberOfSymbols: 如果有COFF 符号表,它代表其中的符号数目,COFF符号是一个大小固定的结构,如果想找到COFF 符号表的结束位置,则需要这个变量。
(6)SizeOfOptionalHeader: 紧跟着IMAGE_FILE_HEADER 后边的数据结构(IMAGE_OPTIONAL_HEADER)的大小。(对于32位PE文件,这个值通常是00E0h;对于64位PE32+文件,这个值是00F0h )。
(7)Characteristics: 文件属性,有选择的通过几个值可以运算得到。( 这些标志的有效值是定义于 winnt.h 内的 IMAGE_FILE_** 的值,具体含义见下表。
普通的EXE文件这个字段的值一般是 0100h,DLL文件这个字段的值一般是 210Eh。)小甲鱼温馨提示:多种属性可以通过 “或运算” 使得同时拥有!
这里写图片描述
下面分析上述程序中的IMAGE_NT_HEADERS 结构:
这里写图片描述
PE文件头的标记为0x00004550
后面所有方框都是IMAGE_FILE_HEADER的内容:
运行平台的值为0x014c,查上面的表得知,它是运行在intel x86平台下
区块表的个数为0x0007
文件创建时间为0x5848fc56
指向符号表的指针为NULL,也就是没有符号表,符号表是用于调试的,在这即使没有这个东西也不影响调试
符号表的数目为0
OptionHeader成员的大小为0x00e0
文件的属性值为0x0102

posted @ 2017-10-24 20:55  masimaro  阅读(394)  评论(0编辑  收藏  举报