1

ULONGLONG GetKeServiceDescriptorTable64() //我的方法
{
	PUCHAR StartSearchAddress = (PUCHAR)__readmsr(0xC0000082);
	PUCHAR EndSearchAddress = StartSearchAddress + 0x500;
	PUCHAR i = NULL;
	UCHAR b1 = 0, b2 = 0, b3 = 0;
	ULONG templong = 0;
	ULONGLONG addr = 0;
	for (i = StartSearchAddress;i < EndSearchAddress;i++)
	{
		if (MmIsAddressValid(i) && MmIsAddressValid(i + 1) && MmIsAddressValid(i + 2))
		{
			b1 = *i;
			b2 = *(i + 1);
			b3 = *(i + 2);
			if (b1 == 0x4c && b2 == 0x8d && b3 == 0x15) //4c8d15
			{
				KdBreakPoint();
				memcpy(&templong, i + 3, 4);
				addr = (ULONGLONG)templong + (ULONGLONG)i + 7;
				return addr;
			}
		}
	}
	return 0;
}

2

ULONGLONG SearchforKeServiceDescriptorTable64(ULONGLONG StartSearchAddress, ULONGLONG EndSearchAddress)
{
	UCHAR b1 = 0, b2 = 0, b3 = 0;
	ULONG templong = 0;
	PUCHAR i;
	ULONGLONG KeServiceDescriptorTable = 0;

	//地址效验
	if (MmIsAddressValid(StartSearchAddress) == FALSE)return NULL;
	if (MmIsAddressValid(EndSearchAddress) == FALSE)return NULL;

	for ( i = StartSearchAddress; i < EndSearchAddress; i++)
	{
		if (MmIsAddressValid(i) && MmIsAddressValid(i + 1) && MmIsAddressValid(i + 2))
		{
			b1 = *i;
			b2 = *(i + 1);
			b3 = *(i + 2);
			if (b1 == 0x4c && b2 == 0x8d && b3 == 0x15)  //4c8d15
			{
				memcpy(&templong, i + 3, 4);
				KeServiceDescriptorTable = (ULONGLONG)templong + (ULONGLONG)i + 7;
				return KeServiceDescriptorTable;
				//当前地址 + 长度 + 数值
				//fffff800`03c8c772+7 + 002320c7 = FFFFF80003EBE840
				/*
				fffff800`03c8c772 4c8d15c7202300  lea     r10,[nt!KeServiceDescriptorTable (fffff800`03ebe840)]
				fffff800`03c8c779 4c8d1d00212300  lea     r11,[nt!KeServiceDescriptorTableShadow (fffff800`03ebe880)]
				*/
			}
		}
	}
	return NULL;
}

//获取SSDT KeServiceDescriptorTable
ULONGLONG GetKeServiceDescriptorTable64_2()
{
	PUCHAR EndSearchAddress;
	ULONGLONG KeServiceDescriptorTable = 0;
	//msr[0xc0000082]变成了KiSystemCall64Shadow函数
	//原来我们64位搜索KeServiceDescriptorTable是通过msr的0xc0000082获得KiSystemCall64字段, 但是现在msr[0xc0000082]变成了KiSystemCall64Shadow函数, 而且这个函数无法直接搜索到KeServiceDescriptorTable。
	ULONGLONG KiSystemServiceUser = 0;
	ULONGLONG templong = 0xffffffffffffffff;
	PUCHAR i;
	PUCHAR pKiSystemCall64 = (PUCHAR)__readmsr(0xc0000082);  //rdmsr c0000082   //定位KiSystemCall64
    EndSearchAddress = pKiSystemCall64 + 0x500;
	

	KeServiceDescriptorTable = SearchforKeServiceDescriptorTable64(pKiSystemCall64, EndSearchAddress);
	if (KeServiceDescriptorTable)return  KeServiceDescriptorTable;

	
	for (i = pKiSystemCall64; i < EndSearchAddress + 0xff; i++)
	{
		if (*(PUCHAR)i == 0xe9 && *(PUCHAR)(i + 5) == 0xc3)
		{
			//fffff803`23733383 e9631ae9ff      jmp     nt!KiSystemServiceUser(fffff803`235c4deb)
			//fffff803`23733388 c3              ret
			RtlCopyMemory(&templong, (PUCHAR)(i + 1), 4);
			KiSystemServiceUser = templong + 5 + i;//KiSystemServiceUser
			EndSearchAddress = KiSystemServiceUser + 0x500;
			KeServiceDescriptorTable = SearchforKeServiceDescriptorTable64(KiSystemServiceUser, EndSearchAddress);
			return KeServiceDescriptorTable;
		}
	}
	return 0;
}