使MS Visual C++编译器将Win32 API导入调用视为(未解析)外部符号

使MS Visual C++编译器将Win32 API导入调用视为(未解析)外部符号

问题描述:

是否有可能使MS Visual C++编译器将Win32 API导入调用视为(未解析)外部符号?使MS Visual C++编译器将Win32 API导入调用视为(未解析)外部符号

换句话说,我需要改变dword ptr调用,参考了一些IAT,如:

FF 15 00 00 00 00 call  dword ptr [[email protected]] 

到外部符号调用,如:

E8 00 00 00 00  call  [email protected] 

这意味着编译后我不需要链接,因为显然这是不可能的。所以作为一个产品,我想获得(MS)COFF .obj文件,这种不寻常的Win32 API调用。

+1

为什么连接“明显”不可能? –

+2

这没有什么意义,'__imp_MessageBoxA @ 16'与'_MessageBoxA @ 16'完全一样“无法解析”。这个区别是由声明中'__declspec(dllimport)'属性引起的,编译器#从WinUser.h包含它,这是一个优化。通过重新声明函数来优化优化并不会使其“更好”,因此始终需要链接导入库。只有使用LoadLibrary + GetProcAddress才能避免链接。 –

+0

@BoPersson,因为Win32 API函数在系统DLL中定义,系统DLL在启动时加载到进程中。因此,在链接阶段,您无法使用真正的Win32 API函数来解析这些符号。但是,是的,我必须承认,链接可以用“假”符号来完成。 – RIscRIpt

正如在问题的评论中指出的,Win32 API调用编译为call [__imp__xxx]的原因是__declspec(dllimport)

因此,要实现问题中提出的问题,必须定义所有Win32 API函数,而不必使用__declspec(dllimport)

在Win32头文件(如WinUser.h)中,您可以看到所有函数都使用宏定义,WINxxxAPI宏又定义在apisetcconv.h中。在后面的文件WINxxxAPI宏定义为DECLSPEC_IMPORT,而后者又定义为__declspec(dllimport)

所以,一个简单的方法来达到要求与以下空预处理器定义(see /D flag),以重新定义DECLSPEC_IMPORT

/DDECLSPEC_IMPORT= 

即相当于

#define DECLSPEC_IMPORT 

附:如果有其他方法,我仍然想知道它们。

+0

只需添加'user32.lib'作为链接器输入。你有* pe * – RbMm

+0

你会意识到这并不能消除对IAT的需求。对于代码来说,对'_MessageBoxA @ 16'的调用需要解析为一个只包含'jmp dword ptr [__imp__MessageBoxA @ 16]'的存根。 –

+0

是的,我明白这一点。您可以查看我的[与RbMm的对话](http://chat.*.com/rooms/153552/discussion-between-riscript-and-rbmm)以了解背景故事,为什么我需要它以及我想要如何使用这个。 Tl; dr:如果您进行运行时链接,则不需要IAT,因为您可以使用GetProcAddr获取活动进程中所有函数的地址,也可以手动检查活动进程中的DLL的IAT。 – RIscRIpt