PE 文件
目录
一、
二、
三、
四、
PE 文件总述.......................................................................................................................2
1、PE 文件和 COM 文件 ...........................................................................................................2
2、PE 文件基本结构 .................................................................................................................2
DOS 头 ................................................................................................................................ 3
PE 文件头........................................................................................................................... 4
1、PE 标识 ................................................................................................................................. 4
2、映像文件头 IMAGE_FILE_HEADER ......................................................................................4
3、可选映像头文件 ..................................................................................................................5
节表和节............................................................................................................................ 8
1、节表...................................................................................................................................... 8
2、RVA 和 FOA........................................................................................................................... 9
3、节 .......................................................................................................................................... 9
修改思路.......................................................................................................................... 14
1、基本.................................................................................................................................... 14
2、进阶.................................................................................................................................... 14
实现.................................................................................................................................. 15
1、修改后文件 ........................................................................................................................15
1、查找序列号的错误打开方式和正确打开方式 ............................................................... 16
五、
六、
一、 PE 文件总述
PE(Portable Executeable File Format,可移植的执行体文件格式),Windows
操作系统中可执行程序有好多种,比如 COM、PIF、SCR、EXE 等,这些文件的格
式大部分都继承自 PE。
1、PE 文件和 COM 文件
COM 文件:在 DOS 时代是最早的、结构最简单的可执行文件,仅包含可执
行代码,没有附带任何“支持性”数据。所以,第一句执行指令必须安排在文件
头部。再就是没有重定位的信息,这样代码中不能有跨段操作数据的指令,造成
代码和数据,甚至包括堆栈只能限制在同一个 64KB 的段中。
EXE 文件:在代码的前面加了一个文件头,文件头中包括各种说明数据,如
文件入口,堆栈位置,重定位表等,操作系统根据文件头的信息将代码部分装入
内存,根据重定位表修正代码,最后在设置好堆栈后从文件头中指定的入口开始
执行。
2、PE 文件基本结构
分为 DOS 部分、PE NT 头(PE 文件头)、节表、节数据
二、 DOS 头
DOS 头即 IMAGE_DOS_HEADER,具体定义如下:
IMAGE_DOS_HEADER STRUCT
+00h WORD e_magic
// Magic DOS signature MZ(MZ)
可改
DOS 可执行文件标记不
// Bytes on last page of file
DOS 代码的初始化堆栈 SS
DOS 代码的初始化堆栈指针 SP
// Pages in file
// Relocations
// Size of header in paragraphs
// Minimun extra paragraphs needs
// Maximun extra paragraphs needs
+02h WORD e_cblp
+04h WORD e_cp
+06h WORD e_crlc
+08h WORD e_cparhdr
+0ah WORD e_minalloc
+0ch WORD e_maxalloc
// intial(relative)SS value
+0eh WORD e_ss
// intial SP value
+10h WORD e_sp
+12h WORD e_csum // Checksum
+14h WORD e_ip
intial IP value
+16h WORD e_cs
+18h WORD e_lfarlc
+1ah WORD e_ovno // Overlay number
+1ch WORD e_res[4]
// Reserved words
+24h WORD e_oemid
+26h WORD e_oeminfo // OEM information;e_oemid specific
+29h WORD e_res2[10]
+3ch LONG e_lfanew // Offset to start of PE header 指向 PE 文件头实际情况
(PE 字母的开始)
IMAGE_DOS_HEADER ENDS
//
// intial(relative)CS value
DOS 代码的初始化指令入口[指针 IP]
DOS 代码的初始堆栈入口 CS
// OEM identifier(for e_oeminfo)
// Reserved words
// File Address of relocation table
(1) 其中第一个字段(2 字节)为字符 MZ,识别标志,如果没有则表明不是
PE 文件。
(2) 最后 4 字节的 e_lfanew 字段,指出了真正的 PE 文件头在文件中的位置。
三、 PE 文件头
PE 文件头是由 IMAGE_NT_HEADERS 结构定义的,分 3 部分(PE 标识、映像
文件头、可选映像文件头):
IMAGE_NT_HEADERS STRUCT
+0h DWORD Signature
+4h
+18h IMAGE_OPTIONAL_HEADER32 OptionalHeader
IMAGE_NT_HEADERS ENDS
IMAGE_FILE_HEADER FileHeader
PE 文件标识不可改
1、PE 标识
开始的 2 字节为标识,为字符 PE,如果不是 PE 则表明不是 PE 文件。
2、映像文件头 IMAGE_FILE_HEADER
Machine;
// 运行平台不必改
NumberOfSections; // 文件的节数目实际情况
TimeDateStamp;
// 文件创建日期和时间
WORD
WORD
DWORD
IMAGE_FILE_HEADER STRUCT
+04h
+06h
+08h
+0Ch
试)
+10h
+14h
DWORD
WORD
DWORD
PointerToSymbolTable; // 指向符号表(主要用于调
NumberOfSymbols;
// 符号表中符号个数(同上)
SizeOfOptionalHeader;// IMAGE_OPTIONAL_HEADER32 结构大
小实际情况(可选映像头大小,包括其末尾的几项)
WORD
Characteristics;
// 文件属性不必改
+16h
IMAGE_FILE_HEADER ENDS
(1) 运行平台:x86 为 0x014c,x64 为 0x8664
(2) NumberOfSymbols: 如果有 COFF 符号表,它代表其中的符号数目,COFF
符号是一个大小固定的结构,如果想找到 COFF 符号表的结束位置,则需
要这个变量
(3) Characteristics: 文件属性,有选择的通过几个值可以运算得到
3、可选映像头文件
Magic; // 标志字, ROM 映像(0107h),普通可执行文件
(1)IMAGE_OPTIONAL_HEADER32 STRUCT
+18h
WORD
(010Bh)不必改
+1Ah
+1Bh
+1Ch
+20h
MajorLinkerVersion;
MinorLinkerVersion;
SizeOfCode;
SizeOfInitializedData;
BYTE
BYTE
DWORD
DWORD
// 链接程序的主版本号
// 链接程序的次版本号
// 所有含代码的节的总大小
// 所有含已初始化数据的节的总
大小
+24h
+28h
DWORD
DWORD
SizeOfUninitializedData; // 所有含未初始化数据的节的大小
// 程序执行入口 RVA 实际情况,指
AddressOfEntryPoint;
令开始的地方
DWORD
DWORD
DWORD
DWORD
+2Ch
+30h
+34h
+38h
(此为 4H)
+3Ch
为 4H)
+40h
DWORD
WORD
BaseOfCode;
BaseOfData;
ImageBase;
SectionAlignment;
// 代码的区块的起始 RVA
// 数据的区块的起始 RVA
// 程序的首选装载地址不必改
// 内存中的区块的对齐大小不必改
FileAlignment;
// 文件中的区块的对齐大小不必改(此
MajorOperatingSystemVersion;
// 要求操作系统最低版本
号的主版本号
+42h
WORD
MinorOperatingSystemVersion;
// 要求操作系统最低版本
号的副版本号
+44h
号
+46h
号
+48h
WORD
MajorImageVersion;
// 可运行于操作系统的主版本
WORD
MinorImageVersion;
// 可运行于操作系统的次版本
WORD
MajorSubsystemVersion;
// 要求最低子系统版本的主版本
+4Ch
话一般为 0
+50h
+54h
号不必改
+4Ah
号
WORD
MinorSubsystemVersion;
// 要求最低子系统版本的次版本
DWORD Win32VersionValue;
// 莫须有字段,不被病毒利用的
DWORD
DWORD
SizeOfImage;
SizeOfHeaders;
// 映像装入内存后的总尺寸别太大
// 所有头 + 区块表的尺寸大小实际
情况,小于代码节开始前即可
DWORD
WORD
WORD
CheckSum;
Subsystem;
DllCharacteristics;
// 映像的校检和
// 可执行文件期望的子系统不必改
// DllMain()函数何时被调用,默认
DWORD
DWORD
SizeOfStackReserve;
SizeOfStackCommit;
// 初始化时的栈大小不必改
// 初始化时实际提交的栈大小
DWORD
SizeOfHeapReserve;
// 初始化时保留的堆大小不必
DWORD
SizeOfHeapCommit;
// 初始化时实际提交的堆大小
+58h
+5Ch
+5Eh
为 0
+60h
+64h
不必改
+68h
改
+6Ch
不必改
DWORD
DWORD
LoaderFlags;
NumberOfRvaAndSizes;
+70h
+74h
自 Windows NT 发布以来一直是 16 实际情况
+78h
DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
IMAGE_OPTIONAL_HEADER32 ENDS
// 与调试有关,默认为 0
// 下边数据目录的项数,这个字段
IMAGE_DATA_DIRECTORY
// 数据目录表(见下)
(2)IMAGE_DATA_DIRECTORY
IMAGE_DATA_DIRECTORY STRUCT
VirtualAddress DWORD ?
+0h
;该项表示数据的起始 RVA 实际情况
isize DWORD ?
+8h
IMAGE_DATA_DIRECTORY ENDS
;数据块的长度
按照顺序具体列表如下:
如导入表,在文件中寻找导入了那些 DLL 文件时,就是找导入表的起始地址。
四、 节表和节
1、节表
( 1 ) 所 有 节 的 属 性 都 被 定 义 在 节 表 中 , 节 表 由 一 系 列 的
IMAGE_SECTION_HEADER 结构排列而成,每个结构用来描述一个节,结构的排列
顺序和它们描述的节在文件中的排列顺序是一致的。全部有效结构的最后以一个
空 的 IMAGE_SECTION_HEADER 结 构 作 为 结 束 , 所 以 节 表 中
IMAGE_SECTION_HEADER 结构数量等于节的数量加一。
节表总是被存放在紧接在 PE 文件头的地方。所以这里不能移动位置,但可
以把两个节合并
(2) 结构:
IMAGE_SECTION_HEADER STRUCT
BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; // 8 个字节的节区名称 1
union Misc
DWORD PhysicalAddress;
DWORD VirtualSize;
//节区的尺寸,节在未对齐之前的实际大小 2
ends
DWORD VirtualAddress;
址 3
DWORD SizeOfRawData;
占大小 4
DWORD PointerToRawData;
5
DWORD PointerToRelocations;
DWORD PointerToLinenumbers;
WORD NumberOfRelocations;
WORD NumberOfLinenumbers;
DWORD Characteristics;
节 20000060H,导入节 40000040H
IMAGE_SECTION_HEADER ENDS
// 节区的 RVA 地址,装载到内存中的 RVA 地
// 在文件中对齐后的尺寸,磁盘里文件所
// 在文件中的偏移量,节在文件中所处位置
// 在 OBJ 文件中使用,重定位的偏移 6
// 行号表的偏移(供调试使用地)
// 在 OBJ 文件中使用,重定位项数目
// 行号表中行号的数目
// 节属性如可读,可写,可执行等,不用改,代码