一、绑定导入表的作用
有些windows程序,如notepad,为了提高加载速度,会直接把DLL中的函数地址写入到IAT表,省去了加载时的计算。但是这样会有两个问题,第一,当DLL没有占住ImageBase时,IAT中的地址就是错的;第二,当链接的DLL被修改了,那IAT里写的地址也是错的。遇到这两种情形之一,加载时就必须修复IAT了。
对于第二种情形,DLL是否被修改,是根据比较DLL的时间戳和绑定导入表中的记录的DLL时间戳来判断的,如果不一致,说明DLL被修改了。
加载程序时,操作系统根据导入表中的时间戳来判断程序是否使用了绑定导入。当时间戳为0,表示不使用绑定导入表;当时间戳为0xFFFFFFFF,说明该程序使用绑定导入。
对于使用绑定导入的程序,绑定导入表存储在最后一个节表后面,如图示:
二、绑定导入表的结构
绑定导入表结构:
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;
TimeDateStamp 是时间戳,用于和DLL中的时间戳比较,判断DLL是否已经发生变化;
OffsetModuleName 是当前模块名距离第一个 _IMAGE_BOUND_IMPORT_DESCRIPTOR 的偏移。
NumberOfModuleForwarderRefs 是该模块依赖的模块数量;
依赖模块结构:
typedef struct _IMAGE_BOUND_FORWARDER_REF {
DWORD TimeDateStamp;
WORD OffsetModuleName;
WORD Reserved;
} IMAGE_BOUND_FORWARDER_REF, *PIMAGE_BOUND_FORWARDER_REF;
除了第三个属性保留,其他与 _IMAGE_BOUND_IMPORT_DESCRIPTOR 相同。
三、打印绑定导入表
// 打印绑定导入表
VOID PrintBou