PE文件结构分析程序(C++)

该程序用与对PE文件的头文件以及数据目录表进行分析,并输出各个数据目录表以及头文件的关键字段

运行环境

Microsoft Visual Studio Professional 2017 Windows10

项目格式

在这里插入图片描述

头文件 Entry.h

#pragma once
#include <stdio.h>
#include <Windows.h>

//计算数据目录表起始位置到文件头的偏移
DWORD RvaToOffset(DWORD dwRva, char *buffer);
//解析导入表的函数
void ImportTable(char * buffer);
//解析导出表的函数
void ExportTable(char * buffer);
//解析TLS表的函数
void TLSTable(char* buffer);
//解析延迟导入表的函数
void DelayImportTable(char *buffer);
//解析重定位表的函数
void RelocTable(char *buffer);
//解析资源表的函数
void ResourceTable(char *buffer);
//解析其他表(以Debug表为例)
void DataTable(char *buffer);

源文件 Entry.cpp

在执行前需要修改分析的PE文件的路径,执行时可以选择调试以及一个一个的功能调试,便于分析.

#include "Entry.h"

int main()
{
   
	//文件读取
	FILE * pFile = NULL;
	char * buffer;
	int nFileLength = 0;
	pFile = fopen("D:\\Program Files\\Edrawsoft\\Edraw MindMaster(简体中文)\\MindMaster.exe", "rb");
	//pFile = fopen("D:\\Program Files\\Edrawsoft\\Edraw MindMaster(简体中文)\\MindMaster.exe", "rb");
	//D:\\Program Files\\Edrawsoft\\Edraw MindMaster(简体中文)\\MindMaster.exe
	fseek(pFile, 0, SEEK_END);
	nFileLength = ftell(pFile);
	rewind(pFile);
	int imageLength = nFileLength * sizeof(char) + 1;
	buffer = (char *)malloc(imageLength);
	memset(buffer, 0, nFileLength * sizeof(char) + 1);
	fread(buffer, 1, imageLength, pFile);
	//MS-DOS头解析
	PIMAGE_DOS_HEADER ReadDosHeader;
	ReadDosHeader = (PIMAGE_DOS_HEADER)buffer;
	printf("MS-DOS Info:\n");
	printf("MZ标志位:%x\n", ReadDosHeader->e_magic);
	printf("PE头偏移:%x\n", ReadDosHeader->e_lfanew);
	printf("==================================================================\n");
	printf("PE Header Info:\n");
	PIMAGE_NT_HEADERS32 ReadNTHeaders;
	//PE头解析
	ReadNTHeaders = (PIMAGE_NT_HEADERS32)(buffer + ReadDosHeader->e_lfanew);
	//PE头标志
	printf("PE标志位:%x\n", ReadNTHeaders->Signature);
	//标准PE头字段
	printf("运行平台:%x\n", ReadNTHeaders->FileHeader.Machine);
	//扩展PE头字段
	printf("ImageBase:%x\n", ReadNTHeaders->OptionalHeader.ImageBase);
	printf("==================================================================\n");
	printf("Section Header Info:\n");
	//区段解析遍历
	PIMAGE_SECTION_HEADER ReadSectionHeader = IMAGE_FIRST_SECTION(ReadNTHeaders);
	PIMAGE_FILE_HEADER pFileHeader = &ReadNTHeaders->FileHeader;
	for (int i = 0; i < pFileHeader->NumberOfSections; i++)
	{
   
		printf("Name(区段名称):%s\n", ReadSectionHeader[i].Name);
		printf("VOffset(起始的相对虚拟地址):%08X\n", ReadSectionHeader[i].VirtualAddress);
		printf("VSize(区段大小):%08X\n", ReadSectionHeader[i].SizeOfRawData);
		printf("ROffset(文件偏移):%08X\n", ReadSectionHeader[i].PointerToRawData);
		printf("RSize(文件中区段大小):%08X\n", ReadSectionHeader[i].Misc.VirtualSize);
		printf("标记(区段的属性):%08X\n\n", ReadSectionHeader[i].Characteristics);
	}
	printf("==================================================================\n");
	//分析函数
	//ImportTable(buffer);
	//ExportTable(buffer);
	//TLSTable(buffer);
	//DelayImportTable(buffer);
	//RelocTable(buffer);
	//ResourceTable(buffer);
	//DataTable(buffer);
	free(buffer);
	return 0;
}

//dwRva是某个数据目录表的VirtualAddress
//buffer是读取到的PE文件缓冲区
DWORD RvaToOffset(DWORD dwRva, char * buffer)// 计算偏移的函数,将RVA转化成偏移
{
   
	//解析Dos头
	PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)buffer;
	//PE头
	PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)(pDos->e_lfanew + buffer);
	//区段表
	PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION(pNt);
	//判断是否落在了头部当中
	if (dwRva 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值