【发布时间】:2018-01-31 18:23:22
【问题描述】:
英特尔处理器 视窗 10 64 位 C++ x86 汇编
我有两个程序,都是我用 C++ 编写的。为了简单起见,我将它们称为程序 A 和程序 B。它们实际上并没有做任何特别的事情,我只是用它们来测试一些东西并在此过程中获得一些乐趣。
想法是程序A将代码注入程序B,注入的代码将设置程序B中函数的参数,并调用程序B中的函数。
我必须说我从这个实验中学到了很多东西。由于我需要打开具有适当权限的进程的句柄,然后构造要注入的汇编代码,因此使用 CreateRemoteThread 调用它并随后进行清理。
我已经设法做到了这一点,并从程序 B 中调用了一个函数,该函数采用一个 UINT64 类型的参数。
我通过注入以下汇编代码来做到这一点:
b9 paramAddr
e8 funcAddr
c3
通过在程序 B 中使用 CreateRemoteThread 从程序 A 调用此代码 sn-p,我设法在地址处调用函数并传递参数。这很好用。没有什么太复杂的,只需调用一个接受一个参数的函数。这里需要注意的一点是,我在这段代码之前已经注入了参数,并且只是为 b9 提供了一个参数地址。
现在我没有做的是从程序 A 中调用程序 B 中的一个函数,该函数接受两个参数。
函数示例: myFunction(uint num1, int num2)
注入的过程是相同的,并且所有工作都很好 Windows API 提供了大量有据可查的功能。
我不能够做的是将两个参数传递给函数。这就是我的麻烦开始的地方。我一直在研究 x86 汇编函数调用约定。他们所做的只是
push param2
push param1
call functAddr
retn
或
执行 mov 到 esi
谁能澄清、解释并提供一个清晰的例子来说明如何在 x86 程序集中调用一个函数,该函数采用两个参数或类型为 uint 和 int。
感谢大家的时间和精力。
【问题讨论】:
-
在 x86-64 上,一些参数在堆栈上的其他寄存器中传递。从en.wikipedia.org/wiki/X86_calling_conventions开始
-
第一个参数在
rcx,第二个在rdx(然后是r8和r9)。您还需要创建一个home area,可能通过sub rsp, 20h。 -
@MargaretBloom 取决于调用约定...
-
@Macmade 是的。使用 VC++ 编译的 Windows 64 位 C++ 代码,上次我检查时使用了这个调用约定。
-
如果程序 A 不是调试器,则它无法使用
CreateRemoteThread。该 API 甚至存在是 Windows 中最大的单一设计错误的有力竞争者。
标签: c++ c function assembly x86