2013-10-30 53 views
6

首先,我不想注入一个dll。我想使用WriteProcessMemory()注入代码(如果这甚至可能)。我已经使用ReadProcessMemory(),所以我认为写作不是什么大不了的事。
好吧,让我们说有在TargetProgram.exe + D78C612
的功能,让我们说,它可以被称为是这样的:C++:代码注入调用函数

push eax 
push [esp+08] 
push edx 
push 00 
push TargetProgram.exe+AF76235 
push 04 
call TargetProgram.exe+D78C612 

我究竟将如何做到这一点用WriteProcessMemory的()?
我的意思是我在哪里可以找到一段可以注入我的代码而不会覆盖重要内容的部分。最重要的是,我将如何调用这个函数?
只需在活动例程中跳转到我的代码,之后跳回并删除它?但是,我如何找到这个例程呢?
这么多问题,我不知道如何开始......我希望你能帮助我。 :)
如果你有时间,我真的很想看到一个函数调用注入的示例代码。

回答

4

您可以使用VirtualAllocEx在远程进程中分配内存,然后将您的程序复制到此内存中。

这里是做注射步骤:

SuspendThread(hThread); // Suspend the remote thread 
remote_address = VirtualAllocEx(hProcess, ...) // allocate memory for your code 
WriteProcessMemory(hProcess, remote_address, local_address, length, NULL) // copy your code to remote process 
WriteProcessMemory(hProcess, remote_fixup, ...) // insert a jump to your code 
ResumeThread(hThread); // Resume the remote thread 
+0

我有一个类似的问题作为OP,但我没有得到你的第一WriteProcessMemory调用。作为local_address,我可以传递函数的地址,但我无法在下一个参数中传递它的长度。只是因为我不知道它有多大(因为编译器还没有编译它)。那么WriteProcessMemory是否适合从我的过程写入另一个函数/代码?编辑:或者是汇编程序中唯一的关键写入函数(我可以计算它)而不是C++? – Kra

+2

@Kra在大多数情况下,您不能将C函数复制到另一个进程,因为跳转地址将被破坏。您必须修复relocs或编写可重定位的代码。在这两种情况下,你都必须使用汇编语言。为了回答你关于函数代码长度的问题,我认为你可以尝试禁用优化并写两个函数f1()和f2(),其中f2代码中的f1。然后你可以从f2的地址中减去f1的地址,[希望]得到f1的长度。但函数大小是你问题最少的地方。 – Max

+0

明白了。谢谢。 – Kra

1

正如马克斯的答复中提到,VirtualAllocEx是在远程进程分配内存页的一种方式,假设你有在过程中PROCESS_VM_OPERATION访问权题。您还需要确保新的页面在写入期间标记为PAGE_EXECUTE_READWRITE以保护其级别,然后使用VirtualProtectEx将其更改为PAGE_EXECUTE_READ

请注意,x86中的分支和某些调用指令是IP相对的。这意味着它们的编码取决于它们在内存中的位置,因为它们从指令的末尾使用带符号的相对位移。因此,如果您计划从新代码调用现有函数,请确保在使用相对调用指令时考虑到这一点,或者使用间接/即时形式。

但是,如果您不知道您要在此完成的工作,很难推荐一种用于执行新目标代码的技术。使用新的代码,您可以使用CreateRemoteThread注入远程线程来执行它,而不必中断任何现有的线程。这将是执行新代码的最简单的解决方案,但要求您调用的代码是线程安全的。挑选一个已经运行的线程,挂起它,修改EIP或者引入一个绕道,并且无副作用地恢复它(在注入的调用中正确保存上下文)是非常棘手的。

个人注意事项:作为Visual Studio 2012中的代码覆盖工具的作者,它使用一堆技巧动态地重写第三方x86/x86-64代码来收集覆盖率数据,这个东西是哦,所以 - 很有趣的破解和思考:)