PE文件结构
|
字数总计:
3554
|
阅读时长:
2分钟
|
阅读量:
103
DOS头
struct __IMAGE_DOS_HEADER {
WORD e_magic; //MZ标记 4D 5A
WORD e_cblp;
WORD e_cp;
WORD e_crlc;
WORD e_cparhdr;
WORD e_minalloc;
WORD e_maxalloc;
WORD e_ss;
WORD e_sp;
WORD e_csum;
WORD e_ip;
WORD e_cs;
WORD e_lfarlc;
WORD e_ovno;
WORD e_res[4];
WORD e_oemid;
WORD e_oeminfo;
WORD e_res2[10];
DWORD e_lfanew; //PE文件真正开始的偏移地址(基于首地址偏移) NT头
};
NT头
struct __IMAGE_NT_HEADERS {
DWORD Signature; //PE标记 50 45
__IMAGE_FILE_HEADER FileHeader; //标准PE头
__IMAGE_OPTIONAL_HEADER OptionalHeader; //可选PE头
};
标准PE头
struct __IMAGE_FILE_HEADER {
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; //每个位有不同的含义,可执行文件值为10F 即0 1 2 3 8位置1
};
可选PE头
struct __IMAGE_OPTIONAL_HEADER {
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; //所有头+节表按照文件对齐后的大小 必须是FileAlignment整数倍否则加载会出错
DWORD CheckSum; //和校验,一些系统文件有要求.用来判断文件是否被修改.
WORD Subsystem;
WORD DllCharacteristics;
DWORD SizeOfStackReserve; //初始化时保留的堆栈大小
DWORD SizeOfStackCommit; //初始化时实际提交的大小
DWORD SizeOfHeapReserve; //初始化时保留的堆大小
DWORD SizeOfHeapCommit; //初始化时实践提交的大小
DWORD LoaderFlags;
DWORD NumberOfRvaAndSizes; //目录项数目
_IMAGE_DATA_DIRECTORY DataDirectory[16];
};
节
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; //该节特征属性
};
导出表
struct __IMAGE_EXPORT_DIRECTORY {
DWORD Characteristics; // 未使用,通常为 0
DWORD TimeDateStamp; // 时间戳
WORD MajorVersion; // 主版本号(通常为 0)
WORD MinorVersion; // 次版本号(通常为 0)
DWORD Name; // 模块名称的 RVA地址
DWORD Base; // 导出函数的起始序号
DWORD NumberOfFunctions; // 导出函数的数量
DWORD NumberOfNames; // 按名称导出的函数数量
DWORD AddressOfFunctions; // 导出函数地址表的 RVA
DWORD AddressOfNames; // 导出函数名称表的 RVA
DWORD AddressOfNameOrdinals; // 导出函数序号表的 RVA
};
重定位表
struct __IMAGE_BASE_RELOCATION {
DWORD VirtualAddress; // 重定位块的虚拟地址,基址,块中的偏移加上此基址则定位到需要修改的地方
DWORD SizeOfBlock; // 重定位块的大小,单位是字节,通常是 8 的倍数。
};