如何在 x86 汇编中调用函数并将参数传递给它

How to call a function and pass arguments to it in x86 assembly

本文关键字:参数传递 函数 调用 x86 汇编      更新时间:2023-10-16

Intel CPU 视窗 10 64 位 C++ x86 程序集

我有两个程序,都是我用C++编写的。为简单起见,我将它们称为程序 A 和程序 B。他们真的没有做任何特别的事情,我只是用它们来测试事情并在此过程中获得一些乐趣。

这个想法是程序A将代码注入程序B,注入的代码将在程序B中设置函数的参数,并将调用程序B中的函数。

我必须说我从这个实验中学到了很多东西。由于我需要打开具有适当权限的进程的句柄,然后构造要注入的汇编代码,因此请使用 CreateRemoteThread 调用它并在之后进行清理。

我已经设法做到这一点并从程序 B 调用一个函数,该函数采用一个 UINT64 类型的参数。

我通过注入以下汇编代码来做到这一点:

b9 paramAddr
e8 funcAddr
c3

通过在程序 B 中使用 CreateRemoteThread 从程序 A 调用此代码片段,我设法在一个地址处调用一个函数并传递了一个参数。这工作正常。没有什么太复杂的,只需调用一个接受一个参数的函数。这里要注意的一点是,我在此代码之前注入了参数,并且只是向 b9 提供了一个参数地址。

现在我未能做的是从程序 A 调用程序 B 中的一个函数,该函数采用两个参数。

函数示例: myFunction(uint num1, int num2)

注入的过程是相同的,所有工作正常 Windows API 提供了大量文档齐全的功能。

我无法做的是将两个参数传递给函数。这就是我的烦恼开始的地方。我一直在研究 x86 汇编函数调用约定。他们所做的要么只是

push param2
push param1
call functAddr
retn

对 ESI 执行 MOV 操作

任何人都可以澄清,解释并提供一个清晰的示例,说明如何在x86程序集中调用一个需要两个参数或键入uint和int的函数。

谢谢大家的时间和努力。

由于您正在寻找一种理解和澄清内部发生的事情的方法,因此我建议您从为您正在使用的特定机器生成汇编程序文件开始。如果您使用的是 gcc 或 g++,则可以使用-S标志生成关联的汇编程序文件。首先,您可以实现一个带有两个参数的函数,并在主函数中调用该函数。使用汇编器文件,您应该非常清楚地了解在调用函数之前堆栈是如何填充的,以及返回值的位置。在下一步中,您应该将汇编程序文件中的内容与 x86 调用对流进行比较。