typedef struct _SERVICE_DESCIPTOR_TABLE
{
PULONG ServiceTableBase;
/
/
SSDT基址,
8
字节大小
PVOID ServiceCounterTableBase;
/
/
SSDT中服务被调用次数计数器,
8
字节大小
ULONGLONG NumberOfService;
/
/
SSDT服务函数的个数,
8
字节大小
PVOID ParamTableBase;
/
/
系统服务参数表基址,
8
字节大小。实际指向的数组是以字节为单位的记录着对应服务函数的参数个数
}SSDTEntry,
*
PSSDTEntry;
NTSTATUS Unload(PDRIVER_OBJECT pDriverObj)
{
return
STATUS_SUCCESS;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pReg)
{
pDriverObj
-
>DriverUnload
=
Unload;
/
/
测试系统:WIN10_22H2_X64
/
/
还未测试过其它版本的偏移是否一样
/
*
*
获取SSDT表
*
ZwSetEvent()
+
0x19
-
> KiServiceInternal()
+
5A
-
> KiSystemServiceStart()
+
0x14
-
> KeServiceDescriptorTable
*
系统调用对应的内核函数地址
=
SSDT基地址
+
((
*
(ULONG
*
)(SSDT基地址
+
调用号
*
4
)) >>
4
)
*
/
/
/
PUCHAR pKiSystemCall64_func
=
(PUCHAR)__readmsr(
0xc0000082
);
/
/
获取指令
PVOID KiServiceInternal_temp
=
NULL;
PVOID KiSystemServiceStart_temp
=
NULL;
PVOID KeServiceDescriptorTable
=
NULL;
UCHAR jmp_KiServiceInternal[
5
]
=
{
0
};
UCHAR lea_KiSystemServiceStart[
7
]
=
{
0
};
UCHAR lea_KeServiceDescriptorTable[
7
]
=
{
0
};
/
/
获取跳转到KiServiceInternal的指令
for
(size_t i
=
0
; i < sizeof(jmp_KiServiceInternal); i
+
+
)
jmp_KiServiceInternal[i]
=
*
(PUCHAR)((PUCHAR)ZwSetEvent
+
0x19
+
i);
/
/
计算KiServiceInternal函数地址 (指令RIP
+
跳转偏移(例:E9后面的
4
个字节XXXXXXXX))
+
指令长度
=
跳转的内存地址
KiServiceInternal_temp
=
(PVOID)((((PUCHAR)ZwSetEvent
+
0x19
)
+
*
(ULONG
*
)(jmp_KiServiceInternal
+
0x1
))
+
sizeof(jmp_KiServiceInternal));
/
/
获取跳转到KiSystemServiceStart的指令
for
(size_t i
=
0
; i < sizeof(lea_KiSystemServiceStart); i
+
+
)
lea_KiSystemServiceStart[i]
=
*
(PUCHAR)((PUCHAR)KiServiceInternal_temp
+
0x5A
+
i);
/
/
计算KiSystemServiceStart函数地址 (指令RIP
+
跳转偏移(例:E9后面的
4
个字节XXXXXXXX))
+
指令长度
=
跳转的内存地址
KiSystemServiceStart_temp
=
(PVOID)((((PUCHAR)KiServiceInternal_temp
+
0x5A
)
+
*
(ULONG
*
)(lea_KiSystemServiceStart
+
0x3
))
+
sizeof(lea_KiSystemServiceStart));
/
/
获取KeServiceDescriptorTable的指令
for
(size_t i
=
0
; i < sizeof(lea_KeServiceDescriptorTable); i
+
+
)
lea_KeServiceDescriptorTable[i]
=
*
(PUCHAR)((PUCHAR)KiSystemServiceStart_temp
+
0x14
+
i);
/
/
计算KeServiceDescriptorTable地址 (指令RIP
+
跳转偏移(例:E9后面的
4
个字节XXXXXXXX))
+
指令长度
=
跳转的内存地址
KeServiceDescriptorTable
=
(PVOID)((((PUCHAR)KiSystemServiceStart_temp
+
0x14
)
+
*
(ULONG
*
)(lea_KeServiceDescriptorTable
+
0x3
))
+
sizeof(lea_KeServiceDescriptorTable));
PSSDTEntry pSSDT
=
KeServiceDescriptorTable;
return
STATUS_SUCCESS;
}