涉及到系统调用,_KTRAP_frame,_KPCR,_KPRCB,_KTHREAD结构体..
KiFastSystemCall(R3) -> KiFastCallEntry(R0)
设置环境
寻找内核函数地址,拷贝参数
此时需要了解一个结构SystemServiceTable
结构如下:
定位SystemServiceTable
_KTHREAD -> ServiceTable
系统服务表有两张:
1.ntoskrnl.exe导出的常用系统服务.
2.Win32k.sys导出的与图形显示和用户界面相关的系统服务(只有GDI相关线程访问对应系统服务表才会有值).
系统服务表结构如下:
typedef struct _KSERVICE_TABLE_DEscriptOR
{
KSYSTEM_SERVICE_TABLE ntoskrnl; // 内核函数
KSYSTEM_SERVICE_TABLE win32k; // win32k.sys 函数
KSYSTEM_SERVICE_TABLE unUsed1; // 未使用
KSYSTEM_SERVICE_TABLE unUsed2; // 未使用
} KSERVICE_TABLE_DEscriptOR, * PKSERVICE_TABLE_DEscriptOR;
typedef struct _KSYSTEM_SERVICE_TABLE
{
PULONG ServiceTablebase; // 函数地址表基址
PULONG ServiceCounterTablebase;// 函数被调用的次数
ULONG NumberOfService; // 函数个数
PULONG ParamTablebase; // 函数参数表基址
} KSYSTEM_SERVICE_TABLE, * PKSYSTEM_SERVICE_TABLE;
ServiceTable指向函数地址表每个成员大小为4字节,存储函数地址.
ServiceLimit存储函数地址表的成员个数.
ArgumentTable 函数参数表每个成员大小为1字节,存储函数参数个数(存储值 / 4 = 参数个数).
在快速调用和中断调用R3函数执行时,EAX存储了系统服务号.
通过第12位确定是哪张表.
通过低12位确定在函数地址表中的索引值以及函数参数表的索引值.
System Services Descriptor Table系统服务描述符表,为导出结构KeServiceDescriptorTable(代码中只需声明即可直接使用).
查找ReadProcessMemory(测试环境系统服务号为115h)对应内核函数地址以及参数
Windbg查看SSDT
dd KeServiceDescriptorTable
继续函数分析
至此完成了初始化内核环境以及参数拷贝,函数调用.



