我試圖模擬Windows 7 X64(SP1)上的syscall指令是如何工作的,所以我使用MinGW64編寫了一個64位GCC示例。據我所知,對於Windows,所有系統調用入口點都在ntdll.dll或ntdll32.dll中(在這種情況下,我們只關心ntdll.dll)。如何在Windows 7 X64 SP1(x64模式)下執行直接系統調用?
Status = NtCreateFile(&FileHandle, // returned file handle
(GENERIC_WRITE | SYNCHRONIZE), // desired access
&ObjectAttributes, // ptr to object attributes
&Iosb, // ptr to I/O status block
0, // allocation size
FILE_ATTRIBUTE_NORMAL, // file attributes
0, // share access
FILE_SUPERSEDE, // create disposition
FILE_SYNCHRONOUS_IO_NONALERT, // create options
NULL, // ptr to extended attributes
0); // length of ea buffer
這是用C編寫的源代碼原件,然後我現在氣
asm volatile
(
"leaq %4, %%r9\n\t"
"leaq %3, %%r8\n\t"
"movq %2, %%rdx\n\t"
"leaq %1, %%rcx\n\t"
"movq %11,0x50(%%rsp)\n\t"
"movq %10,0x48(%%rsp)\n\t"
"movq %9, 0x40(%%rsp)\n\t"
"movq %8, 0x38(%%rsp)\n\t"
"movq %7, 0x30(%%rsp)\n\t"
"movq %6, 0x28(%%rsp)\n\t"
"movq %5, 0x20(%%rsp)\n\t"
"movq %%r9, 0x18(%%rsp)\n\t"
"movq %%r8, 0x10(%%rsp)\n\t"
"movq %%rdx, 0x8(%%rsp)\n\t"
"movq %%rcx, (%%rsp)\n\t"
"movq __imp_NtCreateFile(%%rip), %%rax\n\t"
"call *%%rax\n\t"
: "=a"(Status)
: "m"(FileHandle), "g"(GENERIC_WRITE | SYNCHRONIZE),"m"(ObjectAttributes),"m"(Iosb),"g"(0),"g"(FILE_ATTRIBUTE_NORMAL),"g"(0),"g"(FILE_SUPERSEDE),"g"(FILE_SYNCHRONOUS_IO_NONALERT),"g"(NULL),"g"(0)
: "%rcx", "%rdx", "%r8", "%r9", "%r10","%r11"
);
重寫它爲止,該計劃按預期工作:它創建一個文本文件,寫的東西文件。
我使用WinDbg來拆卸NTDLL!NtCreateFile和
"movq $0x52, %%rax\n\t"
"movq %%rcx, %%r10\n\t"
"syscall\n\t"
"ret\n\t"
我說我的計劃之內的這部分代碼爲
asm volatile
(
"leaq %4, %%r9\n\t"
"leaq %3, %%r8\n\t"
"movq %2, %%rdx\n\t"
"leaq %1, %%rcx\n\t"
"movq %11,0x50(%%rsp)\n\t"
"movq %10,0x48(%%rsp)\n\t"
"movq %9, 0x40(%%rsp)\n\t"
"movq %8, 0x38(%%rsp)\n\t"
"movq %7, 0x30(%%rsp)\n\t"
"movq %6, 0x28(%%rsp)\n\t"
"movq %5, 0x20(%%rsp)\n\t"
"movq %%r9, 0x18(%%rsp)\n\t"
"movq %%r8, 0x10(%%rsp)\n\t"
"movq %%rdx, 0x8(%%rsp)\n\t"
"movq %%rcx, (%%rsp)\n\t"
"movq $0x52, %%rax\n\t"
"movq %%rcx, %%r10\n\t"
"syscall\n\t"
: "=a"(Status)
: "m"(FileHandle), "g"(GENERIC_WRITE | SYNCHRONIZE),"m"(ObjectAttributes),"m"(Iosb),"g"(0),"g"(FILE_ATTRIBUTE_NORMAL),"g"(0),"g"(FILE_SUPERSEDE),"g"(FILE_SYNCHRONOUS_IO_NONALERT),"g"(NULL),"g"(0)
: "%rcx", "%rdx", "%r8", "%r9", "%r10","%r11"
);
只鋸(rewrited作爲氣體&牛逼格式)現在狀態總是返回值'0xc000000d',程序失敗。現在我有幾個困惑的問題:
這裏存儲在用戶模式堆棧中的參數如何進入內核模式?因爲我在NtDll!NtCreateFile中看不到任何東西。
如何將正確的返回值分配回%% rax?這部分也是在disassmebler內部的錯誤。
如何讓我的代碼在執行直接系統調用時能夠工作?
非常感謝您的大力幫助。
OK,在這裏展示工作代碼
asm volatile
(
"leaq %4, %%r9\n\t"
"leaq %3, %%r8\n\t"
"movq %2, %%rdx\n\t"
"leaq %1, %%rcx\n\t"
"movq %11,0x50(%%rsp)\n\t"
"movq %10,0x48(%%rsp)\n\t"
"movq %9, 0x40(%%rsp)\n\t"
"movq %8, 0x38(%%rsp)\n\t"
"movq %7, 0x30(%%rsp)\n\t"
"movq %6, 0x28(%%rsp)\n\t"
"movq %5, 0x20(%%rsp)\n\t"
"push $_end \n\t"
"movq %%rcx,%%r10\n\t"
"movq $0x52,%%rax\n\t"
"syscall\n\t"
"ret\n\t"
"_end:\n\t"
: "=a"(Status)
: "m"(FileHandle), "g"(GENERIC_WRITE | SYNCHRONIZE),"m"(ObjectAttributes),"m"(Iosb),"g"(0),"g"(FILE_ATTRIBUTE_NORMAL),"g"(0),"g"(FILE_SUPERSEDE),"g"(FILE_SYNCHRONOUS_IO_NONALERT),"g"(NULL),"g"(0)
: "%rcx", "%rdx", "%r8", "%r9", "%r10","%r11"
);
它是不是真的痛到模擬的呼叫/ RET。在這裏,我使用了Linus在他的Linux 0.11中使用過的解決方法。
你究竟在做什麼?你是否正在努力解決如何在asm中調用NtCreateFile?或者你是否試圖實現NtCreateFile? –
第二個,實現NtCreateFile進行實驗 –
在這種情況下,放棄嘗試用asm編寫調用。這是混淆的問題。用C編寫調用並將實現寫入asm。你爲什麼甚至試圖做到這一點。這似乎毫無意義,我希望它失敗。 –