win10 x64获取未导出内核函数地址

用Sunday算法进行特征码匹配

.h文件:

//系统信息类
typedef enum _SYSTEM_INFORMATION_CLASS {
	SystemBasicInformation = 0,						//系统的基本信息
	SystemProcessorInformation,             // obsolete...delete
	SystemPerformanceInformation,
	SystemTimeOfDayInformation,
	SystemPathInformation,
	SystemProcessInformation,						//系统进程信息
	SystemCallCountInformation,
	SystemDeviceInformation,
	SystemProcessorPerformanceInformation,
	SystemFlagsInformation,
	SystemCallTimeInformation,
	SystemModuleInformation,					//系统模块信息
	SystemLocksInformation,
	SystemStackTraceInformation,
	SystemPagedPoolInformation,
	SystemNonPagedPoolInformation,
	SystemHandleInformation,
	SystemObjectInformation,
	SystemPageFileInformation,
	SystemVdmInstemulInformation,
	SystemVdmBopInformation,
	SystemFileCacheInformation,
	SystemPoolTagInformation,
	SystemInterruptInformation,
	SystemDpcBehaviorInformation,
	SystemFullMemoryInformation,
	SystemLoadGdiDriverInformation,
	SystemUnloadGdiDriverInformation,
	SystemTimeAdjustmentInformation,
	SystemSummaryMemoryInformation,
	SystemMirrorMemoryInformation,
	SystemPerformanceTraceInformation,
	SystemObsolete0,
	SystemExceptionInformation,
	SystemCrashDumpStateInformation,
	SystemKernelDebuggerInformation,
	SystemContextSwitchInformation,
	SystemRegistryQuotaInformation,
	SystemExtendServiceTableInformation,
	SystemPrioritySeperation,
	SystemVerifierAddDriverInformation,
	SystemVerifierRemoveDriverInformation,
	SystemProcessorIdleInformation,
	SystemLegacyDriverInformation,
	SystemCurrentTimeZoneInformation,
	SystemLookasideInformation,
	SystemTimeSlipNotification,
	SystemSessionCreate,
	SystemSessionDetach,
	SystemSessionInformation,
	SystemRangeStartInformation,
	SystemVerifierInformation,
	SystemVerifierThunkExtend,
	SystemSessionProcessInformation,
	SystemLoadGdiDriverInSystemSpace,
	SystemNumaProcessorMap,
	SystemPrefetcherInformation,
	SystemExtendedProcessInformation,
	SystemRecommendedSharedDataAlignment,
	SystemComPlusPackage,
	SystemNumaAvailableMemory,
	SystemProcessorPowerInformation,
	SystemEmulationBasicInformation,
	SystemEmulationProcessorInformation,
	SystemExtendedHandleInformation,
	SystemLostDelayedWriteInformation,
	SystemBigPoolInformation,
	SystemSessionPoolTagInformation,
	SystemSessionMappedViewInformation,
	SystemHotpatchInformation,
	SystemObjectSecurityMode,
	SystemWatchdogTimerHandler,
	SystemWatchdogTimerInformation,
	SystemLogicalProcessorInformation,
	SystemWow64SharedInformation,
	SystemRegisterFirmwareTableInformationHandler,
	SystemFirmwareTableInformation,
	SystemModuleInformationEx,
	SystemVerifierTriageInformation,
	SystemSuperfetchInformation,
	SystemMemoryListInformation,
	SystemFileCacheInformationEx,
	MaxSystemInfoClass  // MaxSystemInfoClass should always be the last enum
} SYSTEM_INFORMATION_CLASS;
typedef struct _RTL_PROCESS_MODULE_INFORMATION {
	HANDLE Section;                 // Not filled in
	PVOID MappedBase;
	PVOID ImageBase;
	ULONG ImageSize;
	ULONG Flags;
	USHORT LoadOrderIndex;
	USHORT InitOrderIndex;
	USHORT LoadCount;
	USHORT OffsetToFileName;
	UCHAR  FullPathName[256];
} RTL_PROCESS_MODULE_INFORMATION, * PRTL_PROCESS_MODULE_INFORMATION;
typedef struct _RTL_PROCESS_MODULES {
	ULONG NumberOfModules;
	RTL_PROCESS_MODULE_INFORMATION Modules[1];
} RTL_PROCESS_MODULES, * PRTL_PROCESS_MODULES;
//检索系统信息
NTSYSAPI NTSTATUS NTAPI ZwQuerySystemInformation(
	__in		SYSTEM_INFORMATION_CLASS SystemInformationClass, 
	__inout		PVOID SystemInformation, 
	__in		ULONG SystemInformationLength,
	__out_opt	PULONG ReturnLength);

//获取Next数组
void GetNext(DWORD* next, DWORD* Tzm, DWORD TzmLength);
//通过名字获取模块基址及大小
//获取模块参考了  https://blog.csdn.net/qq125096885/article/details/52875797
VOID GetModuleBase(CHAR* ModuleName,PVOID *ModuleBase,PULONG ModuleSize);
//获取系统模块
UINT32 GetSystemModel(PRTL_PROCESS_MODULE_INFORMATION* pSystemModel);
//搜索内存
BOOLEAN SearchMemory(DWORD* Tzm, DWORD* next, DWORD TzmLength, PVOID StartAddress, ULONG size, PUINT64 resultAddr);
//通过特征码获取系统函数地址
UINT64 GetSystemFunByTzm(DWORD* Tzm, DWORD tzmLenth);

