PE文件信息提取

该博客详细介绍了如何解析PE文件的各个关键部分,包括DOS头、NT头、节表、导出表、导入表和重定位表。通过示例代码展示了如何从文件中读取这些信息,并进行地址转换。对于理解PE文件格式和逆向工程有很好的参考价值。

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

**

该程序主要是对PE DOS头,PE头,PE可选头,节表,导出表,导入表,重定位表的一些信息的输出,如果对您有帮助请点一个赞,那方面写的不好的请直接评论批评,我一定会尽最大努力改正

**

#include<Windows.h>
#include<stdio.h>
#include<stdlib.h>
#define IMAGE_SIZEOF_SHORT_NAME 8
//数据的FOA = 数据的ROA - 区段的RVA + 数据的FOA
DWORD RvaToFoa(DWORD rva,int sum,PIMAGE_NT_HEADERS32 NTHead)
{
	PIMAGE_SECTION_HEADER PEZone =  IMAGE_FIRST_SECTION(NTHead);
	for(int i=0;i<sum;i++){
		if(rva>=PEZone->VirtualAddress&&rva<PEZone->VirtualAddress+PEZone->Misc.VirtualSize)
		return rva - PEZone->VirtualAddress + PEZone->PointerToRawData;
		PEZone++;
	} 
} 
int main()
{
	HANDLE hfile = CreateFileA(
		"C:\\Users\\486\\Desktop\\WP\\magic.exe",
		GENERIC_READ,
		FILE_SHARE_READ,
		NULL,
		OPEN_EXISTING,
		FILE_ATTRIBUTE_NORMAL,
		0);
	DWORD fileSize = GetFileSize(hfile, NULL);
	char* fileBuff;
	fileBuff = (char*)malloc((size_t)fileSize);
	BOOL flag = FALSE;
	flag = ReadFile(hfile, fileBuff, fileSize, NULL, NULL);
	if (flag)
		printf("       		文件读取成功\n");
	else
		printf("       		文件读取失败\n");
	printf("---------------------DOS头-----------------------\n");
	PIMAGE_DOS_HEADER pDosHeaders = (PIMAGE_DOS_HEADER)fileBuff;
	printf("e_magic  = %#x\t", pDosHeaders->e_magic);
	printf("%c%c\n", pDosHeaders->e_magic, pDosHeaders->e_magic >> 8);
	printf("e_lfanew = %#x\n", pDosHeaders->e_lfanew);
	printf("----------------------NT头-----------------------\n");
	PIMAGE_NT_HEADERS32 NTHead = (PIMAGE_NT_HEADERS32)((DWORD)fileBuff+pDosHeaders->e_lfanew);
	printf("PE标准:%#x\t",NTHead->Signature);
	printf("%c%c\n",NTHead->Signature,NTHead->Signature>>8);
	PIMAGE_FILE_HEADER PEHead = &NTHead->FileHeader;
	printf("Machine = %#x\n",PEHead->Machine);
	printf("NumberOfSectioms = %#x\n",PEHead->NumberOfSections);
	printf("SizeOfOptionalHeader = %#x\n",PEHead->SizeOfOptionalHeader);
	printf("Characteristics = %#x\n",PEHead->Characteristics);
	PIMAGE_OPTIONAL_HEADER32 PEOptionalHeader = &NTHead->OptionalHeader;
	printf("Magic = %#x\n",PEOptionalHeader->Magic);
	printf("AddressOfEntryPoint = %#x\n",PEOptionalHeader->AddressOfEntryPoint);
	printf("ImageBase = %#x\n",PEOptionalHeader->ImageBase);
	printf("SectionAlignment = %#x\n",PEOptionalHeader->SectionAlignment);
	printf("FileAlignment = %#x\n",PEOptionalHeader->FileAlignment);
	printf("SizeOfImage = %#x\n",PEOptionalHeader->SizeOfImage);
	printf("SizeOfHeaders = %#x\n",PEOptionalHeader->SizeOfHeaders);
	printf("NumberOfRvaAndSizes = %#x\n",PEOptionalHeader->NumberOfRvaAndSizes);
	printf("----------------------节表-----------------------\n");
	PIMAGE_SECTION_HEADER PEZone =  IMAGE_FIRST_SECTION(NTHead);
	for(int i=0;i<PEHead->NumberOfSections;i++){
		char name[9];
		memcpy_s(name,9,PEZone->Name,8);
		printf("区段名称:%s\n",name);
		PEZone++;
	} 
	printf("--------------------导出表-----------------------\n");
	int sum = PEHead->NumberOfSections;
	IMAGE_DATA_DIRECTORY directory = PEOptionalHeader->DataDirectory[0];
	PIMAGE_EXPORT_DIRECTORY pexort = (PIMAGE_EXPORT_DIRECTORY)(RvaToFoa(directory.VirtualAddress,sum,NTHead)+fileBuff);
	char* dllname = RvaToFoa(pexort->Name,sum,NTHead) + fileBuff;
	printf("文件名称:%s\n",dllname);
	DWORD* funaddr = (DWORD*)(RvaToFoa(pexort->AddressOfFunctions,sum,NTHead)+fileBuff);
	WORD* peot = (WORD*)(RvaToFoa(pexort->AddressOfNameOrdinals,sum,NTHead)+fileBuff);
	DWORD* pent = (DWORD*)(RvaToFoa(pexort->AddressOfNames,sum,NTHead)+fileBuff);
	for(int i=0;i<pexort->NumberOfFunctions;i++){
		printf("函数地址:%x\t",*funaddr);
		for(int j=0;j<pexort->NumberOfNames;j++){
			if(peot[j]==i)
			{
				char *funName=(RvaToFoa(pent[j],sum,NTHead)+fileBuff);
				printf("函数名称:%s\n",funName);
				break;
			}
		}
		funaddr++;
	}
	printf("--------------------导入表-----------------------\n");
	IMAGE_DATA_DIRECTORY directory1 = PEOptionalHeader->DataDirectory[1];
	//导入表地址
	PIMAGE_IMPORT_DESCRIPTOR pImport = (PIMAGE_IMPORT_DESCRIPTOR)(RvaToFoa(directory1.VirtualAddress,sum,NTHead)+fileBuff);
	while(pImport->OriginalFirstThunk){
		char *dllName = RvaToFoa(pImport->Name,sum,NTHead) + fileBuff;
		printf("dll文件名称:%s\n",dllName);
		PIMAGE_THUNK_DATA pThukData = (PIMAGE_THUNK_DATA)(RvaToFoa(pImport->OriginalFirstThunk,sum,NTHead)+fileBuff);
		while(pThukData->u1.Function){
			//判断是否按序号导入 
					if(pThukData->u1.Ordinal&0x80000000){
						printf("按序号导入:%d\n",pThukData->u1.Ordinal&0x7FFFFFFF);
					}
					else
					{
						PIMAGE_IMPORT_BY_NAME importName = (PIMAGE_IMPORT_BY_NAME)(RvaToFoa(pThukData->u1.AddressOfData,sum,NTHead)+fileBuff);
						printf("按名称导入:%s\n",importName->Name);
					}
					pThukData++;
		}
		pImport++;
	} 
	printf("-------------------重定位表----------------------\n");
	IMAGE_DATA_DIRECTORY directory5 = PEOptionalHeader->DataDirectory[5];
	PIMAGE_BASE_RELOCATION prelocTable = (PIMAGE_BASE_RELOCATION)(RvaToFoa(directory5.VirtualAddress,sum,NTHead)+fileBuff);
	while(1){
		if(prelocTable->VirtualAddress==0){
			break;
		}
		DWORD number = ((DWORD)prelocTable->SizeOfBlock - 8) / 2;
		WORD *prelocOffset = (WORD*)prelocTable + 4;
		for(int i=0;i<number;i++){
			if((*prelocOffset & 0x3000)==0x3000){
				DWORD rva = (*prelocOffset) & 0x0FFF + prelocTable->VirtualAddress;
				printf("rva = %x\n",rva);
			}
			prelocOffset++;
		}
		prelocTable = (PIMAGE_BASE_RELOCATION)((DWORD)prelocTable+prelocTable->SizeOfBlock);
	}
	printf("-------------------------------------------------\n");
	free(fileBuff);
	CloseHandle(hfile);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值