主要是根据PE结构, 使用文件读取的方式,依次读取PE信息:
#include "stdio.h" #include "windows.h" /* typedef struct _IMAE_DOS_HEADER { //DOS .EXE header 位置 WORD e_magic; //Magic number; 0x00 WORD e_cblp; //Bytes on last page of file 0x02 WORD e_cp; //Pages in file 0x04 WORD e_crlc; //Relocations 0x06 WORD e_cparhdr; //Size of header in paragraphs 0x08 WORD e_minalloc; //Minimum extra paragraphs needed 0x0A WORD e_maxalloc; //Maximum extra paragraphs needed 0x0C WORD e_ss; //Initial (relative) SS value 0x0E WORD e_sp; //Initial SP value 0x10 WORD e_csum; //Checksum 0x12 WORD e_ip; //Initial IP value 0x14 WORD e_cs; //Initial (relative) CS value 0x16 WORD e_lfarlc; //File address of relocation table 0x18 WORD e_ovno; //Overlay number 0x1A WORD e_res[4]; //Reserved words 0x1C WORD e_oemid; //OEM identifier (for e_oeminfo) 0x24 WORD e_oeminfo; //OEM information; e_oemid specific 0x26 WORD e_res2[10]; //Reserved words 0x28 LONG e_lfanew; //File address of new exe header 0x3C } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER; */ LPVOID ReadPEFile(LPSTR lpszFile) { FILE *pFile = NULL; DWORD fileSize = 0; LPVOID pFileBuffer = NULL; //打开文件 pFile = fopen(lpszFile,"rb"); if(!pFile) { printf("无法打开文件EXE文件"); return NULL; } fseek(pFile,0,SEEK_END); fileSize = ftell(pFile); fseek(pFile,0,SEEK_SET); //分配缓冲区 pFileBuffer = malloc(fileSize); if(!pFileBuffer) { printf("分配空间失败!\n"); fclose(pFile); return NULL; } //文件读取 size_t n = fread(pFileBuffer,fileSize,1,pFile); if(!n) { printf("读取数据失败\n"); free(pFileBuffer); fclose(pFile); return NULL; } //关闭文件 fclose(pFile); return pFileBuffer; } VOID PrintNTHeaders(LPSTR lpszFile) { LPVOID pFileBuffer = NULL; PIMAGE_DOS_HEADER pDosHeader = NULL; PIMAGE_NT_HEADERS pNTHeader = NULL; PIMAGE_FILE_HEADER pPEHeader = NULL; PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL; PIMAGE_SECTION_HEADER pSectionHeader = NULL; pFileBuffer= ReadPEFile(lpszFile); if(!pFileBuffer) { printf("文件读取失败\n"); return; } //MZ标志 if(*((PWORD)pFileBuffer)!=IMAGE_DOS_SIGNATURE) { printf("不是有效的MZ标志\n"); free(pFileBuffer); return; } pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer; //打印DOS头 printf("------------DOS头------------\n"); printf("MZ标志: %x\n",pDosHeader->e_magic); printf("PE偏移: %x\n",pDosHeader->e_lfanew); //判断是否是有效的PE if(*((PDWORD)((DWORD)pFileBuffer+pDosHeader->e_lfanew))!=IMAGE_NT_SIGNATURE) { printf("不是有效的PE标志\n"); free(pFileBuffer); return; } pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer+pDosHeader->e_lfanew); //打印NT头 printf("------------NT头------------\n"); printf("Signature: %x\n",pNTHeader->Signature); pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader)+4); printf("------------标准PE头--------\n"); printf("Machine: %x\n",pPEHeader->Machine); printf("节的数量: %x\n",pPEHeader->NumberOfSections); printf("SizeOfOptionHeaders: %x\n",pPEHeader->SizeOfOptionalHeader); //可选择PE头 pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader+IMAGE_SIZEOF_FILE_HEADER); printf("------------OPTION_PE头--------\n"); printf("Machine: %x \n",pOptionHeader->Magic); printf("OEP: %x \n",pOptionHeader->AddressOfEntryPoint); printf("ImageBase: %x \n",pOptionHeader->ImageBase); printf("SectionAlignment: %x \n",pOptionHeader->SectionAlignment); printf("FileAlignment: %x \n",pOptionHeader->FileAlignment); printf("SizeOfImage: %x \n",pOptionHeader->SizeOfImage); printf("SizeOfHeaders: %x \n",pOptionHeader->SizeOfHeaders); //释放内存 free(pFileBuffer); } void main() { LPSTR pStr = "C://msg.exe"; PrintNTHeaders(pStr); return; }
0则评论给“读取PE头信息”