7_输入表 (导入表)

7 输入表 (导入表)

总结一下之前我们学过的内容

首先, 我们知道 PE 文件中的数据被载入内存后根据不同的页面属性被划分成很多区块 (节), 并有区块表 (节表) 的数据来描述这些区块. 这里我们需要注意的问题是 : 一个区块中的数据仅仅只是由于属性相同而放在一起, 并不一定是有同一种用途的内容. 例如接着要讲的输入表, 输出表等就有可能和只读常量一起, 被放在同一个区块中, 因为他们的属性都是可读不可写的.

其次由于不同用途的数据有可能被放入同一个区块中, 因此仅仅依靠区块表是无法确定和定位的. 那该怎么办呢 ? 对了, PE 文件头中 IMAGE_OPTIONAL_HEADER32 结构的数据目录表来指出他们的位置, 我们可以由数据目录表来定位数据, 这些数据包括输入表, 输出表, 资源, 重定位表和 TLS 等 15 种数据. (数据目录表, 不要以为它在前边出现就以为它不重要.)

这里我们谈谈输入表. 为什么程序需要输入表呢 ?

我们需要使用外界的函数, 我们不能说我们所有的东西都从数据目录表里面得到.

因为我们从数据目录表得到的仅仅是一些指定数据的 RVA 和数据库的尺寸. 很明显, 不同的数据块中的数据组织方式 (结构) 是显然不同的, 例如输入表和资源数据块中的数据就是完全不相干的东西. 因此, 我们想要深入了解 PE 文件就必须了解这些数据的组织方式, 以及了解系统是如何处理调用它们的.

输入函数

在代码分析或编程中经常遇到 "输入函数" (Import Functions, 也称导入函数) 的概念.

这里解释下, 输入函数就是被程序调用但它的执行代码又不在程序中的函数, 这些函数的代码位于相关的 dll 文件中, 在调用者程序中只保留相关的函数信息 (比如函数名, dll 文件名等) 就可以.

对于磁盘上的 PE 文件来说, 它无法得知这些输入函数在内存中的地址, 只有当 PE 文件被装入内存后, Windows 加载器才将相关 dll 载入, 并将调用输入函数的指令和函数实际所处的地址联系起来. 这就是 "动态链接" 的概念.

动态链接是通过 PE 文件中定义的 "输入表" 来完成的, 输入表中保存的正是函数名称和其驻留的 dll 名称等.