对 Win32 API 调用在汇编中的工作方式感到困惑

2023-12-23

我不知道如何更好地问这个问题,但为什么会这样:

call ExitProcess

与此相同吗?:

mov eax, ExitProcess
mov eax, [eax]
call eax

我认为这些是等效的:

call ExitProcess
mov eax, ExitProcess
call eax

从 DLL 导入代码时,符号ExitProcess实际上并不是退出进程的代码的地址(它是地址的地址)。因此,在这种情况下,您必须取消引用它才能获取实际的代码地址。

这意味着您必须使用:

call [ExitProcess]

来调用它。

例如,有一些代码这个位置 http://forum.codecall.net/topic/65224-intro-to-win32-assembly-using-nasm-part-3/包含以下内容:

;; Note how we use 'AllocConsole' as if it was a variable. 'AllocConsole', to 
;; NASM, means the address of the AllocConsole "variable" ; but since the 
;; pointer to the AllocConsole() Win32 API function is stored in that 
;; variable, we need to call the address from that variable. 
;; So it's "call the code at the address: whatever's at the address
;; AllocConsole" . 
call [AllocConsole] 

然而,直接在用户代码中导入 DLL 并不是获取该函数的唯一方法。我将在下面解释为什么您会看到这两种方式。

调用 DLL 函数的“正常”方法是对其进行标记extern then import来自 DLL:

extern ExitProcess
import ExitProcess kernel32.dll
:
call [ExitProcess]

因为这将符号设置为indirect引用代码,需要间接调用。

经过一番搜索后,它出现在那里is使用裸形式的野外代码:

call ExitProcess

据我所知,这一切似乎都使用alink链接器,它与win32.lib库文件。这个库可能提供了调用的存根actualDLL 代码,类似于:

import ExitProcessActual kernel32.dll ExitProcess
global ExitProcess

ExitProcess:
    jmp [ExitProcessActual]

In nasm,这将导入地址ExitProcess从 DLL 中调用它ExitProcessActual,请记住该地址是对代码的间接引用,而不是代码本身的地址。

然后它将导出ExitProcess入口点(该 LIB 文件中的入口点,而不是 DLL 中的入口点),以便其他人可以使用它。

然后有人可以简单地写:

extern ExitProcess
:
call ExitProcess

退出进程 - 库将跳转到实际的 DLL 代码。


事实上,通过更多的研究,这是exactly发生了什么。来自alink.txt附带的文件alink下载:

Win32 的示例导入库包含为win32.lib。所有命名的导出Kernel32, User32, GDI32, Shell32, ADVAPI32, version, winmm, lz32, commdlg and commctl被包含在内。

Use:

alink -oPE file[.obj] win32.lib

包含它或指定

INCLUDELIB "win32"

在你的源文件中。

这由一系列导入重定向条目组成 -call MessageBoxA,然后它跳转到[__imp_MessageBoxA],位于导入表中。

因此,如果满足以下条件,对导入的调用将运行得更快:call [__imp_importName]被用来代替call importName.

See test.asm,我的示例程序,它以两种方式调用消息框:

includelib "win32.lib"
extrn MessageBoxA:near
extrn __imp_MessageBoxA:dword

codeseg

start:
push 0 ; OK button
push offset title1
push offset string1
push 0
call MessageBoxA

push 0 ; OK button
push offset title1
push offset string2
push 0
call large [large __imp_MessageBoxA]

(__imp_MessageBoxA是从DLL导入的符号,相当于我的ExitProcessActual above).

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

对 Win32 API 调用在汇编中的工作方式感到困惑 的相关文章

随机推荐