日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

浅谈系统服务分发

發布時間:2025/6/15 windows 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 浅谈系统服务分发 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

    歡迎轉載,轉載請注明出處:http://www.cnblogs.com/uAreKongqi/p/6597701.html

0x00.說在前面

  就我們所知,Windows操作系統內核的陷阱處理器會分發中斷、異常和系統服務調用,這里我們就其中的系統服務分發簡單解析一下。

?

0x01.粗看不同處理器進入系統調用

  (1).在PentiumII 之前的x86處理器上,Windows使用int2e指令產生一個陷阱,導致執行線程轉到內核模式,進入系統服務分發器,eax保存系統服務號,edx指向參數列表。最后通過iret指令返回用戶模式;

     ??我們查看IDT的2e成員,得知該成員保存的地址是系統調用分發器的地址,緊接著u一下KiSystemService,會發現在保存完寄存器等狀態之后,他走到了KiFastCallEntry里面!(在Win7 x86下測試)

      

  (2).在x86Pentium II 處理器上,Windows使用了sysenter指令,內核的系統服務分發器例程的地址保存在與該指令相關聯的一個MSR中,eax,edx保存與int2e相同的內容。最后通過sysexit指令返回用戶模式;

     這里讀取MSR的0x176處,其中包含了系統服務分發器地址,發現實際上調用的就是KiFastCallEntry(入口)!(在Win7 x86下測試)

      

  (3).在x64體系架構上,Windows使用syscall指令,將系統調用號保存在eax中,前四個參數放在寄存器(rcx/rdx/r8/r9)中,剩下的參數在棧中。

    64位平臺讀取MSR的0xC0000082處,里面保存的是64位的syscall,當我們u一下這個地址,發現這個就是x64系統調用分發的入口KiSystemCall64(在Win7 x64下測試)

     ?

    Ps:通過KiSystemCall64的地址可以通過硬編碼得到SSDT、SSSDT地址

?......

?

?  我們發現,32位下,系統調用分發操作都會走到KiFastCallEntry里面,而64位下,系統調用分發操作會走到KiSystemCall64,然后去完成相應的系統服務調用。那么我們有個疑問,系統是怎么進入到這些系統調用的呢?

?

0x02.舉例查看系統調用如何發生

  這里以Win7 x86 平臺下的 NtOpenProcess為例,切換到一個進程內(如explorer.exe),u一下NtOpenProcess,這里顯示的是ntdll里的NtOpenProcess的反匯編:

  

  我們有兩個收獲,一個是看到了系統服務號放在了eax里了,另一個是它呼叫了一個地址,call指令將執行由內核建立起來的系統服務分發代碼,該地址保存在ntdll!_KUSER_SHARED_DATA+0x300處,我們接著進這個地址看看:

  

  我們似乎有了點兒眉目了,系統調用在ntdll里面發生了,也就是說,在ntdll里面完成了從ring3到ring0的切換,其中eax保存服務號,edx保存參數列表首地址,通過服務號可以在SSDT中定位目標服務例程

  32位下的KeServiceDescriptorTable每個成員就是目標系統服務的絕對地址,64位下的目標系統服務真實地址是KeServiceDescriptorTable每個成員保存的偏移量(右移4位后的)+KeServiceDescriptorTable基地址;

  一開始線程的系統服務表地址指向Ntoskrnl.exe中的SSDT表,但當調用了一個USER或GDI服務時,服務表地址被修改成指向win32k.sys中的系統服務表。 

?

0x03.從用戶層到內核層完整的調用過程

  (1). 當一個Windows應用程序調用Kernel32.dll中的OpenProcess時,其導入并調用了API-MS-Win-Core-File-L1-1-0.dll(一個MinWin重定向Dll)中的NtOpenProcess函數;

  (2). 接著上述的NtOpenProcess函數又會調用KernelBase.dll中的OpenProcess函數,這里是函數的真正實現,它會對子系統相關的參數做了檢查;

  (3). 然后KernelBase!OpenProcess就會調用ntdll.dll中的NtOpenProcess函數,在這兒就會觸發系統調用(ntdll!KiFastSystemCall),傳遞NtOpenProcess的系統服務號和參數列表;

  (4). 系統服務分發器(Ntoskrnl.exe中的KiSystemService函數)就會調用真正的NtOpenProcess函數來處理該I/O請求。

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

0x04.內核模式下的系統分發

  在系統調用中,如果原先模式為用戶模式,在給系統服務傳遞的參數指向了用戶空間緩沖區時,內核模式代碼在操作該緩沖區前會檢查是否可以訪問該緩沖區,而原先模式就是內核模式的時候,默認參數有效,則不會對參數進行檢查。而既然已經在內核模式了,那就不需要int2e中斷或者sysenter之類的操作了,但如果直接像調用API一般直接調用NtOpenProcess之類的系統服務函數時,內核保存的原先模式值仍然是用戶模式(進內核之前當然是用戶模式咯~),但又檢測到傳遞來的地址是一個內核模式地址(因為在當前內核模式下調用),于是會導致調用失敗(STATUS_ACCESS_VIOLATION)。

  這里要介紹內核的Zw系列函數了,他們不僅是Nt版本函數的別名或包裝,而是對應Nt系列系統調用的翻版,使用了同樣的系統調用分發機制。他們會建立一個假的中斷棧(CPU在中斷后生成的棧),并直接調用KiSystemService例程,這個過程就在模擬CPU中斷,仿佛調用來自用戶模式一般,而在檢測到該調用的實際特權級后將原先模式修改為內核模式,這樣也省去了參數校驗,成功調用到NtOpenProcess!

  

?

?0x05.簡單小結

?  Ring3 ---> Ring0 的系統調用: Kernel32.dll(API)--->ntdll.dll(Nt/Zw)--->用戶模式轉內核模式--->Ntoskrnl.exe(Nt)--->完成I/O請求(原路返回)

   Ring0 ---> Ring0 的系統調用:Ntoskrnl.exe(Zw)--->Ntoskrnl.exe(Nt)

?  以上理解參考自《深入解析Windows操作系統6》第三章,如果有不正確的地方還請指出,我將虛心請教!

轉載于:https://www.cnblogs.com/uAreKongqi/p/6597701.html

總結

以上是生活随笔為你收集整理的浅谈系统服务分发的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。