VOID temp(ULONG_PTR Addr1, ULONG_PTR Addr2)
{
ULONG_PTR Index = 0;
DbgPrint("Addr1: %I64X Addr2: %I64X\r\n", Addr1, Addr2);
for (Index = 0; Index < 50; ++Index)
{
UHALF_PTR Value1 = *(PUHALF_PTR)(Addr1 + Index * sizeof(UHALF_PTR));
UHALF_PTR Value2 = *(PUHALF_PTR)(Addr2 + Index * sizeof(UHALF_PTR));
UHALF_PTR Delta = Value2 - Value1;
HALF_PTR OrgVal = Value2 - Delta;
HALF_PTR t = OrgVal >> 4;
DbgPrint("Delta: %I64X Value2: %X Value1: %X Original: %X Func: %I64X\r\n", \
Delta, Value2, Value1, Value2 - Delta, Addr1 + t);
}
}
// 此函数为入口函数
NTSTATUS _utl_KeEnumerateSSDT()
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
PKEMODULE_CONTEXT ModuleContext = _utl_KeModuleAllocateContext();
if (ModuleContext)
{
// 遍历内核模块列表
status = _utl_KeEnumerateKernalModules(ModuleContext);
if (NT_SUCCESS(status))
{
PVOID NewNtoskrnlBase = NULL;
UNICODE_STRING NtoskrnlName = RTL_CONSTANT_STRING(L"\\??\\C:\\Windows\\System32\\ntoskrnl.exe");
// Node中存放的是当前内核的各个模块, 第一个是ntoskrnl
PKE_MODULE_LIST Node = CONTAINING_RECORD(ModuleContext->KeModuleList._next.Flink, KE_MODULE_LIST, _next);
// 重载ntoskrnl内核
status = _petl_LdrReloadPE(&NtoskrnlName, ModuleContext, &NewNtoskrnlBase);
if (NT_SUCCESS(status))
{
ULONG_PTR OriginalSSDTBase = NULL, NewSSDTBase = NULL;
// _utl_KeFixServiceDescriptorTable主要是实现nt!KeCompactServiceTable的逻辑
// _utl_KeFixServiceDescriptorTable返回当前内核的SSDT表各项的起始地址
OriginalSSDTBase = _utl_KeFixServiceDescriptorTable(Node->ModuleBase, NewNtoskrnlBase);
// 计算重载后内核的SSDT表的起始地址: 重载后内核基址 + (原版内核SSDT地址 - 原版内核基址)
NewSSDTBase = (ULONG_PTR)NewNtoskrnlBase + OriginalSSDTBase - Node->ModuleBase;
// 打印新老表的信息
temp(OriginalSSDTBase, NewSSDTBase);
__debugbreak();
_petl_LdrFree(NewNtoskrnlBase);
}
}
_utl_KeModuleCleanUp(ModuleContext);
}
return status;
}