Windows系统调用学习笔记(四)—— 系统服务表SSDT
生活随笔
收集整理的這篇文章主要介紹了
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ù):
上一篇留了幾個(gè)練習(xí):
本篇將對(duì)第二個(gè)和第三個(gè)練習(xí)進(jìn)行說(shuō)明
系統(tǒng)服務(wù)表
描述:
結(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
描述:
在WinDbg中查看已導(dǎo)出成員:
kd>dd KeServiceDescriptorTable
在WinDbg中查看未導(dǎo)出成員:
實(shí)驗(yàn):在SSDT中查找內(nèi)核函數(shù)信息
實(shí)驗(yàn)說(shuō)明
第一步:查看函數(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)題。
- 上一篇: Windows系统调用学习笔记(三)——
- 下一篇: Windows进程与线程学习笔记(一)—