将x86代码注入x64进程

时间:2012-07-27 19:42:59

标签: c++ winapi x86 64-bit inject

我正在使用x86 dll注入器,我想将x86代码注入x64进程线程并执行它。首先,我在x64进程上调用 CreateRemoteThread 失败,导致错误代码5.然后我找到this trick并且我能够用它创建远程线程。但是当我尝试 ResumeThread 并在x64进程内执行x86代码时,整个进程崩溃。

将x86注入x86效果很好,问题仅在于x86到x64。

所以,我的问题是 - 是否有可能模拟并运行x64进程中复制的x86代码?我知道一种方法是使用相同代码的两个版本,并根据远程进程的体系结构选择一个,但我认为这不是最好的方法。

感谢。

3 个答案:

答案 0 :(得分:4)

段选择器确定位数,所以你所做的就是使用右段选择器“某种形式的远跳”。虽然在64位,但没有那么多方法可以做到这一点。 retf仍有效。

未经测试,但您明白了这一点:

sub rsp, 8
mov dword [rsp+4], 0x23   // 32 bit segment selector
mov dword [rsp], offset some32bitcode
retf

就是这样,你现在处于32位模式。它可能会造成严重破坏(特别是如果你试图调用任何Windows函数),但是你去了 - 你可以做它(只是不要)。

您可以更轻松地切换回来:

jmp far 33h:some64bitcode // 64 bit segment selector

直接远跳是在64位模式下无法编码的。间接远跳/远程呼叫仍然存在,远远返回,这显然是间接的。

23h和33h是windows的值,它可能(并且可能)在其他操作系统上有所不同。

当然,这仍然意味着你必须采用不同的方式处理64位进程。

答案 1 :(得分:3)

您无法在x64进程内运行x86代码,反之亦然。期。操作系统根本不允许它。您只能将x86代码注入x86进程,并将x64代码注入x64进程。

答案 2 :(得分:-1)

我真的怀疑这是否能正常运作。请记住,AMD64架构抛弃了所有INCDEC操作码,以便用REX前缀替换它们,而指令本身则替换为两个字节的等价物。这意味着如果您的x86代码包含编码为一个字节的INCDEC,则在x64中工作时,CPU会将其视为REX前缀,并尝试解码下一个字节。指令流作为正常指令,由于指令被解码为非理性指令,因此肯定会导致一般保护错误或类似情况。

这是一个例子。假设我想使用以下代码(NASM)在循环中访问数组。

bits 32
mov ecx, 200
myloop:
 dec ecx
 mov eax, [myarray+ecx*4+0x100]
 jnz myloop
myarray resb 10

将其编译为平面二进制文件并将其拆解为64位代码后,这就是ndisasm返回的内容:

00000000  B9C8000000        mov ecx,0xc8
00000005  498B048D0F010000  mov rax,[rcx*4+0x10f]
0000000D  75F6              jnz 0x5

正如您所看到的,“循环”实际上不再是循环,因为它的计数器永远不会递减,并且根据最后修改零标志的指令进行跳转。这清楚地表明,指令解码器在32位和64位模式下的工作方式非常不同,在64位模式下运行时,有效地禁止您运行组装为32位的代码。