实现x86到x64汇编代码切换

时间:2016-09-03 19:57:54

标签: windows assembly reverse-engineering x86-64 ntdll

我正在查看NtDll如何为x86进程工作,我使用IDA PRO调试了函数NtCreateFile。它的代码如下:

mov     eax, 55h        ; NtCreateFile
mov     edx, offset _Wow64SystemServiceCall@0 ; 
call    edx ; Wow64SystemServiceCall() ; 
retn    2Ch

Wow64SystemServiceCall()

mov     edx, large fs:30h
mov     edx, [edx+464h]
test    edx, 2
jz      short loc_7738B5C8
int     2Eh             ; DOS 2+ internal - EXECUTE COMMAND
                        ; DS:SI -> counted CR-terminated command string
retn
loc_7738B5C8:                           ; CODE XREF: 
jmp     far ptr byte_7738B8FF

我查找了jmp far ptr byte_7738B8FF的命令代码 它是EA CF B5 38 77 33 00,是跳转到另一个段,0x33 jmp 0x33:0x7738b5cf。因此,根据我在互联网上阅读的内容,这是64位系统上进程的x64段基础,对吧?不幸的是我无法进一步调试,因为,ida并没有跟随跳跃。但我为x64编写了另一个简单的C应用程序,并调用了CreateFile,附加了x64 IDA PRO远程调试器,并查找了反汇编,NtCreateFile看起来像是这样:

x64_NtCreateFile proc near  
mov     r10, rcx
mov     eax, 55h
test    byte ptr ds:7FFE0308h, 1
jnz     short loc_7FFED6695B85
syscall
retn
loc_7FFED6695B85:                     
int     2Eh             ; DOS 2+ internal - EXECUTE COMMAND
                        ; DS:SI -> counted CR-terminated command string
retn

所以我有几个问题,从x86进程附加ntdll跳远jmp 0x33:0x7738b5cf的跳转是如何进入x64_NtCreateFile第一条指令?在这种情况下,如何从x86切换到x64?基本上我可以创建x86应用程序,并使用跳转来切换段,只需在那里执行x64代码,我可以通过执行类似db (0x00) ; x64 machine code commands的操作来创建,这是对的吗?

2 个答案:

答案 0 :(得分:3)

如果查看地址0x7738b5cf处的字节,您会看到类似

的内容

41 FF A7 F8 00 00 00(至少如果您使用的是Windows 8.1或更高版本)

对应于单个x86_64指令jmp QWORD PTR [r15+0xf8]

通过远程跳转从32位切换到64位代码后,R15寄存器将始终指向wow64cpu.dll内的特殊跳转表(R15寄存器设置为从64位代码指向此表,该代码在应用程序的32位入口点之前执行。)

[r15+0xf8]恰好指向CpupReturnFromSimulatedCode中的wow64cpu.dll方法,该方法将设置正确的上下文并执行实际的系统调用(在您的情况下为NtCreateFile)使用syscall指令。

有关详细说明的一些信息,请参阅:

答案 1 :(得分:2)

是的,我可以确认可以在64位Windows上运行的32位Windows应用程序中执行64位代码。

Mixing x86 with x64 code提供了解释和如何执行此操作的示例。

这是我尝试过的(适合我的Smaller C编译器编译):

header('Access-Control-Allow-Origin: *');
header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept");
header('Access-Control-Allow-Methods: GET, POST, PUT');

然后我在调试器下运行它并注意到当第二个断点被击中时,eax包含64位指令“lea rax,[$]”的地址。