PE 文件格之导入导出表

本文详细介绍了PE文件格式中的导入导出表,包括如何将虚拟地址转换为文件地址,以及如何解析OriginalFirstThunk和FirstThunk的区别。通过实例展示了如何找到并解析DLL的导入导出信息,如API序号、函数地址等,帮助理解PE文件结构。
摘要由CSDN通过智能技术生成
PE 文件格之导入导出表
先将源码贴上:


#include <stdio.h>
#include "windows.h"
BOOL DirInSecton(PIMAGE_DATA_DIRECTORY ndir,PIMAGE_SECTION_HEADER nsection)
{
	if(ndir->VirtualAddress>=nsection->VirtualAddress&&ndir->VirtualAddress<=nsection->VirtualAddress+nsection->Misc.VirtualSize)
	{
		return TRUE;
	}
	return FALSE;
}
void AnyImportFromFile(PIMAGE_SECTION_HEADER Section,PIMAGE_NT_HEADERS npe,char *filePath)//导入表
{
	IMAGE_DATA_DIRECTORY* IMAGE_Import = &npe->OptionalHeader.DataDirectory[1];
	int IMAGE_Import_ID = -1;
	//从所有节点中打到,所属于的结点位置
	for (int i = 0 ; i < npe->FileHeader.NumberOfSections ; ++i)
	{
		if(DirInSecton(IMAGE_Import,Section+i))
		{
			IMAGE_Import_ID = i;break;
		}
	}
	//如果找到了
	if(IMAGE_Import_ID>=0)
	{
		//VirtualAddress 虚拟地址的起始位置,PointerToRawData 是文件中的起始位置。但是,它们的偏移是一样的
		//IMAGE_Import->VirtualAddress 要将这个虚拟地址,转化为文件的地址,所以如下。
		int n_Import_file=Section[IMAGE_Import_ID].VirtualAddress-Section[IMAGE_Import_ID].PointerToRawData;//相对值,RVA与PTRD想对值 
		int n_Import=IMAGE_Import->VirtualAddress-n_Import_file;//将位置进行转换
		IMAGE_IMPORT_DESCRIPTOR dll;
		IMAGE_IMPORT_DESCRIPTOR zero_dll = {0};//主要是为了用空比较
		HANDLE file=INVALID_HANDLE_VALUE;
		DWORD lpNumberOfBytesRead;
		try
		{
			file=CreateFile(filePath,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,FILE_ATTRIBUTE_READONLY,0);//打开文件 
			if(file==INVALID_HANDLE_VALUE ) return ;//如果错误
			int Dllnum = 0;//记录dll个数
			SetFilePointer(file,n_Import,0,FILE_BEGIN);//设置位置
			while (1)//主要是统计dll个数
			{
				ReadFile(file,&dll,sizeof(IMAGE_IMPORT_DESCRIPTOR),&lpNumberOfBytesRead,0);//读取,
				if(memcmp(&zero_dll,&dll,sizeof(IMAGE_IMPORT_DESCRIPTOR)) == 0)//直到为空就停止
					break;
				Dllnum ++;
			}
			if(Dllnum == 0)
				throw  (1);
			PIMAGE_IMPORT_DESCRIPTOR PDll = new IMAGE_IMPORT_DESCRIPTOR[Dllnum];//为其分配空间
			int i = 0;
			SetFilePointer(file,n_Import,0,FILE_BEGIN);//设置位置
			//为得到 dll个数
			while (1)
			{
				ReadFile(file,&PDll[i],sizeof(IMAGE_IMPORT_DESCRIPTOR),&lpNumberOfBytesRead,0);//读取,
				if(memcmp(&zero_dll,&PDll[i],sizeof(IMAGE_IMPORT_DESCRIPTOR)) == 0)//直到为空就停止
					break;
				i++;
			}
			char Temp[256]={0};
			printf("导入表\n");
			//枚举
			for (i = 0 ; i < Dllnum ; ++i)
			{
				SetFilePointer(file,PDll[i].Name-n_Import_file,NULL,FILE_BEGIN);
				ReadFile(file,Temp,100,&lpNumberOfBytesRead,0);//读取名字
				printf("%s ",Temp);
				printf(" RVA:%08X\n",PDll[i].Name+npe->OptionalHeader.ImageBase);
				char name[MAX_PATH]={0};
				int vadd=0;
				DWORD nameadd=0;
				int j  = 0;
				//循环,导入表的函数
				do 
				{
					//进入
					if(PDll[i].OriginalFirstThunk > 0)
						SetFilePointer(file,PDll[i].OriginalFirstThunk-n_Import_file+vadd,NULL,FILE_BEGIN);//从原始表
					else
						SetFilePointer(file,PDll[i].FirstThunk-n_Import_file+vadd,NULL,FILE_BEGIN);//如果上面不成功
					ReadFile(file,&nameadd,4,&lpNumberOfBytes
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值