导入表

数据目录表的第二项为导入表
导入表 即 应用程序需要调用函数的地址一个表

导入表结构
typedef struct _IMAGE_IMPORT_DESCRIPTOR {
DWORD OriginalFirstThunk;//指向INT表 导入名字表
DWORD TimeDateStamp;
DWORD ForwarderChain;
DWORD Name;
DWORD FirstThunk;//指向IAT表 导入地址表
} IMAGE_IMPORT_DESCRIPTOR, *PIMAGE_IMPORT_DESCRIPTOR;

导入表结构是 多个连续的IMAGE_IMPORT_DESCRIPTOR结构体,可以用Name来判断是否遍历完.

OriginalFirstThunk 指向INT表
IMAGE_THUNK_DATA32结构为4字节大小 如果这个值的最高位(32位)为1 那么剩下的31位为所需要函数的导出序号(该函数在dll中是以序号导出的),如果为0,那么这个值是IMAGE_IMPORT_BY_NAME结构的RVA

typedef struct _IMAGE_IMPORT_BY_NAME {
WORD Hint;
CHAR Name[1];
} IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME;
该结构的前两个字节为函数在地址表的索引(没多大用),第三个字节是函数名字的开始。

在这里插入图片描述

Name
DLL文件的名字RVA,从结果可以看出导入表的dll名字都是挨在一起的。
在这里插入图片描述
在这里插入图片描述

FirstThunk
指向IAT表 ,一般情况下,在程序加载前IAT表的值与INT表一样。在加载后,IAT表的值为函数的地址。
在加载时,通过INT表找到第一个函数的名字,然后通过GetProcAddress得到函数的地址,写入IAT表同样索引的位置。然后找第二个函数的地址,遍历完INT表,IAT表的地址也就写入完成。

还有一种情况是IAT表在加载前就直接写成了绝对地址,所需DLL的ImageBase设置成不同的值,这个表即可在程序加载前直接写入。通过_IMAGE_IMPORT_DESCRIPTOR的TimeDateStamp(时间戳)可以判断导入表是否被绑定,当这个值为0时,未绑定,这个值为-1时,被绑定。

typedef struct _IMAGE_BOUND_IMPORT_DESCRIPTOR {
DWORD TimeDateStamp;
WORD OffsetModuleName;
WORD NumberOfModuleForwarderRefs;
// Array of zero or more IMAGE_BOUND_FORWARDER_REF follows
} IMAGE_BOUND_IMPORT_DESCRIPTOR, *PIMAGE_BOUND_IMPORT_DESCRIPTOR;

绑定导入表,位于数据目录表的第12项。它的TimeDateStamp记录了绑定的时间。
OffsetModuleName 模块的名字RVA
NumberOfModuleForwarderRefs 这个模块所依赖的DLL个数,有几个DLL依赖项,它的后面就跟着几个_IMAGE_BOUND_FORWARDER_REF结构

typedef struct _IMAGE_BOUND_FORWARDER_REF {
DWORD TimeDateStamp;时间戳
WORD OffsetModuleName; DLL文件名的偏移
WORD Reserved;
} IMAGE_BOUND_FORWARDER_REF, *PIMAGE_BOUND_FORWARDER_REF;
OffsetModuleName真正的文件名=第一个绑定导入表的开始地址+这个偏移
最后一个绑定导入表为全0结构
在这里插入图片描述

修复IAT表

在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值