[英]Implement x86 to x64 assembly code switch
我一直在尋找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
。 因此,從我在Internet上閱讀的內容來看,這是64位系統上進程的x64段基礎,對嗎? 不幸的是,我無法進一步調試,因為ida並沒有跟上跳轉。 但是我制作了另一個針對x64編譯的簡單C應用程序,名為CreateFile
,附加了x64 IDA PRO Remote調試器,並進行了反匯編,而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
所以我有幾個問題,如何從附加了ntdll的x86進程跳轉遠跳轉到jmp 0x33:0x7738b5cf
才進入第一個指令x64_NtCreateFile
? 從x86到x64的切換在這種情況下究竟如何發生? 基本上,我可以制作x86應用程序,並通過跳轉切換段,然后在其中執行x64代碼,我可以通過執行db (0x00) ; x64 machine code commands
類的操作來創建該代碼db (0x00) ; x64 machine code commands
db (0x00) ; x64 machine code commands
,對嗎?
如果查看地址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
指令。
有關詳細信息,請參閱:
是的,我可以確認人們可以在64位Windows上運行的32位Windows應用程序中執行64位代碼。
將x86與x64代碼混合在一起將提供說明和操作方法示例。
這是我嘗試過的(適用於我的Smaller C編譯器,並使用它編譯):
#define EM(a) asm("db " #a);
#define X64_Start_with_CS(_cs) \
{ \
EM(0x6A) EM(_cs) /* push _cs */ \
EM(0xE8) EM(0) EM(0) EM(0) EM(0) /* call $+5 */ \
EM(0x83) EM(4) EM(0x24) EM(5) /* add dword [esp], 5 */ \
EM(0xCB) /* retf */ \
}
#define X64_End_with_CS(_cs) \
{ \
EM(0xE8) EM(0) EM(0) EM(0) EM(0) /* call $+5 */ \
EM(0xC7) EM(0x44) EM(0x24) EM(4) /* */ \
EM(_cs) EM(0) EM(0) EM(0) /* mov dword [rsp + 4], _cs */ \
EM(0x83) EM(4) EM(0x24) EM(0xD) /* add dword [rsp], 0xD */ \
EM(0xCB) /* retf */ \
}
#define X64_Start() X64_Start_with_CS(0x33)
#define X64_End() X64_End_with_CS(0x23)
#define __break() asm("int3")
int main(void)
{
__break();
X64_Start();
EM(0x48) EM(0x8D) EM(0x05) EM(0xF9) EM(0xFF) EM(0xFF) EM(0xFF) // lea rax, [$] ; rip-relative
X64_End();
__break();
}
然后,我在調試器下運行它,並注意到當擊中第二個斷點時,eax包含64位指令“ lea rax,[$]”的地址。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.