PE之DOS头,NT头相关记录
一、DOS头相关
上 _IMAGE_DOS_HEADER结构体
在这里的话除了介绍最为重要的e_magic字段外其余的不在做介绍,感兴趣的同学可以自己查询相关资料
typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header
WORD e_magic; // (最为重要,可以当作解析时作为判断是否是PE文件的第一个标志)
WORD e_cblp; // Bytes on last page of file
WORD e_cp; // Pages in file
WORD e_crlc; // Relocations
WORD e_cparhdr; // Size of header in paragraphs
WORD e_minalloc; // Minimum extra paragraphs needed
WORD e_maxalloc; // Maximum extra paragraphs needed
WORD e_ss; // Initial (relative) SS value
WORD e_sp; // Initial SP value
WORD e_csum; // Checksum
WORD e_ip; // Initial IP value
WORD e_cs; // Initial (relative) CS value
WORD e_lfarlc; // File address of relocation table
WORD e_ovno; // Overlay number
WORD e_res[4]; // Reserved words
WORD e_oemid; // OEM identifier (for e_oeminfo)
WORD e_oeminfo; // OEM information; e_oemid specific
WORD e_res2[10]; // Reserved words
LONG e_lfanew; // File address of new exe header
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
二、NT头相关
上_IMAGE_NT_HEADERS结构体
typedef struct _IMAGE_NT_HEADERS {
DWORD Signature; //PE文件标记(判断是否为PE文件的第二个标志,可以与介绍到的e_magic 连用)
IMAGE_FILE_HEADER FileHeader; //标准文件头(非常重要)
IMAGE_OPTIONAL_HEADER32 OptionalHeader; //扩展文件头(非常重要)
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;
这里着重介绍一下IMAGE_FILE_HEADER(标准文件头)与IMAGE_OPTIONAL_HEADER32(扩展文件头)
1、上IMAGE_FILE_HEADER结构体
typedef struct _IMAGE_FILE_HEADER {
WORD Machine; //文件的运行平台
WORD NumberOfSections; //节(区段)的数量
DWORD TimeDateStamp; //文件创建时间
DWORD PointerToSymbolTable; //符号表偏移
DWORD NumberOfSymbols; //符号个数
WORD SizeOfOptionalHeader; //扩展头的大小
WORD Characteristics; //记录PE文件的一些属性
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
2、上_IMAGE_OPTIONAL_HEADER结构体
typedef struct _IMAGE_OPTIONAL_HEADER {
//
// Standard fields.
//
WORD Magic; //标志这是一个什么类型的PE文件,32位一般是0x010B,64位的PE文件一般是0x020B,还有一个0x170,代表ROM镜像
BYTE MajorLinkerVersion; //连接器主版本
BYTE MinorLinkerVersion; //连接器次版本
DWORD SizeOfCode; //指所有代码区段(节)的总大小
DWORD SizeOfInitializedData; //已初始化数据的总大小
DWORD SizeOfUninitializedData; //未初始化数据的总大小,在磁盘中不占用空间,在加载到内存中后,会预留这么大的空间。一般存储在.bss区段(节)中
DWORD AddressOfEntryPoint; //程序开始执行的相对虚拟地址(RVA),也叫OEP,Orginal Entry Point,源入口点
DWORD BaseOfCode; //起始代码的相对虚拟地址(RVA)
DWORD BaseOfData; //起始数据的相对虚拟地址(RVA)
//
// NT additional fields.
//
DWORD ImageBase; //默认加载基址(如果没有加载到这个地址,会发生重定位)
DWORD SectionAlignment; //块对齐数,就是在映射到内存中的区段(节)对齐,这个数必须大小文件对齐数,一般是0x1000
DWORD FileAlignment; //文件对齐数,就是在硬盘中的文件的区段(节)对齐,一般是0x200
WORD MajorOperatingSystemVersion; //主操作系统版本号
WORD MinorOperatingSystemVersion; //次操作系统版本号
//主映像版本
WORD MajorImageVersion; //主映像版本
WORD MinorImageVersion; //次映像版本
WORD MajorSubsystemVersion; // 主子系统版本号
WORD MinorSubsystemVersion; // 次子系统版本号
DWORD Win32VersionValue; //保留值,一般是0
DWORD SizeOfImage; //把文件加载进内存,所需要的内存大小,注意是进行了块对齐之后
DWORD SizeOfHeaders; // 所有头部大小,一般也是文件主体相对文件起始的偏移
DWORD CheckSum; //校验和对于驱动和一些系统dll来说需要校验(使用IMAGEHLP.DLL中的CheckSumMappedFile API)
WORD Subsystem; //子系统
WORD DllCharacteristics; //指示Dll特征的标志
DWORD SizeOfStackReserve; //表示进程中栈可以增长到最大值一般1MB
DWORD SizeOfStackCommit; //表示进程中栈的初始值,据说也是栈每次分配增长的值一般4KB
DWORD SizeOfHeapReserve; //表示进程中堆可以增长到的最大值一般1MB
DWORD SizeOfHeapCommit; //表示进程堆的初始值
DWORD LoaderFlags; //
DWORD NumberOfRvaAndSizes; //数据目录个数,也就是下面字段中数组的个数
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; // 数据目录表
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;
本文参考自 <黑客免杀攻防> 及 <PE权威指南>