混淆Win32 API调用如何在程序集中工作

Hud*_*den 4 windows x86 assembly winapi nasm

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

call ExitProcess
Run Code Online (Sandbox Code Playgroud)

做同样的事情吗?:

mov eax, ExitProcess
mov eax, [eax]
call eax
Run Code Online (Sandbox Code Playgroud)

我认为这些是等价的:

call ExitProcess
Run Code Online (Sandbox Code Playgroud)


mov eax, ExitProcess
call eax
Run Code Online (Sandbox Code Playgroud)

pax*_*blo 8

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

这意味着你必须使用:

call [ExitProcess]
Run Code Online (Sandbox Code Playgroud)

打电话给它.

例如,此位置的代码包含以下内容:

;; 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] 
Run Code Online (Sandbox Code Playgroud)

但是,直接在用户代码中导入DLL并不是获取该功能的唯一方法.我会解释为什么你会看到以下两种方式.

调用DLL函数的"正常"方法是从DLL中标记它extern然后import:

extern ExitProcess
import ExitProcess kernel32.dll
:
call [ExitProcess]
Run Code Online (Sandbox Code Playgroud)

因为它将符号设置为对代码的间接引用,所以需要间接调用它.

经过一番搜索,似乎有在使用中的裸野代码:

call ExitProcess
Run Code Online (Sandbox Code Playgroud)

据我所知,这一切似乎都使用了alinkwin32.lib库文件链接的链接器.这个库可能提供了用于调用实际 DLL代码的存根,例如:

import ExitProcessActual kernel32.dll ExitProcess
global ExitProcess

ExitProcess:
    jmp [ExitProcessActual]
Run Code Online (Sandbox Code Playgroud)

nasm,这将导入ExitProcessDLL 的地址并调用它ExitProcessActual,请记住,该地址是代码的间接引用,而不是代码本身的地址.

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

然后有人可以简单地写:

extern ExitProcess
:
call ExitProcess
Run Code Online (Sandbox Code Playgroud)

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


事实上,通过更多的研究,这正是正在发生的事情.从下载alink.txt附带的alink文件:

包含Win32的示例导入库win32.lib.在所有命名出口Kernel32,User32,GDI32,Shell32,ADVAPI32,version,winmm,lz32,commdlgcommctl都包括在内.

使用:

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]
Run Code Online (Sandbox Code Playgroud)

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

  • 是的,这是因为它在导入表中.至于评论的第二部分,我不知道.我会认为_Would not_工作,除非由于导入或调用`ExitProcess`的方式发生了一些魔法,例如,如果`ExitProcess`被赋予真正的代码目标而不是IAT中的地址.我自己从未使用过"裸体"版本. (3认同)