流沙团
读取PE头信息
2017-11-7 流沙团


主要是根据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;
}

发表评论:
昵称

邮件地址 (选填)

个人主页 (选填)

内容