PE解析

本文深入探讨了PE(Portable Executable)文件格式,它是Windows操作系统中用于执行程序和动态链接库的主要格式。内容包括PE文件的结构、节区、导入导出表、资源管理等关键部分,旨在帮助安全开发者更好地理解和分析恶意软件行为。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

// 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;
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值