2013-11-03 21 views
2

我嘗試寫一些程序直接調用系統調用,而無需通過ntdll.dll中去Windows 7中使用的x86 SYSENTER

我的代碼進行直接的系統調用(Visual Studio的語法...):

#include <windows.h> 

int main() 
{ 
    _asm{ 
     push arg1 
     push arg2 
     push arg3 
     mov eax,syscall_id 
     mov edx,esp 
     _emit 0xf 
     _emit 0x34 //sysenter opcodes... 
     } 

當程序試圖執行該指令SYSENTER導致程序崩潰與此訪問衝突:

CALL DWORD PTR DS:[EAX+EDX*4] // Access Violation when reading [00000128] 

EAX == 0x00000000 
EDX == 0x0000004D 

我試圖把一個硬件斷點使用內核調試程序中所需SYST EM調用和執行流程沒有達到那裏...

我想這個問題有事情做與堆疊順序/深度。

非常感謝!

解決:

我猜問題是,我試圖執行無負載USER32和GDI32 DLL的一個WIN32K系統調用。

只是說:

LoadLibraryW(L"user32.dll"); 
LoadLibraryW(L"gdi32.dll"); 

和問題解決了..

如果任何人有一個更好的主意,爲什麼出現這種情況,而無需加載這些dll,我會很高興地知道:)

+0

這可能是因爲你調用系統調用在GDI32.DLL實現,因爲它確實增加了一些內核級功能。 –

+0

你好John。上面的彙編代碼是否在彙編器下編譯?我似乎得到一個A2008語法錯誤。謝謝 – user1232138

回答

3

SYSENTER和SYSEXIT操作碼不像正常的調用/ ret操作碼那樣工作。

兩個SYSENTER和SYSEXIT [執行跳轉到預定的地址(一個在內核空間中,另一個在用戶空間)。

具體地說,SYSEXIT被設置爲跳轉到KiFastSystemCallRet在NTDLL。通常在ntdll中導出的系統過程調用KiFastSystemCall,而不是直接使用SYSENTER。讓我們來看看在KiFastSystemCall和KiFastSystemCallRet在NTDLL:

KiFastSystemCall:  mov edx, esp 
         sysenter 
KiFastSystemCallRet: retn 

您的代碼將導致系統程序從內核返回到RETN指令,這意味着回到你有什麼ARG3地址。我不知道爲什麼加載user32和gdi32會改變任何東西,也許它與arg3的值有關。

無論如何,呼籲自己的內核系統過程使用KiFastSystemCall最安全的方式。你也可以編寫自己的代碼,記住,從內核模式返回時,首先操作碼爲RETN軸承,所以您的代碼將需要在堆棧的頂部有回信地址。