Skip to content

gmh5225/Kernel_Anti-Cheat

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 

Repository files navigation

*Legal Disclaimer

The use of this project is the sole responsibility of the user. I am not responsible for any consequences arising from the use of this tool.

Features :

NMI StackWalking
Hypervisor Detection
Big Pool scanning
UUID
Scanning system threads
Checking PIDDBCacheTable for KDmapper & Drvmap

The NMI Stackwalking :

First we register an NMI callback that will be called when a hardware interupt occurs. inside the NMI callback you can see we capture the stack using RtlCaptureStackBackTrace and store the results in a list. code: BOOLEAN NmiCallback(PVOID context, BOOLEAN handled) { UNREFERENCED_PARAMETER(context); UNREFERENCED_PARAMETER(handled);

	PVOID* stackTrace = ExAllocatePoolWithTag(NonPagedPool, 0x1000, AC_POOL_TAG);
 
	if (!stackTrace)
		return TRUE;
 
	//Walk the stack and record information for each frame
	USHORT capturedFrames = RtlCaptureStackBackTrace(0, 0x1000 / 8, stackTrace, NULL);
 
	// Loop through g_PageOfpStackWalkResult list, 
	// if empty it has been checked by the DetectionThread,
	// and we can store the stackTrace and the capturedFrames in the list.
	for (int i = 0; i < 0x1000 / 0x10; i += 2)
	{
		if (((DWORD64*)g_PageOfpStackWalkResult)[i] == 0)
		{
			((DWORD64*)g_PageOfpStackWalkResult)[i] = (ULONG64)stackTrace;
			((DWORD64*)g_PageOfpStackWalkResult)[i + 1] = capturedFrames;
			break;
		}
	}
 
	return TRUE;
}

Then when we get the results inside our list we can iterate through it and check one of the frame values is not in a valid module. Code:

// Loop through the g_PageOfpStackWalkResult list
		for (INT i = 0; i < 0x1000 / 0x10; i += 2)
		{
			// Check if current item of g_PageOfpStackWalkResult is there
			if (((DWORD64*)g_PageOfpStackWalkResult)[i] == 0)
				continue;
 
			// Check if the stackTrace is valid and there are captured frames to loop through
			if (MmIsAddressValid(((PVOID*)g_PageOfpStackWalkResult)[i]) && ((DWORD64*)g_PageOfpStackWalkResult)[i + 1])
			{
				// Loop through the captured frames
				for (SIZE_T j = 0; i < ((DWORD64*)g_PageOfpStackWalkResult)[i + 1]; j++)
				{
					ULONG64 CurrentFrameValue = (((DWORD64**)g_PageOfpStackWalkResult)[i])[j];
 
					// Check if the CurrentFrameValue is an address in kernel 
					if (CurrentFrameValue < 0xFFFF000000000000)
						break;
 
					// Check if CurrentFrameValue is in a kernel module.
					// If not, we have found something.
					if (IsAdressOutsideModulelist(CurrentFrameValue))
						DbgPrintEx(0, 0, "Unsigned code : %llx", CurrentFrameValue);
				}
			}
 
			// Remove the stackTrace and the capturedFrames out of the list,
			// So the NMI callback can store new ones.
			ExFreePoolWithTag(((PVOID*)g_PageOfpStackWalkResult)[i], AC_POOL_TAG);
			((DWORD64*)g_PageOfpStackWalkResult)[i] = 0;
			((DWORD64*)g_PageOfpStackWalkResult)[i + 1] = 0;
		}

At last we can fire an NMI using HalSendNMI whenever we want to. Code:

BOOLEAN FireNMI(INT core, PKAFFINITY_EX affinity)
{
	KeInitializeAffinityEx(affinity);
	KeAddProcessorAffinityEx(affinity, core);
 
	HalSendNMI(affinity);
 
	return TRUE;
}
 
// Fire an NMI for eac core on the system with 100 ms delay
for (ULONG i = 0; i < KeQueryActiveProcessorCountEx(0); i++)
{
	FireNMI(i, g_NmiAffinity);
	DelayExecutionThread(100);
}
  • Improve the NMI callback
  • Improve the SystemThread scanning
  • Maybe add more features

About

Check detection vectors

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C 100.0%