为什么他们习惯在DLL中调用函数?
为什么我不能用绝对地址给他们打电话?
毕竟,它们都没有加载到我的4GB地址空间吗?
答案 0 :(得分:3)
相对调用用于模块内调用,但调用直接内存地址当然是可行的(这可以通过WinAPI函数完成):
FF15 B8401301 CALL DWORD PTR DS:[<&MSVCR100.printf>] ; \printf - note this calling with a pointer to the abs address stored in the IAT
这主要是因为windows dll无法重新分配(加上它们位于特殊的地址空间,因为每个应用程序都有自己的系统dll视图),但用户dll可以轻松重新分配(特别是与ASLR)。 see wikipedia's article on this as well.
此外,不要将间接符号表调用(也称为模块间调用)与纯粹的相对调用混淆。如果您的调用函数在当前模块之外,您将获得对存储在符号表中的绝对地址的相对调用:
CALL MySymb
MySymb: JMP &MySymbAbs
或更好的真实版本:
6FC019E9 E8 300D0000 CALL <JMP.&Storm.#501> ; CALL 6FC0271E without name labeling
6FC0271E - FF25 8071C06F JMP DWORD PTR DS:[<&Storm.#501>] ; Storm.#501
所有这些在很大程度上还取决于你的编译器,有些我直接调用符号用于所有东西,有些只会用于系统dll和/或COM接口。
顺便说一句,在32位x86上,从技术上讲,你在用户态应用程序中没有4gb可用,通常是3GB。