C实现PE结构解析

C实现PE结构解析

其实就是照着PE结构图抄过来,定义结构体,用结构体指针访问,挨个打印出来。

这里随便用了个植物大战僵尸的PE文件(导出表是用的游戏的dll)。

Loader.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
typedef char BYTE;
typedef short WORD;
typedef int DWORD;

struct IMAGE_RESOURCE_DATA
{
   
	DWORD VirtualAddress;
	DWORD Size;
};
struct IMAGE_RESOURCE_DIRECTORY_ENTRY
{
   
	union 
	{
   
		struct 
		{
   
			DWORD NameOffset : 31;			//目录项名称或者ID			
			DWORD NameIsString : 1;
		};
		DWORD   Name;
		WORD    Id;
	};

	union 
	{
   
		DWORD   OffsetToData;
		struct
		{
   
			DWORD   OffsetToDirectory : 31;				//目录项指针,不是rva		
			DWORD   DataIsDirectory : 1;
		};
	};
};
struct IMAGE_RESOURCE_DIRECTORY {
   
	DWORD Characteristics;
	DWORD TimeDateStamp;
	WORD MajorVersion;
	WORD MinorVersion;
	WORD NumberOfNamedEntries;
	WORD NumberOfIdEntries;
};
struct PIMAGE_IMPORT_BY_NAME
{
   
	WORD Hint;
	BYTE Name;
};
struct PIMAGE_THUNK_DATA
{
   
	union
	{
   
		BYTE ForwarderString;
		DWORD Function;
		DWORD Ordinal;
		PIMAGE_IMPORT_BY_NAME AddressOfData;
	};
};
struct IMAGE_IMPORT_DESCRIPTOR
{
   
	union 
	{
   
		DWORD Characteristics;
		PIMAGE_THUNK_DATA OriginalFirstThunk;
	}u;
	DWORD TimeDateStamp;
	DWORD ForwarderChain;
	DWORD Name;
	PIMAGE_THUNK_DATA FirstThunk;
};
struct IMAGE_DIRECTORY_ENTRY_BASERELOC {
   
	DWORD VirtualAddress;
	DWORD Size;
};
struct IMAGE_SECTION_HEADER
{
   
	BYTE Name[8];
	union {
   
		DWORD PhysicalAddress;
		DWORD VirtualSize;
	} Misc;
	DWORD VirtualAddress;
	DWORD SizeOfRawData;
	DWORD PointerToRawData;
	DWORD PointerToRelocations;
	DWORD PointerToLinenumbers;
	WORD NumberOfRelocations;
	WORD NumberOfLinenumbers;
	DWORD Characteristics;
};
struct IMAGE_EXPORT_DIRECTORY {
   
	DWORD Characteristics;
	DWORD TimeDateStamp;
	WORD MajorVersion;
	WORD MinorVersion;
	DWORD Name;
	DWORD Base;
	DWORD NumberOfFunctions;
	DWORD NumberOfNames;
	DWORD AddressOfFunctions;
	DWORD AddressOfNames;
	DWORD AddressOfNameOrdinals;
};
struct IMAGE_DATA_DIRECTORY
{
   
	DWORD VirtualAddress;
	DWORD Size;
};
struct IMAGE_DOS_HEADER
{
   
	WORD e_magic;
	WORD e_cblp;
	WORD e_cp;
	WORD e_crlc;
	WORD e_cparhdr;
	WORD e_minalloc;
	WORD e_maxalloc;
	WORD e_ss;
	WORD e_sp;
	WORD e_csum;
	WORD e_ip;
	WORD e_cs;
	WORD e_lfarlc;
	WORD e_ovno;
	WORD e_res[4];
	WORD e_oemid;
	WORD e_oeminfo;
	WORD e_res2[10];
	DWORD e_lfanew;

};
struct IMAGE_FILE_HEADER
{
   
	WORD Machine;
	WORD NumberOfSections;
	DWORD TimeDateStamp;
	DWORD PointerToSymbolTable;
	DWORD NumberOfSymbols;
	WORD SizeOfOptionalHeader;
	WORD Characteristics;
};
struct IMAGE_OPTIONAL_HEADER
{
   
	WORD Magic;
	BYTE MajorLinkerVersion;
	BYTE MinorLinkerVersion;
	DWORD SizeOfCode;
	DWORD SizeOfInitializedData;
	DWORD SizeOfUninitializedData;
	DWORD AddressOfEntryPoint;
	DWORD BaseOfCode;
	DWORD BaseOfData;
	DWORD ImageBase;
	DWORD SectionAlignment;
	DWORD FileAlignment;
	WORD MajorOperatingSystemVersion;
	WORD MinorOperatingSystemVersion;
	WORD MajorImageVersion;
	WORD MinorImageVersion;
	WORD MajorSubsystemVersion;
	WORD MinorSubsystemVersion;
	DWORD Win32VersionValue;
	DWORD SizeOfImage;
	DWORD SizeOfHeaders;
	DWORD CheckSum;
	WORD Subsystem;
	WORD DllCharacteristics;
	DWORD SizeOfStackReserve;
	DWORD SizeOfStackCommit;
	DWORD SizeOfHeapReserve;
	DWORD SizeOfHeapCommit;
	DWORD LoaderFlags;
	DWORD NumberOfRvaAndSizes;
	IMAGE_DATA_DIRECTORY DataDirectory[16];
};
struct IMAGE_NT_HEADERS
{
   
	DWORD Signature;
	IMAGE_FILE_HEADER FileHeader;
	IMAGE_OPTIONAL_HEADER OptionalHeader;
};

void* OpenFile();
void PrintPEStructs();
void PrintPeHeaders();
int RVAToFOA(int RVA);
int RTF(int Rva);
void ExportTables();
void Relocation();
void ImportTable();
void ResourceTable();

Loader.cpp:

#include "Loader.h"


//打开文件,分配内存,获取指针
void* OpenFile()
{
   
	char arr[] = "D:\\PlantsVsZombies.exe";
	FILE* FileOpen = fopen(arr, "rb");
	if (!FileOpen)
	{
   
		printf("打开文件失败");
		return NULL;
	}
	fseek(FileOpen, 0, SEEK_END);
	int FileSize = ftell(FileOpen);
	fseek(FileOpen, 0, SEEK_SET);
	void* FileBuffer = malloc(FileSize);
	if (!FileBuffer)
	{
   
		printf("分配内存失败");
		return NULL;
	}
	size_t n = fread(FileBuffer, FileSize, 1, FileOpen);
	if (!n)
	{
   
		printf("加载到内存失败");
		free(FileBuffer);
		fclose(FileOpen);
		return NULL;
	}
	fclose(FileOpen);
	return FileBuffer;
}

//打印PE头相关信息
char* pBegin = (char*)OpenFile();
IMAGE_DOS_HEADER* DOS_Header = (IMAGE_DOS_HEADER*)pBegin;
int e_lfanew = DOS_Header->e_lfanew;
IMAGE_NT_HEADERS* NT_Header = (IMAGE_NT_HEADERS*)(pBegin + e_lfanew);
IMAGE_DATA_DIRECTORY* datadirectory = (IMAGE_DATA_DIRECTORY*)NT_Header->OptionalHeader.DataDirectory;
WORD SizeOfOptionalHeaders = NT_Header->FileHeader.SizeOfOptionalHeader;
IMAGE_SECTION_HEADER* Sec
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值