.c文件:

UINT32 GetSystemModel(PRTL_PROCESS_MODULE_INFORMATION *pSystemModel)
{
	//定义变量
	ULONG i = 0;
	RTL_PROCESS_MODULES* ProcessModules = NULL;
	ULONG ReturnLength = 0;
	ZwQuerySystemInformation(SystemModuleInformation, &ProcessModules, 4, &ReturnLength);
	if (ReturnLength)
	{
		ProcessModules = (PRTL_PROCESS_MODULES)ExAllocatePoolWithTag((POOL_TYPE)SystemModuleInformation, 2 * ReturnLength, ' kdD');
		if (ProcessModules)
		{
			if (NT_SUCCESS(ZwQuerySystemInformation(SystemModuleInformation, ProcessModules, 2 * ReturnLength, NULL)))
			{
				*pSystemModel = (PRTL_PROCESS_MODULE_INFORMATION)(ProcessModules->Modules);
				return ProcessModules->NumberOfModules;
			}
		}
	}

	return 0;
}


// 获取模块基址
VOID GetModuleBase(CHAR* ModuleName,PVOID* ModuleBase, PULONG ModuleSize)
{
	//参数效验
	if (ModuleName == NULL || ModuleBase==0 || ModuleSize==0)return;


	//定义变量
	ULONG i = 0;
	RTL_PROCESS_MODULES* ProcessModules = NULL;
	PVOID ImageBase = NULL;
	ULONG ReturnLength = 0;
	RTL_PROCESS_MODULE_INFORMATION* ModuleInformation = NULL;

	ZwQuerySystemInformation(SystemModuleInformation, &ProcessModules, 4, &ReturnLength);
	if (ReturnLength)
	{
		ProcessModules = (PRTL_PROCESS_MODULES)ExAllocatePoolWithTag((POOL_TYPE)SystemModuleInformation, 2 * ReturnLength, ' kdD');
		if (ProcessModules)
		{
			if (NT_SUCCESS(ZwQuerySystemInformation(SystemModuleInformation, ProcessModules, 2 * ReturnLength, NULL)))
			{
				ModuleInformation = (RTL_PROCESS_MODULE_INFORMATION*)(ProcessModules->Modules);
				for (i = 0; i < ProcessModules->NumberOfModules; i++)
				{
					//KdPrint(("%s\n", (CHAR*)&ModuleInformation[i].FullPathName[ModuleInformation[i].OffsetToFileName]));
					if (!_stricmp(ModuleName, (CHAR*)&ModuleInformation[i].FullPathName[ModuleInformation[i].OffsetToFileName]))
					{
						ImageBase = ModuleInformation[i].ImageBase;
						*ModuleBase = ImageBase;
						*ModuleSize = ModuleInformation[i].ImageSize;
						KdPrint(("找到的模块地址:%llx,大小:%llx\n", *ModuleBase, *ModuleSize));
						break;
					}
				}
			}
			ExFreePoolWithTag(ProcessModules, 0);
		}
	}
}


//获取Next数组
void GetNext(DWORD* next, DWORD* Tzm, DWORD TzmLength)
{
	//特征码(字节集)的每个字节的范围在0-255(0-FF)之间,256用来表示问号,到260是为了防止越界
	for (DWORD i = 0; i < 260; i++)
		next[i] = -1;
	for (DWORD i = 0; i < TzmLength; i++)
		next[Tzm[i]] = i;
}

//搜索一块内存
BOOLEAN SearchMemory(DWORD* Tzm, DWORD* next, DWORD TzmLength, PVOID StartAddress, ULONG size, PUINT64 resultAddr)
{
	DWORD i = 0, j, k,num;
	if (!MmIsAddressValid(StartAddress))
	{
		KdPrint(("非法地址:%llu",StartAddress));
		return FALSE;
	}

	while (i < (DWORD)size)
	{
		j = i; k = 0;
		
		for (; k < TzmLength && j < (DWORD)size && (Tzm[k] == ((PBYTE)StartAddress)[j] || Tzm[k] == 256); k++, j++);

		if (k == TzmLength)
		{
			*resultAddr = (UINT64)StartAddress + i;
			return TRUE;
		}

		if ((i + TzmLength) >= (DWORD)size)
		{
			return FALSE;
		}
		num = next[((BYTE*)StartAddress)[i + TzmLength]];
		if (num == -1)
			i += (TzmLength - next[256]);//如果特征码有问号,就从问号处开始匹配,如果没有就i+=-1
		else
			i += (TzmLength - num);
	}
	return FALSE;
}

UINT64 GetSystemFunByTzm(DWORD* Tzm,DWORD tzmLenth)
{
	PVOID modualAddr;
	UINT64 reAddr = 0;
	ULONG size;
	DWORD next[260] = { 0 };

	GetModuleBase("ntoskrnl.exe", &modualAddr, &size);
	GetNext(next, Tzm, tzmLenth);
	SearchMemory(Tzm, next, tzmLenth, modualAddr, size, &reAddr);
	
	return reAddr;
}

用法:

DWORD Tzm[] = { 0x48,0x8b,0x05,0x47,0x81,0xc7,0xff };
	
KdPrint(("结果地址:%llx\n", GetSystemFunByTzm(Tzm, 7)));
发布了23 篇原创文章 · 获赞 51 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_44286745/article/details/104942378