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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > windows >内容正文

windows

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

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

Windows系統(tǒng)調(diào)用學(xué)習(xí)筆記(四)—— 系統(tǒng)服務(wù)表&SSDT

    • 要點(diǎn)回顧
    • 系統(tǒng)服務(wù)表
      • 實(shí)驗(yàn):分析 KiSystemService 與 KiFastCallEntry 共同代碼
    • SSDT
      • 實(shí)驗(yàn):在SSDT中查找內(nèi)核函數(shù)信息
        • 第一步:查看函數(shù)地址
        • 第二步:查看參數(shù)個(gè)數(shù)
        • 第三步:查看內(nèi)核函數(shù)反匯編
    • 練習(xí)

要點(diǎn)回顧

API進(jìn)入0環(huán)后調(diào)用的函數(shù):

  • 中斷門(mén) – KiSystemService
  • 快速調(diào)用 – KiFastCallEntry
  • 上一篇留了幾個(gè)練習(xí):

  • 進(jìn)0環(huán)后,原來(lái)的寄存器存在哪里?
  • 如何根據(jù)系統(tǒng)服務(wù)號(hào)(eax中存儲(chǔ))找到要執(zhí)行的內(nèi)核函數(shù)?
  • 調(diào)用時(shí)參數(shù)是存儲(chǔ)到3環(huán)的堆棧,如何傳遞給內(nèi)核函數(shù)?
  • 兩種調(diào)用方式是如何返回到3環(huán)的?
  • 本篇將對(duì)第二個(gè)和第三個(gè)練習(xí)進(jìn)行說(shuō)明

    系統(tǒng)服務(wù)表

    描述

  • 系統(tǒng)服務(wù)表:System Service Table
  • 系統(tǒng)服務(wù)表共有兩張,第一張表后緊接第二張表
  • 系統(tǒng)服務(wù)表里的函數(shù)都是來(lái)自內(nèi)核文件導(dǎo)出的函數(shù)
  • 它并不包含內(nèi)核文件導(dǎo)出的所有函數(shù),而是3環(huán)最常用的內(nèi)核函數(shù)
  • 系統(tǒng)服務(wù)表位于 _KTHREAD +00xE0
  • 結(jié)構(gòu)體

    typedef struct _SERVICE_DESCRIPTOR_TABLE {PULONG ServiceTableBase; // 指針,指向函數(shù)地址,每個(gè)成員占4字節(jié)PULONG ServiceCounterTableBase; // 當(dāng)前系統(tǒng)服務(wù)表被調(diào)用的次數(shù)ULONG NumberOfService; // 服務(wù)函數(shù)的總數(shù)PUCHAR ParamTableBase; // 服務(wù)函數(shù)的參數(shù)總長(zhǎng)度,以字節(jié)為單位,每個(gè)成員占一個(gè)字節(jié)// 如:服務(wù)函數(shù)有兩個(gè)參數(shù),每個(gè)參數(shù)占四字節(jié),那么對(duì)應(yīng)參數(shù)總長(zhǎng)度為8// 函數(shù)地址成員 與 參數(shù)總長(zhǎng)度成員 一一對(duì)應(yīng) } SSDTEntry, *PSSDTEntry;

    結(jié)構(gòu)圖

    實(shí)驗(yàn):分析 KiSystemService 與 KiFastCallEntry 共同代碼

    IDA反匯編

    .text:00406932 loc_406932: ; CODE XREF: _KiBBTUnexpectedRange+18↑j .text:00406932 ; _KiSystemService+71↑j .text:00406932 mov edi, eax ; 從 eax 寄存器中取出3環(huán)傳進(jìn)來(lái)的系統(tǒng)調(diào)用號(hào) .text:00406934 shr edi, 8 ; 系統(tǒng)調(diào)用號(hào)右移8位 .text:00406937 and edi, 30h ; 右移后的值和0x30進(jìn)行與運(yùn)算; 目的是檢測(cè)第12位是否為1; WindowsNT基本的(Native)系統(tǒng)調(diào)用有兩百多個(gè),編號(hào)都小于0x1000; 編號(hào)大于0x1000的系統(tǒng)調(diào)用號(hào)是微軟擴(kuò)展出來(lái)的; 這些擴(kuò)展出的系統(tǒng)調(diào)用位于動(dòng)態(tài)安裝的模塊中,即win32k.sys; 若第12位為0x00,則將低12位作為下標(biāo)在 ntoskrl.exe 中尋找對(duì)應(yīng)的系統(tǒng)調(diào)用; 若第12位為0x10,則將低12位作為下標(biāo)在 win32k.sys 中尋找對(duì)應(yīng)的系統(tǒng)調(diào)用 .text:0040693A mov ecx, edi ; 將運(yùn)算結(jié)果賦值給 ecx .text:0040693C add edi, [esi+0E0h] ; 將系統(tǒng)服務(wù)表的指針賦值給 edi; nt!_KTHREAD; +0x0e0 ServiceTable : Ptr32 Void; 這里將系統(tǒng)服務(wù)表所在地址直接加上edi的運(yùn)算結(jié)果; 巧妙地得到要查哪張表(兩張表是連續(xù)的),每張表占16字節(jié) .text:00406942 mov ebx, eax ; 將系統(tǒng)調(diào)用號(hào)賦值給 ebx .text:00406944 and eax, 0FFFh ; 將系統(tǒng)調(diào)用號(hào)與 0xFFF進(jìn)行與運(yùn)算; 目的是保留低12位,作為函數(shù)地址的下標(biāo) .text:00406949 cmp eax, [edi+8] ; typedef struct _SYSTEM_SERVICE_TABLE; {; PVOID ServiceTableBase; //這個(gè)指向系統(tǒng)服務(wù)函數(shù)地址表; PULONG ServiceCounterTableBase;; ULONG NumberOfService; //服務(wù)函數(shù)總數(shù); ULONG ParamTableBase; //參數(shù)總長(zhǎng)度; }SYSTEM_SERVICE_TABLE,*PSYSTEM_SERVICE_TABLE;;; +8 是服務(wù)函數(shù)的個(gè)數(shù) .text:0040694C jnb _KiBBTUnexpectedRange ; 若大于系統(tǒng)調(diào)用號(hào)的個(gè)數(shù)則跳轉(zhuǎn),即系統(tǒng)調(diào)用號(hào)越界 .text:00406952 cmp ecx, 10h ; 將 ecx 與0x10進(jìn)行比較; ecx 保存的是 edi 與0x30與運(yùn)算后的結(jié)果,只能是0x00貨0x10 .text:00406955 jnz short loc_406972 ; 若系統(tǒng)調(diào)用號(hào)小于0x1000,則跳轉(zhuǎn) .text:00406957 mov ecx, large fs:18h ; 只有當(dāng)ecx == 0x10才會(huì)向下執(zhí)行; 作用是動(dòng)態(tài)加載GUI等圖形相關(guān)函數(shù) .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環(huán)參數(shù)的指針 .text:0040697B mov ebx, [edi+0Ch] ; edi指向要使用的系統(tǒng)服務(wù)表; +0Ch是ParamTableBase(參數(shù)表指針) .text:0040697E xor ecx, ecx ;ecx清零 .text:00406980 mov cl, [eax+ebx] ; eax保存的是3環(huán)傳入的系統(tǒng)調(diào)用號(hào); ebx保存的是是參數(shù)表指針; 這條指令的目的是得到內(nèi)核函數(shù)的參數(shù)總長(zhǎng)度,存入cl .text:00406983 mov edi, [edi] ; 取出系統(tǒng)調(diào)用表的第一個(gè)成員(函數(shù)地址指針) .text:00406985 mov ebx, [edi+eax*4] ; 函數(shù)地址指針 + 系統(tǒng)調(diào)用號(hào)*4(乘4是因?yàn)槊總€(gè)成員占4字節(jié)); 目的是找到函數(shù)地址,存入ebx .text:00406988 sub esp, ecx ; 提升堆棧,大小為參數(shù)總長(zhǎng)度 .text:0040698A shr ecx, 2 ; 參數(shù)總長(zhǎng)度/4 = 參數(shù)個(gè)數(shù) .text:0040698D mov edi, esp ; 設(shè)置要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 ; 全局變量存儲(chǔ)用戶(hù)能訪問(wèn)的最大范圍; 這條指令的作用是判斷3環(huán)參數(shù)是否越界 .text:004069A1 jnb loc_406B4F ; 越界則跳轉(zhuǎn)至異常處理 .text:004069A7 .text:004069A7 loc_4069A7: .text:004069A7 rep movsd ; 將3環(huán)參數(shù)復(fù)制到0環(huán)堆棧 .text:004069A9 call ebx ; 調(diào)用函數(shù)

    SSDT

    描述

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

    kd>dd KeServiceDescriptorTable


    在WinDbg中查看未導(dǎo)出成員:

    實(shí)驗(yàn):在SSDT中查找內(nèi)核函數(shù)信息

    實(shí)驗(yàn)說(shuō)明

  • 在之前的實(shí)驗(yàn)中,我們通過(guò)分析三環(huán)的ReadProcessMemory函數(shù),一步步了解三環(huán)函數(shù)是如何進(jìn)入內(nèi)核的
  • 當(dāng)ReadProcessMemory即將進(jìn)入內(nèi)核時(shí),傳遞了一個(gè)系統(tǒng)服務(wù)號(hào),為0BAh
  • 本次實(shí)驗(yàn)查找編號(hào) 0BAh 在 SSDT 表中的相關(guān)信息
  • 第一步:查看函數(shù)地址

    函數(shù)地址表

    [函數(shù)地址表 + 系統(tǒng)服務(wù)號(hào)*4] = 內(nèi)核函數(shù)地址

    第二步:查看參數(shù)個(gè)數(shù)

    參數(shù)表

    [參數(shù)表 + 系統(tǒng)服務(wù)號(hào)] = 內(nèi)核函數(shù)參數(shù)個(gè)數(shù)(單位:字節(jié))

    第三步:查看內(nèi)核函數(shù)反匯編

    練習(xí)

    要求:在SSDT表中追加一個(gè)函數(shù)地址(NtReadVirtualMemory),自己編寫(xiě)API的3環(huán)部分調(diào)用這個(gè)新增的函數(shù)(注意:使用2-9-9-12分頁(yè))。

    答案:略(待補(bǔ)充)

    總結(jié)

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

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。