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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

Windows系统调用学习笔记(二)—— 3环进0环

發布時間:2025/3/21 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Windows系统调用学习笔记(二)—— 3环进0环 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Windows系統調用學習筆記(二)—— 3環進0環

    • 要點回顧
    • 基本概念
      • _KUSER_SHARED_DATA
      • 0x7FFE0300
        • 實驗:判斷CPU是否支持快速調用
          • 第一步:修改EAX=1
          • 第二步:將當前匯編指令修改為cpuid
          • 第三步:清空ECX與EDX
          • 第四步:執行cpuid,觀察結果
          • 第五步:觀察EDX的SEP位(第11位)
    • 3環進0環
      • 基本步驟
      • 中斷門進0環
        • 分析 KiIntSystemCall
        • 分析 INT 0x2E
          • 第一步:在IDT表中找到0x2E號門描述符
          • 第二步:分析CS/SS/ESP/EIP的來源
          • 第三步:查看門描述符指向的EIP
      • 快速調用進0環
        • 分析 KiFastSystemCall
        • 分析 sysenter指令
          • MSR寄存器
    • 總結
      • API通過中斷門進0環
      • API通過sysenter指令進0環
      • 內核模塊
    • 練習

要點回顧

上一篇我們分析了ReadProcessMemory這個函數的3環部分

  • ReadProcessMemory函數存在于kernel32.dll
  • 它并沒有做什么,只是調用了另一個函數(NtReadVirtualMemory),然后設置了一些返回值
  • NtReadVirtualMemory函數來自ntdll.dll
  • NtReadVirtualMemory也沒做什么,只是提供了一個編號(0BAh)和一個函數地址(7FFE0300h),然后進行了內核調用
  • 本篇將弄清這個 函數地址(7FFE0300h) 是什么

    基本概念

    _KUSER_SHARED_DATA

  • 在 User 層和 Kernel 層分別定義了一個 _KUSER_SHARED_DATA 結構區域,用于 User 層和 Kernel 層共享某些數據
  • 它們使用固定的地址值映射,_KUSER_SHARED_DATA結構區域在User層Kernel層地址分別為:
    User:0x7ffe0000
    Kernnel:0xffdf0000

    注意:雖然指向的是同一個物理頁,但在User層是只讀的,在Kernnel層是可寫
  • 0x7FFE0300

    描述
    當通過eax=1來執行cpuid指令時,處理器的特征信息被放在ecxedx寄存器中,其中edx包含了一個SEP位(11位),該位指明了當前處理器知否支持sysenter/sysexit指令

    • 支持
      ntdll.dll! KiFastSystemCall()
    • 不支持
      ntdll.dll! KiIntSystemCall()

    實驗:判斷CPU是否支持快速調用

    第一步:修改EAX=1

    第二步:將當前匯編指令修改為cpuid

    第三步:清空ECX與EDX

    第四步:執行cpuid,觀察結果

    第五步:觀察EDX的SEP位(第11位)

    0xBFF = 二進制:1011 1111 1111

    SEP=1,說明當前CPU支持 sysenter / sysexit 指令

    3環進0環

    基本步驟

  • CS的權限由3變為0,意味著需要新的CS
  • SS與CS的權限永遠一致,需要新的SS
  • 權限發生切換的時候,堆棧也一定會切換,需要新的ESP
  • 進0環后會修改EIP
  • 中斷門進0環

    分析 KiIntSystemCall


    該函數函數只執行了兩行代碼

    分析

  • 第一行將參數的地址放入EDX
  • 第二行調用了0x2e中斷(所有的API進內核時,統一的中斷號為0x2e)
  • 注意:在執行KiIntSystemCall函數前,編號已被寫入EAX

    分析 INT 0x2E

    第一步:在IDT表中找到0x2E號門描述符


    門描述符:804dee00`0008e7d1
    指向地址:804de7d1

    第二步:分析CS/SS/ESP/EIP的來源

    CS:門描述符的段選擇子部分(0008)
    SS:從段選擇子指向的TSS段描述符指向的TSS表中取出
    ESP:從段選擇子指向的TSS段描述符指向的TSS表中取出
    EIP:804de7d1

    第三步:查看門描述符指向的EIP


    nt表示當前函數為內核函數

    快速調用進0環

    快速調用

  • 中斷門進0環,需要的CSEIP在IDT表中,需要查內存(SS與ESP由TSS提供)
  • CPU如果支持sysenter指令,操作系統會提前將CS/SS/ESP/EIP的值存儲在MSR寄存器中,sysenter指令執行時,CPU會將MSR寄存器中的值直接寫入相關寄存器,沒有讀內存的過程,所以叫快速調用,它們的本質是一樣的
  • 分析 KiFastSystemCall


    該函數函數只執行了兩行代碼

    分析

  • 第一行將當前棧頂(esp)的值放入edx
  • 第二行執行了sysenter指令
  • 注意:在執行KiIntSystemCall函數前,編號已被寫入EAX

    分析 sysenter指令

    注意

  • 在執行sysenter指令之前,操作系統必須指定0環的CS段、SS段、EIP以及ESP
  • 其中,CS段、EIP以及ESP來自MSR寄存器
  • MSR寄存器

    描述:MSR寄存器非常龐大,這里只列出三個值,詳細信息參照Intel白皮書

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

  • kd> rdmsr 174 //查看CS
  • kd> rdmsr 175 //查看ESP
  • kd> rdmsr 176 //查看EIP

    查看EIP所在地址的反匯編

    nt表示當前函數為內核函數
  • 注意
    4. 在執行sysenter指令時,只有CSESP、EIP三個寄存器的值可從MSR寄存器中獲得,其中并不包括SS!
    5. SS= IA32_SYSENTER_CS + 8
    6. 這些操作與操作系統無關,而是硬件(CPU)做的(詳情參考Intel白皮書第二卷)

    總結

    API通過中斷門進0環

  • 固定中斷號為0x2E
  • CS/EIP由門描述符提供,ESP/SS由TSS提供
  • 進入0環后執行的內核函數:NT!KiSystemService
  • API通過sysenter指令進0環

  • CS/ESP/EIP由MSR寄存器提供(SS是算出來的)
  • 進入0環后執行的內核函數:NT!KiFastCallEntry
  • 內核模塊

    10-10-12分頁:ntoskrnl.exe
    2-9-9-12分頁:ntkrnlpa.exe

    練習

    要求:通過IDA找到KiSystemServiceKiFastCallEntry函數并分析

    問題:

  • 進0環后,原來的寄存器存在哪里?
  • 如何根據系統調用號(eax中存儲)找到要執行的內核函數?
  • 調用時參數是存儲到3環的堆棧,如何傳遞給內核函數?
  • 2種調用方式是如何返回到3環的?
  • 答案:見下篇

    總結

    以上是生活随笔為你收集整理的Windows系统调用学习笔记(二)—— 3环进0环的全部內容,希望文章能夠幫你解決所遇到的問題。

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