我正在使用x86 dll注入器,我想将x86代码注入x64进程线程并执行它。首先,我在x64进程上调用 CreateRemoteThread 失败,导致错误代码5.然后我找到this trick并且我能够用它创建远程线程。但是当我尝试 ResumeThread 并在x64进程内执行x86代码时,整个进程崩溃。
将x86注入x86效果很好,问题仅在于x86到x64。
所以,我的问题是 - 是否有可能模拟并运行x64进程中复制的x86代码?我知道一种方法是使用相同代码的两个版本,并根据远程进程的体系结构选择一个,但我认为这不是最好的方法。
感谢。
答案 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架构抛弃了所有INC
和DEC
操作码,以便用REX前缀替换它们,而指令本身则替换为两个字节的等价物。这意味着如果您的x86代码包含编码为一个字节的INC
或DEC
,则在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位的代码。