PE文件格式(2)
2007-01-14 20:15:04 来源:WEB开发网要按照名字找出输出符号,沿着AddressOfNames'RVA,找到指向包含输出名字的RVAs的数组,其中每个RVA指向一个名字。搜索名字,使用名字的索引在AddressOfNameOrdinals数组得到与相应名字对应的16位数(按照PE规范,此数值为输出函数的序号,需要减去BASE得到索引)。根据经验,这就是索引,不是序号,不必减去BASE,直接使用该索引在'AddressOfFunctions'数组找出输出函数的的RVA或者是一个指向转发串。
输入表importedsymbols
----------------
当编译器发现一个调用的函数在其他可执行文件(一般是DLL)内,它将不知道这个情况,简单输出一个调用符号的指令,其地址由链接器添上。链接器使用输入库查询哪个DLL哪个符号被引入。为所有引入的符号产生STUB,每个由一个跳转指令构成,STUB是真正的调用目标,这些跳转指令真正跳到一个从地址表内取出的地址。在复杂的应用中,当"__declspec(dllimport)"被使用的时候,编译器知道函数被引入,并输出一个对输入表内的地址的调用。无论如何,DLL内的函数地址总是必须的,来自输出DLL的输出目录的地址被提供给加载器,加载器知道哪个符号需要查找,通过搜索输入目录修正地址。下面是一个例子:
一个带有/不带有声明__declspec(dllimport)的调用如下:
源程序:
intsymbol(char*);
__declspec(dllimport)intsymbol2(char*);
voidfoo(void)
{
inti=symbol("bar");
intj=symbol2("baz");
}
汇编程序:
...
call_symbol ;无declspec(dllimport)
...
call[__imp__symbol2] ;有declspec(dllimport)
...
第一种情况,没有声明,编译器不知道'_symbol'在一个DLL,于是链接器必须提供此函数。因为函数不在那里,它将提供一个STUB函数对应输入符号,作为一个间接跳转。所有的输入STUB的集合称作转换区或跳板,因为跳到那里为的是跳到另一个地方。该跳板典型的位于代码区,不是输入目录的一部分。每个函数的STUB是一个跳转到DLL的实际函数的JUMP,跳板区看起来如下:
更多精彩
赞助商链接