windows - 实现 x86 到 x64 汇编代码切换

标签 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 process attached ntdll far jump jmp 0x33:0x7738b5cf 的跳转如何进入 x64_NtCreateFile 第一条指令?在这种情况下,从 x86 到 x64 的切换究竟是如何发生的?基本上我可以制作 x86 应用程序,并使用跳转切换段,然后执行其中的 x64 代码,我可以通过执行类似 db (0x00) 的操作来创建它; x64 机器代码命令,这样对吗?

最佳答案

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

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

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

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

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

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

关于windows - 实现 x86 到 x64 汇编代码切换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39310831/

相关文章:

ios - 如何在 Windows 上使用 Objective C 进行编码?

windows - 如何每 2 分钟更新一次 Windows 注册表?

assembly - 为什么在PUSHA指令中执行PUSH BX之前先执行PUSH CX

linux - 在 GDB 的堆栈上执行?

linux - 读写文件汇编

reverse-engineering - OllyDbg 捕获/抛出异常

C结构体完成函数的汇编代码

windows - 如何在 Windows 环境中使用 Trac 和 SVN 实现 Post Commit Hook?

reverse-engineering - 如何在内存中找到代表 Minesweeper 排雷布局的数据结构?

windows - WSL 可以继承 Windows 身份验证凭据吗