创建远程线程,错误5

CreateRemoteThread, error 5

我正在尝试从我的 32 位进程中将存根注入到 64 位 Windows 进程中,然后远程启动 x64 进程中的线程。这导致了一些问题,因为 winapi 的 CreateRemoteThread is throwing error-code 5 which translates to ERROR_ACCESS_DENIED, no matter which flags I use when calling OpenProcess。我读到这是因为 Windows 不允许注入 "cross-platform",但我认为这不是问题,因为代码注入很好。

我在调用 CreateRemoteThread() 后立即使用 GetLastError(),它显示错误代码 5。

我正在为 OpenProcess 使用这组标志,但没有成功:

PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE

以及 PROCESS_ALL_ACCESS.

有人知道是什么导致了这个错误吗?

无法完成。您不能在 64 位进程中 运行 32 位代码,也不能在 32 位进程中 运行 64 位代码。

解决方案是将您的注入代码重建为 64 位。

这是设计使然。处理器在 32 位和 64 位模式下的工作方式并不完全相同,而且您无法轻松地从一种模式切换到另一种模式,然后再切换回来。有几件事截然不同:

  • Push 和 Pop 指令在 64 位模式下始终是 64 位的。所以 32 位代码会压入 64 位值,因此 void foo(int x, int y) 会得到一个 64 位 x 覆盖 xy。这会影响堆栈上变量的偏移量以及函数内的所有其他内容。
  • 实际调用约定不同 - 32 位模式使用不同且较少的寄存器将参数传递给函数(如果有任何参数通过寄存器传递 - 它是可选的),而 64 位模式始终使用寄存器和更多寄存器。因此,来自 32 位模式的调用会将数据放在 64 位模式的错误位置等。
  • 一些常用指令的指令编码不同——主要是 0x40-0x4f 是针对 PUSH/POP 所有寄存器的单字节指令,其中该范围是 64 位模式下的 REX(寄存器扩展)前缀。 64 位模式使用双字节编码[引入它是为了允许一组更灵活的 PUSH/POP 指令,在第二个字节中描述了多种寻址模式]

还有许多其他不同的东西,但这些应该足以表明"it doesn't work like that"。

不支持从 32 位进程调用 CreateRemoteThread,而目标进程是 64 位。您需要从 64 位进程调用 CreateRemoteThread