欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

[原创]发个xp~win10_x86/x64全兼容的ShadowSSDT获取函数

[原创]发个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;
}

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功