PE文件导入表代码解析

解析导入表就需要先认识下面这三个结构体 

//导入表结构体
typedef struct _IMAGE_IMPORT_DESCRIPTOR {
	union {
		DWORD   Characteristics;   

		//主要这个,包含指向INT的RVA
		DWORD   OriginalFirstThunk;
	};

	//时间标识
	DWORD   TimeDateStamp;  

	//与转发有关
	DWORD   ForwarderChain;             

	//这就是DLL文件名
	DWORD   Name;

	//IAT的RVA
	DWORD   FirstThunk; 
} IMAGE_IMPORT_DESCRIPTOR, *PIMAGE_IMPORT_DESCRIPTOR;

 

//
typedef struct _IMAGE_THUNK_DATA32 {
	union {

		//转发器有关
		DWORD ForwarderString;

		//IAT有关
		DWORD Function;

		//当前结构高位为1是有关
		DWORD Ordinal;

		//不是上面三个的时候这个就发挥作用
		//指向输入名称表
		DWORD AddressOfData;
	} u1;
} IMAGE_THUNK_DATA32,*PIMAGE_THUNK_DATA32;
//输入名称表
typedef struct _IMAGE_IMPORT_BY_NAME {

	//导入的函数序号
	WORD    Hint;

	//导入的函数名称
	CHAR   Name[1];
} IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME;

 IMAGE_IMPORT_DESCRIPTOR(导入表)仅仅是一个引导者,引导系统找到那两个保存有真正导入信息的结构体,也就是IMAGE_THUNK_DATA和IMAGE_IMPORT_BY_NAME。

实现代码: 


BOOL PEAnalyseSpace::PEAnalyse::ShowImport()
{
	//执行是否成功
	BOOL bRet = FALSE;

	//导入表指针
	PIMAGE_IMPORT_DESCRIPTOR pImport = NULL;

	//指针
	PIMAGE_THUNK_DATA pThunk = NULL;

	//导入名称表指针
	PIMAGE_IMPORT_BY_NAME pName = NULL;

	//字符串指针
	PCHAR pszName = NULL;

	do 
	{
		//没有解析
		if (m_lpBase == NULL)
		{
			break;
		}

		//没有导入导入表,这个是不可能的
		if (m_pNt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size == NULL)
		{
			break;
		}

		//获取导入表
		pImport = (PIMAGE_IMPORT_DESCRIPTOR)
			(RVAtoOffset(m_pNt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress)
				+ (DWORD)m_lpBase);

		//循环遍历
		while (pImport->Name)
		{
			//获取导入地址表
			pThunk = (PIMAGE_THUNK_DATA)
				(RVAtoOffset(pImport->OriginalFirstThunk) + (DWORD)m_lpBase);

			//获取模块名字
			pszName = (PCHAR)(RVAtoOffset(pImport->Name) + (DWORD)m_lpBase);


			cout << "Module Name Is: "
				<< pszName
				<< endl;

			//循环遍历地址
			while (pThunk->u1.AddressOfData)
			{
				//判断是序号导入还是名称导入
				//序号
				if (IMAGE_SNAP_BY_ORDINAL32(pThunk->u1.AddressOfData))
				{
					cout << "Index Import -> ID: "
						<< hex
						<< (pThunk->u1.Ordinal & 0xffff)
						<< endl;
				}
				else//名称导入
				{
					//获取导入名称
					pName = (PIMAGE_IMPORT_BY_NAME)
						(RVAtoOffset(pThunk->u1.AddressOfData)
							+ (DWORD)m_lpBase);
					cout << "Name Import -> ID: "
						<< hex
						<< pName->Hint
						<< "\tName: "
						<< pName->Name
						<< endl;
				}
				pThunk++;
			}
			cout << endl;
			pImport++;
		}
		bRet = TRUE;
	} while (FALSE);
	return bRet;
}

 实际效果:

Github:源代码下载

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值