[原创]发个xp~win10_x86/x64全兼容的ShadowSSDT获取函数
获取SSDT部分是来自于titanhide的代码,我只是加了由SSDT搜索ShadowSSDT的方法,请各位大神批评指正!
PKSERVICE_TABLE_DESCRIPTOR FindKeServiceDescriptorTableShadow()
{
static PKSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTableShadow = NULL;
PKSERVICE_TABLE_DESCRIPTOR SSDT = 0;
if (!KeServiceDescriptorTableShadow)
{
UNICODE_STRING routineName;
#ifndef _WIN64
//x86 code
RtlInitUnicodeString(&routineName, L"KeServiceDescriptorTable");
SSDT = (PKSERVICE_TABLE_DESCRIPTOR)MmGetSystemRoutineAddress(&routineName);
#else
//x64 code
RtlInitUnicodeString(&routineName, L"KeAddSystemServiceTable");
PVOID KeASST = MmGetSystemRoutineAddress(&routineName);
if (!KeASST)
{
Log("[TITANHIDE] Failed to find KeAddSystemServiceTable!\n");
return 0;
}
unsigned char function[1024];
unsigned int function_size = 0;
RtlCopyMemory(function, KeASST, sizeof(function));
for (unsigned int i = 0; i < sizeof(function); i++)
{
if (function[i] == 0xC3) //ret
{
function_size = i + 1;
break;
}
}
if (!function_size)
{
Log("[TITANHIDE] Failed to get function size of KeAddSystemServiceTable!\n");
return 0;
}
/*
000000014050EA4A 48 C1 E0 05 shl rax, 5
000000014050EA4E 48 83 BC 18 80 3A 36 00 00 cmp qword ptr [rax+rbx+363A80h], 0 <- we are looking for this instruction
000000014050EA57 0F 85 B2 5C 0A 00 jnz loc_1405B470F
000000014050EA5D 48 8D 8B C0 3A 36 00 lea rcx, rva KeServiceDescriptorTableShadow[rbx]
000000014050EA64 48 03 C8 add rcx, rax
000000014050EA67 48 83 39 00 cmp qword ptr [rcx], 0
*/
int rvaSSDT = 0;
for (unsigned int i = 0; i < function_size; i++)
{
if (((*(unsigned int*)(function + i)) & 0x00FFFFF0) == 0xBC8340 &&
!*(unsigned char*)(function + i + 8)) //4?83bc?? ???????? 00 cmp qword ptr [r?+r?+????????h],0
{
rvaSSDT = *(int*)(function + i + 4);
break;
}
}
if (rvaSSDT) //this method worked
{
Log("[TITANHIDE] SSDT RVA: 0x%X\n", rvaSSDT);
PVOID base = GetKernelBase();
if (!base)
{
Log("[TITANHIDE] GetKernelBase() failed!\n");
return 0;
}
Log("[TITANHIDE] GetKernelBase()->0x%p\n", base);
SSDT = (PKSERVICE_TABLE_DESCRIPTOR)((unsigned char*)base + rvaSSDT);
}
else
{
/*
Windows 10 Technical Preview:
fffff800e21b30ec 757f jne nt!KeAddSystemServiceTable+0x91 (fffff800e21b316d)
fffff800e21b30ee 48833deafee4ff00 cmp qword ptr [nt!KeServiceDescriptorTable+0x20 (fffff800e2002fe0)],0 <- we are looking for this instruction
fffff800e21b30f6 7575 jne nt!KeAddSystemServiceTable+0x91 (fffff800e21b316d)
fffff800e21b30f8 48833da0fee4ff00 cmp qword ptr [nt!KeServiceDescriptorTableShadow+0x20 (fffff800e2002fa0)],0
fffff800e21b3100 756b jne nt!KeAddSystemServiceTable+0x91 (fffff800e21b316d)
*/
int rvaFound = -1;
for (unsigned int i = 0; i < function_size; i++)
{
if (((*(unsigned int*)(function + i)) & 0x00FFFFFF) == 0x3D8348 &&
!*(unsigned char*)(function + i + 7)) //48833d ???????? 00 cmp qword ptr [X],0
{
rvaFound = i;
rvaSSDT = *(int*)(function + i + 3);
break;
}
}
if (rvaFound == -1)
{
Log("[TITANHIDE] Failed to find pattern...\n");
return 0;
}
//Sanity check SSDT & contents
__try
{
SSDT = (PKSERVICE_TABLE_DESCRIPTOR)((ULONG_PTR)KeASST + rvaFound + rvaSSDT + 8 - 0x20);
ULONG_PTR check = (ULONG_PTR)KeASST & 0xFFFFFFFF00000000;
if (((ULONG_PTR)SSDT & 0xFFFFFFFF00000000) != check ||
((ULONG_PTR)SSDT->Base & 0xFFFFFFFF00000000) != check ||
(SSDT->Limit & 0xFFFFFFFFFFFF0000) != 0 ||
((ULONG_PTR)SSDT->Number & 0xFFFFFFFF00000000) != check)
{
Log("[TITANHIDE] Found SSDT didn't pass all checks...\n");
return 0;
}
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
Log("[TITANHIDE] An exception was thrown while accessing the SSDT...\n");
return 0;
}
}
#endif
// search shadowSSDT from the address of ssdt
if (SSDT)
{
unsigned char* startAddr = (unsigned char*)SSDT + sizeof(KSERVICE_TABLE_DESCRIPTOR);
__try
{
for (int i = 0; i < 0x100; ++i)
{
if (memcmp(startAddr + i, SSDT, sizeof(KSERVICE_TABLE_DESCRIPTOR)) == 0)
{
KeServiceDescriptorTableShadow = (PKSERVICE_TABLE_DESCRIPTOR)(startAddr + i);
break;
}
}
}
__except (EXCEPTION_EXECUTE_HANDLER) { }
}
}
return KeServiceDescriptorTableShadow;
}
