PE头解析

这两天对于PE的学习总结:

1.PE结构的应用

(1)windows下exe文件

(2)动态链接库(大部分是以dll为扩展名得文件)

2.关于PE分节

(1)节省硬盘空间   (2)一个应用程序多开

对齐 旧式的电脑新款
硬盘对齐   200h   1000h
内存对齐 1000h   1000h

3.PE整体结构

DOS头              NT头              节表/块表              .text块               .rdata块                 data块

(后面这几个快不确定位置和数量,这些由节表确定)

 

下面介绍的都是几个头中重点的几个标识,所以详细的自己百度

 

4.    DOS头(一般运用在16位系统中 )

                        
WORD   e_magic                *                  "MZ标记" 用于判断是否为可执行文件.  (即判断是否在windows上执行)          
DWORD  e_lfanew;             *                  PE头相对于文件的偏移,用于定位PE文件 

DOS头和NT头之间由垃圾数据填充

5.NT头

NT头分为三部分(1)PE标记(2)标准PE头(3)可选PE头

1)PE标记   

dword   signature   (由DoS头里e_lfanew确定位置)

2)标准PE头     fileheader 

          WORD    Machine;              *                程序运行的CPU型号:0x0 任何处理器/0x14C 386及后续处理器                        
          WORD    NumberOfSections;     *        文件中存在的节的总数,如果要新增节或者合并节 就要修改这个值.                   
          DWORD   TimeDateStamp;        *        时间戳:文件的创建日期和时间(和操作系统的创建时间无关),编译器填写的.  
          DWORD   PointerToSymbolTable;                                         
          DWORD   NumberOfSymbols;                                         
          WORD    SizeOfOptionalHeader; *       可选PE头的大小32位PE文件默认E0h 64位PE文件默认为F0h  大小可以自定义.  
          WORD    Characteristics;      *              文件属性,每个位有不同的含义,普通exe文件值为10Fh 即0 1 2 3 8位置1                                                                                                                                            Dll文件一般是210Eh

(3)可选pe头   optionalheader(由标准pe头里sizeOfOptionalHeader确定)

WORD    Magic;        *                说明文件类型:10B 32位下的PE文件     20B 64位下的PE文件                        
BYTE    MajorLinkerVersion;                                        
BYTE    MinorLinkerVersion;                                        
DWORD   SizeOfCode;*                所有代码节的和,必须是FileAlignment的整数倍 编译器填的  没用                        
DWORD   SizeOfInitializedData;*                已初始化数据大小的和,必须是FileAlignment的整数倍 编译器填的  没用                      
DWORD   SizeOfUninitializedData;*                未初始化数据大小的和,必须是FileAlignment的整数倍 编译器填的  没用                 
DWORD   AddressOfEntryPoint;*                程序入口                        
DWORD   BaseOfCode;*                代码开始的基址,编译器填的   没用                        
DWORD   BaseOfData;*                数据开始的基址,编译器填的   没用                        
DWORD   ImageBase;*                内存镜像基址                        
DWORD   SectionAlignment;*                内存对齐                        
DWORD   FileAlignment;*                文件对齐                        
WORD    MajorOperatingSystemVersion;                                        
WORD    MinorOperatingSystemVersion;                                        
WORD    MajorImageVersion;                                        
WORD    MinorImageVersion;                                        
WORD    MajorSubsystemVersion;                                        
WORD    MinorSubsystemVersion;                                        
DWORD   Win32VersionValue;                                        
DWORD   SizeOfImage;*             内存中整个PE文件的映射的尺寸,可以比实际的值大,但必须是SectionAlignment的整数倍     
DWORD   SizeOfHeaders;*          所有头+节表按照文件对齐后的大小,否则加载会出错                        
DWORD   CheckSum;*                校验和,一些系统文件有要求.用来判断文件是否被修改.                        
WORD    Subsystem;                                        
WORD    DllCharacteristics;                                        
DWORD   SizeOfStackReserve;*                初始化时保留的堆栈大小                         
DWORD   SizeOfStackCommit;*                初始化时实际提交的大小                     DOS    
DWORD   SizeOfHeapReserve;*                初始化时保留的堆大小                     ...    
DWORD   SizeOfHeapCommit;*                初始化时实践提交的大小                     PE标记    
DWORD   LoaderFlags;                                    标准PE    
DWORD   NumberOfRvaAndSizes;*                目录项数目                    可选PE头    


6.节表(由标准PE头里NumberOfsections可知节表数目)

#define IMAGE_SIZEOF_SHORT_NAME      8                                       
typedef struct _IMAGE_SECTION_HEADER {                    
    BYTE    Name[IMAGE_SIZEOF_SHORT_NAME];                    
    union {                    
            DWORD   PhysicalAddress;                    
            DWORD   VirtualSize;                    
    } Misc;                    
    DWORD   VirtualAddress;                    
    DWORD   SizeOfRawData;                    
    DWORD   PointerToRawData;                    
    DWORD   PointerToRelocations;                    
    DWORD   PointerToLinenumbers;                    
    WORD    NumberOfRelocations;                    
    WORD    NumberOfLinenumbers;                    
    DWORD   Characteristics;                    
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;

                    
1、Name    8个字节 一般情况下是以"\0"结尾的ASCII吗字符串来标识的名称,内容可以自定义.    
注意:该名称并不遵守必须以"\0"结尾的规律,如果不是以"\0"结尾,系统会截取8个字节的长度进行处理.
2、Misc  双字 是该节在没有对齐前的真实尺寸,该值可以不准确。               
3、VirtualAddress 节区在内存中的偏移地址。加上ImageBase才是在内存中的真正地址.    
4、SizeOfRawData  节在文件中对齐后的尺寸                    
5、PointerToRawData 节区在文件中的偏移.                    
6、PointerToRelocations 在obj文件中使用 对exe无意义            
7、PointerToLinenumbers 行号表的位置 调试的时候使用            
8、NumberOfRelocations 在obj文件中使用  对exe无意义
9、NumberOfLinenumbers 行号表中行号的数量 调试的时候使用
10、Characteristics   *       节的属性    

(这是一个节表信息,几个节表信息连续)

7.三种不同的地址

文件中的地址(FA): 在文件地址空间中,文件载入的起始位置总是等于0,FA地址表现为一个偏移地址;

虚拟地址(VA):PE文件被映射到内存中时,在内存中的映射地址;

相对偏移地址(RVA):程序某一结构的VA减去FA的结果;

程序被装载入内存中时,由文件结构不变,故其RVA不变,但装载起始地址不变,因为很难保证计算机的运行状态时时刻刻都是一致的。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值