【发布时间】:2014-05-11 02:02:42
【问题描述】:
调用 DLL 函数涉及链接器生成存根,除非函数声明为 __declspec(dllimport),在这种情况下,可以绕过存根,直接调用导入表更高效,例如
__declspec(dllimport) void ExitProcess(int);
ExitProcess(0);
生成
call qword ptr [__imp_ExitProcess]
其中__imp_ExitProcess 解析为可执行文件中导入表中的某个位置。
我试图弄清楚__imp_ExitProcess 是如何解决的。可以肯定的是,它在 kernel32.lib 中作为一个符号出现,但该符号具有存储类 IMAGE_SYM_CLASS_EXTERNAL,节号为零且值为零,这相当于只是说“这将在其他地方定义”而实际上没有定义它。
__imp_ 前缀是否有特殊含义,即链接器是否注意到该前缀并将其作为将符号解析为名称已删除该前缀的 DLL 函数的导入表条目的指令?还是发生了其他事情?
【问题讨论】:
-
你在看哪个
kernel32.lib? -
@IgorSkochinsky Microsoft C++ 2013 附带的 64 位版本。286522 字节。
-
它是外部的,在 kernel32.dll 中的其他地方定义。这由加载程序在运行时解决。前缀没有意义。
-
@HansPassant 对,加载器在运行时从导入表工作,并不关心前缀。但是在链接时,链接器如何知道
__imp_ExitProcess应该指向导入表而不是作为未定义符号被拒绝?
标签: windows dll linker reverse-engineering portable-executable