MASM和C跳转到函数

3

我有一个指向C语言中__stdcall函数的指针,无论是x86还是x64汇编,我希望有一个asm函数来跳转到该函数。

例如,以Windows API函数MessageBoxW为例。

void *fn = GetProcAddress(GetModuleHandle("kernel32.dll"), MessageBoxW);

然后在C语言中,我会像这样调用汇编:

void foo()
{
MessageBoxW_asmstub(NULL, "test", "test", NULL);
}

假设fn是全局变量。然后在汇编中,我想要一个只转发到MessageBoxW而不调用它的函数。换句话说,我希望MessageBoxW清理传递给MessageBoxW_asmstub的变量,然后返回foo。
jump (fn) ?

我不知道如何做这个。

在x86上,您需要遵循stdcall调用约定和在x86上的Microsoft x64调用约定(x86上没有stdcall)。根据您在MessageBoxW_asmstub中所做的操作,可以使用简单的“jmp fn”指令来完成此操作。这假设您将所有非易失性和参数寄存器以及堆栈保留在asmstub入口点处的确切状态中。在大多数情况下,这应该不难做到。 - Ross Ridge
1个回答

0
假设MessageBoxW_asmstub已经被C编译器声明为具有正确的调用约定(即x86的__stdcall;对于x64,仅有一种调用约定),那么根据Ross Ridge的评论所说,这就像是简单地跳转到目标函数,然后目标函数将直接返回给调用者。由于您有一个间接引用(即fn指向目标的指针),您可能需要另一个加载指令(尽管我在x86方面的知识有限--如果有某种双重间接形式的jmp,我一点也不会感到惊讶)。您可以使用调用约定中的任何易失性寄存器来执行此操作,例如对于x64,您可以使用以下内容:
extern fn:qword

MessageBoxW_asmstub:
  mov rax, fn
  jmp rax

顺便说一句,如果您使用调试器来逐步执行对延迟加载的DLL导入的调用,您可能会看到链接器生成的存根函数中使用了类似的模式。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接