我在C和x86和x64程序集中都有一个指向__stdcall函数的指针,我想做的就是拥有一个asm函数,可以用来跳转到该函数。

例如以Windows API函数MessageBoxW

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

然后在C中,我将呼叫ASM,例如
void foo()
{
MessageBoxW_asmstub(NULL, "test", "test", NULL);
}

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

我不知道该怎么做。

最佳答案

假定向C编译器声明MessageBoxW_asmstub具有正确的调用约定(即x86的__stdcall;对于x64,只有一个调用约定),然后正如Ross Ridge的评论所述,这就像跳转到目标一样简单函数,然后直接返回到调用者。由于您有一个间接引用(即fn指向目标的指针),因此您可能需要另一个装入指令(尽管我对x86的了解仅限于此-如果有一些双间接引用,我也不会感到惊讶jmp的形式)。您可以在调用约定中使用任何易失性寄存器来执行此操作,例如对于x64,您可以使用以下方式:

extern fn:qword

MessageBoxW_asmstub:
  mov rax, fn
  jmp rax

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

关于c - MASM和C跳转到功能,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32022250/

10-11 15:33