102
信息安全中心安全沙龙 逆向工程 Windows(一)
的代码位于相关的 DLL 文件中,在调用者程序中只保留相关的函数信息(如函数
名、DLL 文件名等)就可以。对于磁盘上的 PE 文件来说,它无法得知这些在内
存中的地址,只有当 PE 文件被装入内存后输入函数,Windows 加载器才将相关
DLL 装入,并将调用输入函数的指令和函数实际所处的地址联系起来。这就是
“动态链接”的概念。动态链接是通过 PE 文件中定义的“导入表”来完成的,
导入表中保存的正是函数名和其驻留的 DLL 名等。
导入表是以一个 IMAGE_IMPORT_DESCRIPTOR (简称 IID) 的数组开始。每
个被 PE 文件链接进来的 DLL 文件都分别对应一个 IID 数组结构。在这个 IID
数组中,并没有指出有多少个项(就是没有明确指明有多少个链接文件),但它最
后是以一个全为 NULL(0) 的 IID 作为结束标志。
①联合体值为 0 时(一般用 Characteristics 判断是否是 0),表示这是导
入表结构体数组最后一个元素,除了最后这一个元素,其它每一个结构体都保存
了一个 dll 信息。联合体的值不为 0 时,用 OriginalFirstThunk(RVA)来索引
Import Name Table(INT)的地址。这张 INT 表存放了该 dll 的导出函数的信息
(序号与函数名)。
②TimeDateStamp:当时间戳值为 0 时,表示未加载前,Import Address Table
(IAT)与 Import Name Table(INT)完全相同;当时间戳不为 0(为-1)时,
表示 IAT 与 INT 表不同,IAT 存储的是该 dll 的所有函数的绝对地址,这样在未
加载前就直接填充函数地址的方式为函数地址的绑定,其地址是根据绑定导入表
来确定的。也就是说当时间戳为-1 时绑定导入表才有效,而真正的时间戳存放
到绑定导入表中,否则无效。
③ForwarderChain:一般情况下我们也可以忽略该字段。在老版的绑定中,
它引用 API 的第一个 forwarder chain(传递器链表)。
④Name:RVA 指向 dll 的名字字符串。
⑤FirstThunk:RVA 指向 IAT 表。