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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

2.API的调用过程(3环进0环)

發布時間:2025/3/20 编程问答 15 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2.API的调用过程(3环进0环) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
_KUSER_SHARED_DATA /*這是一個結構體,翻譯過來就是: Kernel與User分享的一塊數據。 0環與3環共享的一塊內存 */
  • 在User層和Kernel層分別定義了一個_KUSER_SHARED_DATA結構區域,用于User層和Kernel層共享某些數據
  • 它們使用固定的地址值映射,_KUSER_SHARED_DATA結構區域在User和 Kernel層地址分別為:
    User層地址為: 0x7ffe0000
    Kernnel層地址為: 0xffdf0000
  • 他們兩個線性地址對應的物理頁是一樣的,只不過映射了兩份

    特別說明:
    雖然指向的是同一個物理頁,但在User層是只讀的,在Kernnel層是可讀可寫的.



    我們來看看這個結構

    回顧之前的

    也就是說我們用了SystemCall的方式進入0環,下面我們來看看0x7FFE0300儲存的是什么

    當通過eax=1來執行cpuid指令時,處理器的特征信息被放在ecx和edx寄存器中, 其中edx包含了一個SEP位(11位) ,該位指明了當前CPU知否支持-sysenter/sysexit指令(快速調用)
    SEP位=1:支持快速調用
    SEP位=0:不支持快速調用
    支持:ntdll.dl!KiFastSystemCall()
    不支持:ntdll.dl!lkilntSystemCall()


    我的是支持的,當操作系統啟動的時候就會提供cpuid指令來查看你支不支持sysenter/sysexit指令,當你支持的時后它會把ntdll.dl!KiFastSystemCall()這個函數的地址寫到_KUSER_SHARED_DATA結構+300的處,如果不支持就寫ntdll.dl! lkilntSystemCal()

    進入0環需要修改的寄存器

  • CS的權限由3變為0意味著需要新的CS
  • SS與CS的權限永遠一致需要新的SS,
  • 權限發生切換的時候,堆棧也一定會切換,需要新的ESP
  • 進0環后代碼的位置,需要EIP
  • ntdll.dl!KiFastSystemCall()與ntall.dl!lkilntSystemCall()就是提供了兩種不同的找法

    API通過中斷門進0環

    當你的CPU不支持快速調用是用以下方法進入0環的

    eax里的值是內核操作碼,edx存的是參數的指針,api統一中斷號0x2e(idt 表2e位置)

    int 0x2e進ring0

  • 在IDT表中找到0x2E號門描述符
  • 分析CS/SS/ESP/EIP的來源
  • 分析EIP是什么

    0008 就是CS,高4字節+低4字節就是EIP:8053e481,ss與esp是從Tss(任務段)提供的

  • EIP:KiSystemService();,這個函數是內核模塊里的

  • 固定中斷號為0x2E
  • CS/EIP由門描述符提供ESP/SS由TSS提供
  • 進入0環后執行的內核函數: NT!KiSystemService
  • 通過iret/iretd指令返回到用戶模式 (從內核棧中pop eip,cs,eflags,esp,ss。然后將控制權交給eip所值的用戶代碼)



  • sysenter進0環


    eax是操作碼,edx是返回地址以及參數的指針

    為什么叫快速調用?
    中斷門進0環,需要的CS, EIP在IDT表中,需要查內存(SS與ESP由TSS提供)

    而CPU如果支持sysenter指令時,操作系統會提前將CS/SS/ESP/EIP的值存儲在 MSR寄存器中, sysenter指令執行時, CPU會將MSR寄存器中的值直接寫入相關,寄存器,沒有讀內存的討程,所以叫快速調用,本質是一樣的!

    在執行sysenter指令之前,操作系統必須指定0環的CS段、SS段、EIP以及ESP.

    MSR寄存器是非常大的,0x174位置存放新的CS,0x175存放新的ESP,0x176存放新的EIP。SS并沒有存放在MSR寄存器中,執行sysenter后cs+8就是ss了

    可以通過RDMSR/WRMST來進行讀寫(操作系統使用WRMST寫該寄存器) :

    windbg 查看這這幾個值

    rdmsr 174 //查看CSrdmsr 175 //查看ESPrdmsr 176 //查看EIP


    EIP:KiFastCallEntry();

    用戶代碼調用sysenter指令以前,必須將要返回的指令地址和棧指針值保存到edx和ecx寄存器中,否則,內核模式代碼將來無法設置正確的值,以使sysexit還能返回到用戶模式代碼原來的位置。

    API通過sysenter指令進0環:

  • CS/ESP/EIP由MSR寄存器提供(SS是算出來的)
  • 進入0環后執行的內核函數: NT!KiFastCallEntry
  • 通過sysexit指令返回用戶模式
  • sysexit:
    將IA_32_SYSENTER_CS+16裝載到CS寄存器;將edx寄存器中的指針裝載到eip寄存器中;(指定用戶模式代碼段)
    將IA_32_SYSENTER_CS+24裝載到SS寄存器;將ecx寄存器中的指針裝載到esp寄存器中;(指定用戶模式棧段)
    切換到特權級3,執行eip寄存器中指定的用戶代碼。

    C:\Windows\System32
    內核模塊: ntoskrnl.exe/ntkrnlpa.exe
    2-9-9-12分頁用:ntkrnlpa.exe
    10-10-12用:ntoskrnl.exe

    總結

    以上是生活随笔為你收集整理的2.API的调用过程(3环进0环)的全部內容,希望文章能夠幫你解決所遇到的問題。

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