9.3 SSDT
本讲主要内容:
1.SSDT表。
2.KiSwapThread函数
3.SwapContext函数
----------------------------------------------
----------------------------------------------
1.SSDT表
1>int 0x2E进入0环后,在_KiSystemService函数中trap_frame框架形成之后,会把3环的参数拷贝到0环的栈,然后调用函数,用下列语句实现的:
rep movsd
call ebx
我们往上看代码拷贝时:esi来源于3环的edx,edi来源于SSDT表,ebx是函数的地址也来源于SSDT表。
2>怎么找到SSDT表
在IDA的函数列表中找到KiInitSystem函数,有下列语句
mov ds:_KeServiceDescriptorTable, offset _KiServiceTable
mov ds:dword_48B524, esi
mov ds:dword_48B52C, offset _KiArgumentTable
_KeServiceDescriptorTable是SSDT表,_KiServiceTable是函数表,_KiArgumentTable是参数表。
3>SSDT表的结构
typedef struct _KSERVICE_TABLE_DESCRIPTOR
{
PULONG_PTR Base; //函数列表
PULONG Count; //函数调用的次数
ULONG Limit; //函数列表中(Base指向的表)函数的个数
PUCHAR Number; //函数的参数列表
} KSERVICE_TABLE_DESCRIPTOR, *PKSERVICE_TABLE_DESCRIPTOR;
可以在WRK中输入KSERVICE_TABLE_DESCRIPTOR查看。
2.KiSwapThread函数
1>SSDT表中所有的函数都会调用KiSwapThread,可以通过IDA的交叉引用功能看出来。
2>调用了2个关键函数,KiFindReadyThread和KiSwapContext。
3>KiFindReadyThread得到将要切换线程的kThread的首地址,并传给KiSwapContext
4>KiSwapContext只有一个参数,就是将要切换的线程kThread的首地址,并把他传给SwapContext函数。
3.SwapContext函数
1>在KiSwapContext函数中有下列语句
mov ebx, large fs:_KPCR.SelfPcr ;
mov esi, ecx
mov edi, [ebx+_KPCR.PrcbData.CurrentThread] ;
mov [ebx+_KPCR.PrcbData.CurrentThread], esi ;
mov cl, [edi+58h] ; WaitIrql
call SwapContext
可以看出向SwapContext传入了3个参数,其中ESI存放的是目标线程的kThread首地址,EDI存放的是当前线程的kThread首地址。Cl存放的是WaitIrql,暂时不管。
2>SwapContext中进行了堆栈的切换,
切换语句是mov esp, [esi+28h],
在切之前保存了以前线程的esp,语句是mov [edi+28h], esp。
3>SwapContext函数不光是切换了堆栈还进行了其他操作,看SwapContext函数把读写了那些结构体的哪些成员记录下来。
<本节习题>
看SwapContext函数把读写了那些结构体的哪些成员记录下来。
<学习参考>
《Windows内核情景分析》(毛德操 著)的5.9节
浙公网安备 33010602011771号