2、标准PE头 IMAGE_FILE_HEADER
2、标准PE头 IMAGE_FILE_HEADER
这里看过了PE初始的文章,了解了ImageNtHead结构体的构成,我们就可以知道。IMAGE_FILE_HEADER文件的位置了,。其实她的位置就是再IMAGE_NT_HEAD的第二个成员。代码如下
typedef struct _IMAGE_NT_HEADERS {
DWORD Signature;
IMAGE_FILE_HEADER FileHeader;
IMAGE_OPTIONAL_HEADER32 OptionalHeader;
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;
typedef struct _IMAGE_FILE_HEADER {
WORD Machine; // 程序运行平台
WORD NumberOfSections; // PE中节(IMAGE_SECTION_HEADER)的数量
DWORD TimeDateStamp; // 时间戳
DWORD PointerToSymbolTable; // COFF符号表中文件的偏移 没啥用
DWORD NumberOfSymbols; // 符号表中符号的数量 没啥用
WORD SizeOfOptionalHeader; // 扩展PE头的大小
WORD Characteristics; // PE文件属性
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
这里要提一下。IMAGE_FILE_HEADER 是一个固定大小的。她的大小是20个字节,有一个宏如下其实就是标记我们标准头的大小的。以后可以经常使用这个要舒服很多
#define IMAGE_SIZEOF_FILE_HEADER 20
其中第一个成员介绍如下,
#define IMAGE_FILE_MACHINE_UNKNOWN 0
#define IMAGE_FILE_MACHINE_TARGET_HOST 0x0001 // Useful for indicating we want to interact with the host and not a WoW guest.
#define IMAGE_FILE_MACHINE_I386 0x014c // Intel 386.
#define IMAGE_FILE_MACHINE_R3000 0x0162 // MIPS little-endian, 0x160 big-endian
#define IMAGE_FILE_MACHINE_R4000 0x0166 // MIPS little-endian
#define IMAGE_FILE_MACHINE_R10000 0x0168 // MIPS little-endian
#define IMAGE_FILE_MACHINE_WCEMIPSV2 0x0169 // MIPS little-endian WCE v2
#define IMAGE_FILE_MACHINE_ALPHA 0x0184 // Alpha_AXP
#define IMAGE_FILE_MACHINE_SH3 0x01a2 // SH3 little-endian
#define IMAGE_FILE_MACHINE_SH3DSP 0x01a3
#define IMAGE_FILE_MACHINE_SH3E 0x01a4 // SH3E little-endian
#define IMAGE_FILE_MACHINE_SH4 0x01a6 // SH4 little-endian
#define IMAGE_FILE_MACHINE_SH5 0x01a8 // SH5
#define IMAGE_FILE_MACHINE_ARM 0x01c0 // ARM Little-Endian
#define IMAGE_FILE_MACHINE_THUMB 0x01c2 // ARM Thumb/Thumb-2 Little-Endian
#define IMAGE_FILE_MACHINE_ARMNT 0x01c4 // ARM Thumb-2 Little-Endian
#define IMAGE_FILE_MACHINE_AM33 0x01d3
#define IMAGE_FILE_MACHINE_POWERPC 0x01F0 // IBM PowerPC Little-Endian
#define IMAGE_FILE_MACHINE_POWERPCFP 0x01f1
#define IMAGE_FILE_MACHINE_IA64 0x0200 // Intel 64
#define IMAGE_FILE_MACHINE_MIPS16 0x0266 // MIPS
#define IMAGE_FILE_MACHINE_ALPHA64 0x0284 // ALPHA64
#define IMAGE_FILE_MACHINE_MIPSFPU 0x0366 // MIPS
#define IMAGE_FILE_MACHINE_MIPSFPU16 0x0466 // MIPS
#define IMAGE_FILE_MACHINE_AXP64 IMAGE_FILE_MACHINE_ALPHA64
#define IMAGE_FILE_MACHINE_TRICORE 0x0520 // Infineon
#define IMAGE_FILE_MACHINE_CEF 0x0CEF
#define IMAGE_FILE_MACHINE_EBC 0x0EBC // EFI Byte Code
#define IMAGE_FILE_MACHINE_AMD64 0x8664 // AMD64 (K8)
#define IMAGE_FILE_MACHINE_M32R 0x9041 // M32R little-endian
#define IMAGE_FILE_MACHINE_ARM64 0xAA64 // ARM64 Little-Endian
#define IMAGE_FILE_MACHINE_CEE 0xC0EE
这个平台的值就是说明再那个平台运行的。
第二个成员是 NumberOfSections 表示PE文件中节区的总数。(非常重要)
第六个成员 SizeOfOptionalHeader 是扩展PE头的大小,这个非常重要一定要记住其他的就没了。
下面写一下,代码打印标准PE头首位
VOID PrintFileHeader()
{
//文件读取到内存中
DWORD dwFileSize = 0;
PCHAR fileBuff = fileToMem(&dwFileSize);
if (!fileBuff)
{
log_error("fileToMem error");
return;
}
// 定位标准PE头
PIMAGE_DOS_HEADER pImgDosHeader = (PIMAGE_DOS_HEADER)fileBuff;
PIMAGE_NT_HEADERS pImgNtHeader = (PIMAGE_NT_HEADERS)(fileBuff + pImgDosHeader->e_lfanew);
PIMAGE_FILE_HEADER pImgFileHeader = (PIMAGE_FILE_HEADER)((PCHAR)pImgNtHeader + 4);
//WORD Machine;
//WORD NumberOfSections;
//DWORD TimeDateStamp;
//DWORD PointerToSymbolTable;
//DWORD NumberOfSymbols;
//WORD SizeOfOptionalHeader;
//WORD Characteristics;
printf("Machine %#x\n", pImgFileHeader->Machine);
printf("NumberOfSections %#x\n", pImgFileHeader->NumberOfSections);
printf("TimeDateStamp %#x\n", pImgFileHeader->TimeDateStamp);
printf("PointerToSymbolTable %#x\n", pImgFileHeader->PointerToSymbolTable);
printf("NumberOfSymbols %#x\n", pImgFileHeader->NumberOfSymbols);
printf("SizeOfOptionalHeader %#x\n", pImgFileHeader->SizeOfOptionalHeader);
printf("Characteristics %#x\n", pImgFileHeader->Characteristics);
}