创建远程线程,错误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
覆盖 x
和 y
。这会影响堆栈上变量的偏移量以及函数内的所有其他内容。
- 实际调用约定不同 - 32 位模式使用不同且较少的寄存器将参数传递给函数(如果有任何参数通过寄存器传递 - 它是可选的),而 64 位模式始终使用寄存器和更多寄存器。因此,来自 32 位模式的调用会将数据放在 64 位模式的错误位置等。
- 一些常用指令的指令编码不同——主要是 0x40-0x4f 是针对 PUSH/POP 所有寄存器的单字节指令,其中该范围是 64 位模式下的 REX(寄存器扩展)前缀。 64 位模式使用双字节编码[引入它是为了允许一组更灵活的 PUSH/POP 指令,在第二个字节中描述了多种寻址模式]
还有许多其他不同的东西,但这些应该足以表明"it doesn't work like that"。
不支持从 32 位进程调用 CreateRemoteThread
,而目标进程是 64 位。您需要从 64 位进程调用 CreateRemoteThread
。
我正在尝试从我的 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
覆盖x
和y
。这会影响堆栈上变量的偏移量以及函数内的所有其他内容。 - 实际调用约定不同 - 32 位模式使用不同且较少的寄存器将参数传递给函数(如果有任何参数通过寄存器传递 - 它是可选的),而 64 位模式始终使用寄存器和更多寄存器。因此,来自 32 位模式的调用会将数据放在 64 位模式的错误位置等。
- 一些常用指令的指令编码不同——主要是 0x40-0x4f 是针对 PUSH/POP 所有寄存器的单字节指令,其中该范围是 64 位模式下的 REX(寄存器扩展)前缀。 64 位模式使用双字节编码[引入它是为了允许一组更灵活的 PUSH/POP 指令,在第二个字节中描述了多种寻址模式]
还有许多其他不同的东西,但这些应该足以表明"it doesn't work like that"。
不支持从 32 位进程调用 CreateRemoteThread
,而目标进程是 64 位。您需要从 64 位进程调用 CreateRemoteThread
。