Assembly 如何使用NASM以Microsoft Visual Studio的样式生成重新定位?
我正在尝试使用NASM创建一个对象文件,该文件尽可能接近Microsoft Visual Studio 2012生成的文件。我已经非常接近了,但我正在为进口和搬迁而挣扎 具体来说,当我使用Assembly 如何使用NASM以Microsoft Visual Studio的样式生成重新定位?,assembly,nasm,Assembly,Nasm,我正在尝试使用NASM创建一个对象文件,该文件尽可能接近Microsoft Visual Studio 2012生成的文件。我已经非常接近了,但我正在为进口和搬迁而挣扎 具体来说,当我使用cl.exe创建一个对象文件并执行dumpbin/all binary.obj时,我会得到以下感兴趣的行: Offset Type Applied To Symbol Index Symbol Name -------- ------- ---------- -----
cl.exe
创建一个对象文件并执行dumpbin/all binary.obj
时,我会得到以下感兴趣的行:
Offset Type Applied To Symbol Index Symbol Name
-------- ------- ---------- ------------ -----------
00000007 DIR32 00000000 B __imp__GetModuleHandleA@4
但是当我执行dumpbin/all-nasmobj.obj
时,我得到了一个类似但略有不同的行:
Offset Type Applied To Symbol Index Symbol Name
-------- ------- ---------- ------------ -----------
00000007 REL32 00000000 7 __imp__GetModuleHandleA@4
所以区别在于MSVC产生的重定位是“直接”重定位,正如我的NASM代码产生的“相对”重定位一样。我怎样才能解决这个问题
我正在使用以下工具编译我的NASM代码:
nasm -f win32 nasmtst.s
NASM关注的代码是:
SECTION .text
EXTERN __imp__GetModuleHandleA@4
%define GetModuleHandleA (__imp__GetModuleHandleA@4)
; code happens
...
call GetModuleHandleA
...
; more code happens
请注意,
\u imp__GetModuleHandleA@4
是一个导入指针,而不是GetModuleHandleA函数的实际代码位置。Win32 PE通常有一个.idata部分,其中包含收集的所有导入指针,这与ELF的GOT表有些类似:
SECTION .idata
__imp__GetModuleHandleA@4 dd ? ; to be filled by system loader
此部分和所有支持元数据通常由链接器使用导入库生成,但也可以这样做
在您的情况下,以下内容就足够了:
EXTERN __imp__GetModuleHandleA@4
call [__imp__GetModuleHandleA@4]
对于某些汇编器/宏包,可以使用类似于:
call GetModuleHandleA
或
这将导致调用链接器生成的存根:
GetModuleHandleA:
jmp [__imp__GetModuleHandleA@4]
这种方法的优点是只有一个重定位需要修补(对于
jmp
指令),而不是几个(call
指令)。我想删除\u imp\u
可能会有所帮助,但我不是很确定。不幸的是,我也尝试过这样做,但没有成功:(我越来越接近于认为这只是NASM不能这么感谢你的事情!这让我发疯了!
GetModuleHandleA:
jmp [__imp__GetModuleHandleA@4]