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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

Windows系统调用学习笔记(四)—— 系统服务表SSDT

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

Windows系統調用學習筆記(四)—— 系統服務表&SSDT

    • 要點回顧
    • 系統服務表
      • 實驗:分析 KiSystemService 與 KiFastCallEntry 共同代碼
    • SSDT
      • 實驗:在SSDT中查找內核函數信息
        • 第一步:查看函數地址
        • 第二步:查看參數個數
        • 第三步:查看內核函數反匯編
    • 練習

要點回顧

API進入0環后調用的函數:

  • 中斷門 – KiSystemService
  • 快速調用 – KiFastCallEntry
  • 上一篇留了幾個練習:

  • 進0環后,原來的寄存器存在哪里?
  • 如何根據系統服務號(eax中存儲)找到要執行的內核函數?
  • 調用時參數是存儲到3環的堆棧,如何傳遞給內核函數?
  • 兩種調用方式是如何返回到3環的?
  • 本篇將對第二個和第三個練習進行說明

    系統服務表

    描述

  • 系統服務表:System Service Table
  • 系統服務表共有兩張,第一張表后緊接第二張表
  • 系統服務表里的函數都是來自內核文件導出的函數
  • 它并不包含內核文件導出的所有函數,而是3環最常用的內核函數
  • 系統服務表位于 _KTHREAD +00xE0
  • 結構體

    typedef struct _SERVICE_DESCRIPTOR_TABLE {PULONG ServiceTableBase; // 指針,指向函數地址,每個成員占4字節PULONG ServiceCounterTableBase; // 當前系統服務表被調用的次數ULONG NumberOfService; // 服務函數的總數PUCHAR ParamTableBase; // 服務函數的參數總長度,以字節為單位,每個成員占一個字節// 如:服務函數有兩個參數,每個參數占四字節,那么對應參數總長度為8// 函數地址成員 與 參數總長度成員 一一對應 } SSDTEntry, *PSSDTEntry;

    結構圖

    實驗:分析 KiSystemService 與 KiFastCallEntry 共同代碼

    IDA反匯編

    .text:00406932 loc_406932: ; CODE XREF: _KiBBTUnexpectedRange+18↑j .text:00406932 ; _KiSystemService+71↑j .text:00406932 mov edi, eax ; 從 eax 寄存器中取出3環傳進來的系統調用號 .text:00406934 shr edi, 8 ; 系統調用號右移8位 .text:00406937 and edi, 30h ; 右移后的值和0x30進行與運算; 目的是檢測第12位是否為1; WindowsNT基本的(Native)系統調用有兩百多個,編號都小于0x1000; 編號大于0x1000的系統調用號是微軟擴展出來的; 這些擴展出的系統調用位于動態安裝的模塊中,即win32k.sys; 若第12位為0x00,則將低12位作為下標在 ntoskrl.exe 中尋找對應的系統調用; 若第12位為0x10,則將低12位作為下標在 win32k.sys 中尋找對應的系統調用 .text:0040693A mov ecx, edi ; 將運算結果賦值給 ecx .text:0040693C add edi, [esi+0E0h] ; 將系統服務表的指針賦值給 edi; nt!_KTHREAD; +0x0e0 ServiceTable : Ptr32 Void; 這里將系統服務表所在地址直接加上edi的運算結果; 巧妙地得到要查哪張表(兩張表是連續的),每張表占16字節 .text:00406942 mov ebx, eax ; 將系統調用號賦值給 ebx .text:00406944 and eax, 0FFFh ; 將系統調用號與 0xFFF進行與運算; 目的是保留低12位,作為函數地址的下標 .text:00406949 cmp eax, [edi+8] ; typedef struct _SYSTEM_SERVICE_TABLE; {; PVOID ServiceTableBase; //這個指向系統服務函數地址表; PULONG ServiceCounterTableBase;; ULONG NumberOfService; //服務函數總數; ULONG ParamTableBase; //參數總長度; }SYSTEM_SERVICE_TABLE,*PSYSTEM_SERVICE_TABLE;;; +8 是服務函數的個數 .text:0040694C jnb _KiBBTUnexpectedRange ; 若大于系統調用號的個數則跳轉,即系統調用號越界 .text:00406952 cmp ecx, 10h ; 將 ecx 與0x10進行比較; ecx 保存的是 edi 與0x30與運算后的結果,只能是0x00貨0x10 .text:00406955 jnz short loc_406972 ; 若系統調用號小于0x1000,則跳轉 .text:00406957 mov ecx, large fs:18h ; 只有當ecx == 0x10才會向下執行; 作用是動態加載GUI等圖形相關函數 .text:0040695E xor ebx, ebx .text:00406960 .text:00406960 loc_406960: .text:00406960 or ebx, [ecx+0F70h] .text:00406966 jz short loc_406972 .text:00406968 push edx .text:00406969 push eax .text:0040696A call ds:_KeGdiFlushUserBatch .text:00406970 pop eax .text:00406971 pop edx .text:00406972 .text:00406972 loc_406972: ; CODE XREF: _KiFastCallEntry+B6↑j .text:00406972 ; KiSystemServiceAccessTeb()+6↑j .text:00406972 inc large dword ptr fs:638h ; _KPRCB -> +0x518 KeSystemCalls 增加1 .text:00406979 mov esi, edx ; edx保存的是3環參數的指針 .text:0040697B mov ebx, [edi+0Ch] ; edi指向要使用的系統服務表; +0Ch是ParamTableBase(參數表指針) .text:0040697E xor ecx, ecx ;ecx清零 .text:00406980 mov cl, [eax+ebx] ; eax保存的是3環傳入的系統調用號; ebx保存的是是參數表指針; 這條指令的目的是得到內核函數的參數總長度,存入cl .text:00406983 mov edi, [edi] ; 取出系統調用表的第一個成員(函數地址指針) .text:00406985 mov ebx, [edi+eax*4] ; 函數地址指針 + 系統調用號*4(乘4是因為每個成員占4字節); 目的是找到函數地址,存入ebx .text:00406988 sub esp, ecx ; 提升堆棧,大小為參數總長度 .text:0040698A shr ecx, 2 ; 參數總長度/4 = 參數個數 .text:0040698D mov edi, esp ; 設置要COPY的目的地 .text:0040698F test byte ptr [ebp+72h], 2 .text:00406993 jnz short loc_40699B .text:00406995 test byte ptr [ebp+6Ch], 1 .text:00406999 jz loc_4069A7 .text:0040699B .text:0040699B loc_40699B: ; CODE XREF: KiSystemServiceAccessTeb()+33↑j .text:0040699B cmp esi, ds:_MmUserProbeAddress ; 全局變量存儲用戶能訪問的最大范圍; 這條指令的作用是判斷3環參數是否越界 .text:004069A1 jnb loc_406B4F ; 越界則跳轉至異常處理 .text:004069A7 .text:004069A7 loc_4069A7: .text:004069A7 rep movsd ; 將3環參數復制到0環堆棧 .text:004069A9 call ebx ; 調用函數

    SSDT

    描述

  • 全稱:System Services Descriptor Table(系統服務描述符表)
  • SSDT的每個成員叫做系統服務表
  • SSDT的第一個成員是導出的,聲明一下即可使用
  • SSDT的第二個成員是未導出的,需要通過其它方式查找
  • 在Windows中,SSDT的第三個成員和第四個成員未被使用
  • 在WinDbg中查看已導出成員:

    kd>dd KeServiceDescriptorTable


    在WinDbg中查看未導出成員:

    實驗:在SSDT中查找內核函數信息

    實驗說明

  • 在之前的實驗中,我們通過分析三環的ReadProcessMemory函數,一步步了解三環函數是如何進入內核的
  • ReadProcessMemory即將進入內核時,傳遞了一個系統服務號,為0BAh
  • 本次實驗查找編號 0BAh 在 SSDT 表中的相關信息
  • 第一步:查看函數地址

    函數地址表

    [函數地址表 + 系統服務號*4] = 內核函數地址

    第二步:查看參數個數

    參數表

    [參數表 + 系統服務號] = 內核函數參數個數(單位:字節)

    第三步:查看內核函數反匯編

    練習

    要求:在SSDT表中追加一個函數地址(NtReadVirtualMemory),自己編寫API的3環部分調用這個新增的函數(注意:使用2-9-9-12分頁)。

    答案:略(待補充)

    總結

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

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