PE解析

// PE解析1.cpp : 定义控制台应用程序的入口点。
//1·获取文件到内存
//2·判断是否是PE文件
//3·解析字段
//
//f1·RVAtoFOA

#include "stdafx.h"
#include<windows.h>


char* ReadFileToMem(char* pFilePath)
{
	HANDLE hFile = CreateFileA(pFilePath,
		GENERIC_READ,
		FILE_SHARE_WRITE | FILE_SHARE_READ,//设置共享属性 默认为0会独占
		NULL,
		OPEN_EXISTING,
		FILE_ATTRIBUTE_NORMAL,
		NULL
		);
	if (hFile == INVALID_HANDLE_VALUE)
	{
		printf("File open failed\n");
		return 0;
	}
	//获取文件大小
	DWORD dwFileSize = GetFileSize(hFile, NULL);
	//申请内存空间
	char* pFileBuf = new char[dwFileSize] {};
	//读文件数据
	DWORD dwRead;
	BOOL bRet =
		ReadFile(hFile, pFileBuf, dwFileSize, &dwRead, NULL);

	if (bRet)
	{
		return pFileBuf;
	}
	delete pFileBuf;
	return 0;
}

/*2·判断是否是PE文件*/
BOOL IsPeFile(char* pFileBuf)
{
	PIMAGE_DOS_HEADER pDos=(PIMAGE_DOS_HEADER)pFileBuf;
	PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)(pDos->e_lfanew + pFileBuf);

	if ((pDos->e_magic!=IMAGE_DOS_SIGNATURE)||(pNt->Signature!=IMAGE_NT_SIGNATURE))
	{
		printf("isn't PE File\n");
		delete pFileBuf;
		return FALSE;
	}
	printf("It's PE File\n");
	return TRUE;
}

/*3·解析PE中的字段*/
void ShowImportantData(char * pFileBase)
{
	PIMAGE_DOS_HEADER pDos=(PIMAGE_DOS_HEADER)pFileBase;
	PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)(pDos->e_lfanew + pFileBase);

	//加载基址
	printf("加载基址:0x%X\n", pNt->OptionalHeader.ImageBase);
	//OEP
	printf("OEP:0x%X\n", pNt->OptionalHeader.AddressOfEntryPoint);
	//文件属性
	printf("文件属性:0x%X\n", pNt->FileHeader.Characteristics);

	//32or64位文件
	if (pNt->OptionalHeader.Magic==0x10B?1:0)
	{
		printf("32位文件\n");
	}
	else
	{
		printf("64位文件\n");
	}
}

/*f1 RVA to FOA*/
DWORD RVAtoFOA(DWORD dwRVA, char*pBase)
{
	PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)pBase;
	PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)(pDos->e_lfanew + pBase);

	//获取区段数
	DWORD dwSectionCount = pNt->FileHeader.NumberOfSections;
	//第一区段表地址
	PIMAGE_SECTION_HEADER pSec1 = IMAGE_FIRST_SECTION(pNt);
	//循环比对地址落在哪个区段
	for (DWORD i = 0; i < dwSectionCount;i++)
	{
		if (dwRVA>=pSec1->VirtualAddress &&
			dwRVA<pSec1->VirtualAddress+
			pSec1->SizeOfRawData)
		{
			return dwRVA - pSec1->VirtualAddress + pSec1->PointerToRawData;
		}
		pSec1++;
	}
	return 0;
}



int _tmain(int argc, _TCHAR* argv[])
{
	char* pFile = ReadFileToMem("F:\\src.exe");  //文件路径
	if (!IsPeFile(pFile))
	{
		return 0;
	}
	ShowImportantData(pFile);
	getchar();
	return 0;
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/useror/article/details/90200362