对Win32 API调用在组装中的工作方式感到困惑 [英] Confusion with how Win32 API calls work in assembly
问题描述
我不知道如何更好地提出这个问题,但是为什么这样做:
call ExitProcess
与此相同吗?:
mov eax, ExitProcess
mov eax, [eax]
call eax
我认为这些是等效的:
call ExitProcess
mov eax, ExitProcess
call eax
从DLL导入代码时,符号ExitProcess
实际上不是退出进程的代码地址(它是地址地址).因此,在这种情况下,必须取消引用它才能获取实际的代码地址.
这意味着您必须使用:
call [ExitProcess]
调用它.
例如,在
但是,直接在用户代码中导入DLL并不是获得该功能的唯一方法.我将在下面解释为什么您同时看到两种方式. 调用DLL函数的正常"方法是先将其标记为 由于将符号设置为对代码的间接引用,因此需要间接调用它. 经过一番搜索后,似乎出现了 is 代码,它们使用裸露的形式: 据我所知,这似乎都使用了 在 然后它将导出 然后有人可以简单地写: 退出该过程-库将跳转到实际的DLL代码. 事实上,经过更多的研究,这确实是确切的.从 用于Win32的示例导入库包含在 使用: 包含或指定 在您的源文件中. 这由一系列用于导入重定向的条目- 如果使用 请参阅我的示例程序
( I don't know how to ask this better but why does this: do the same as this?: I would think that these would be equivalent:
When importing the code from a DLL, the symbol That means that you must use: to call it. For example, there's some code at this location containing the following:
However, importing the DLL directly in user code is not the only way to get at the function. I'll explain why you're seeing both ways below. The "normal" means of calling a DLL function is to mark it Because that sets up the symbol to be an indirect reference to the code, you need to call it indirectly. After some searching, it appears there is code in the wild that uses the naked form: From what I can tell, this all seems to use the In It would then export the Then someone could simply write: to exit the process - the library would jump to the actual DLL code. In fact, with a little more research, this is exactly what's happening. From the A sample import library for Win32 is included as Use: to include it or specify in your source file. This consists of a series of entries for import redirection - Thus calls to imports will run faster if See
( 这篇关于对Win32 API调用在组装中的工作方式感到困惑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
extern
,然后从DLL中将其标记为import
:extern ExitProcess
import ExitProcess kernel32.dll
:
call [ExitProcess]
call ExitProcess
alink
链接程序,该链接程序与win32.lib
库文件链接.该库可能提供了用于调用 actual DLL代码的存根,例如:import ExitProcessActual kernel32.dll ExitProcess
global ExitProcess
ExitProcess:
jmp [ExitProcessActual]
nasm
中,这将从DLL导入ExitProcess
的地址并称为ExitProcessActual
,请记住,该地址是对代码的间接引用,而不是代码本身的地址. /p>
ExitProcess
入口点(此LIB文件中的一个,而不是DLL中的一个),以便其他人可以使用它.extern ExitProcess
:
call ExitProcess
alink
下载随附的alink.txt
文件中:
win32.lib
中.包括Kernel32
,User32
,GDI32
,Shell32
,ADVAPI32
,version
,winmm
,lz32
,commdlg
和commctl
的所有命名导出.alink -oPE file[.obj] win32.lib
INCLUDELIB "win32"
call MessageBoxA
组成,它跳转到导入表中的[__imp_MessageBoxA]
.call [__imp_importName]
而不是call importName
,则对导入的调用将运行得更快.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
).call ExitProcess
mov eax, ExitProcess
mov eax, [eax]
call eax
call ExitProcess
mov eax, ExitProcess
call eax
ExitProcess
isn't actually the address of the code that exits your process (it's the address of the address). So, in that case, you have to dereference it to get the actual code address.call [ExitProcess]
;; 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]
extern
then import
it from the DLL:extern ExitProcess
import ExitProcess kernel32.dll
:
call [ExitProcess]
call ExitProcess
alink
linker, which links with the win32.lib
library file. It's possible that this library provides the stub for calling the actual DLL code, something like:import ExitProcessActual kernel32.dll ExitProcess
global ExitProcess
ExitProcess:
jmp [ExitProcessActual]
nasm
, this would import the address of ExitProcess
from the DLL and call it ExitProcessActual
, keeping in mind that this address is an indirect reference to the code, not the address of the code itself.ExitProcess
entry point (the one in this LIB file, not the one in the DLL) so that others could use it.extern ExitProcess
:
call ExitProcess
alink.txt
file which comes with the alink
download:
win32.lib
. All named exports in Kernel32
, User32
, GDI32
, Shell32
, ADVAPI32
, version
, winmm
, lz32
, commdlg
and commctl
are included.alink -oPE file[.obj] win32.lib
INCLUDELIB "win32"
call MessageBoxA
, and it jumps to [__imp_MessageBoxA]
, which is in the import table.call [__imp_importName]
is used instead of call importName
.test.asm
, my sample program, which calls up a message box both ways: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
is the symbol imported from the DLL, equivalent to my ExitProcessActual
above).