PE学习(14) 绑定导入表介绍与解析

有些WINDOWS程序为了提高加载速度,会直接把DLL中的函数地址写入到IAT表

例如上一篇文章里提到的,打印NOTEPADIAT表其中Name为空(这里其实是函数地址)

 

但是这样会有两个问题:

(1)当DLL没有占住ImageBaseIAT中的地址就是错的

(2)当链接的DLL被修改后IAT里写的地址也是错的

遇到这两种情形之一,加载时就必须修复IAT表

对于第二种情形,DLL是否被修改,是根据比较DLL的时间戳和绑定导入表中的记录的DLL时间戳来判断的,如果不一致,说明DLL被修改了

加载程序时,操作系统根据导入表中的时间戳来判断程序是否使用了绑定导入。当时间戳为0,表示不使用绑定导入表;当时间戳为0xFFFFFFFF,说明该程序使用绑定导入

对于使用绑定导入的程序,绑定导入表存储在最后一个节表后面(数据目录最后一部分)

 

绑定导入表结构:

字段说明:

 

依赖模块结构:

属性意思相同,其中Reserved字段保留无意义

 

解析

省略头部解析代码

数据目录第二个是导入表,其中的时间戳如果是0表示不存在绑定导入表

遍历所有绑定导入表

这里的OffsetModuleName偏移不是RVA也不是FOA而是相对于第一个绑定导入表的偏移,因此需要在循环前复制一份第一个绑定导入表,在输出DLL名称以及依赖名称时使用

类似地,打印依赖时也需要使用这种计算方式

 

整体代码

 

打印NOTEPAD的截图