NMICallbackBlocker2

October 17, 2024 ยท View on GitHub

This is a POC Test project for INTEL CPUs on blocking NMI Entries through the IDT Handler.

typedef struct _KNMI_HANDLER_CALLBACK
{
	struct _KNMI_HANDLER_CALLBACK* Next;
	void(*Callback)();
	void* Context;
	void* Handle;
} KNMI_HANDLER_CALLBACK, * PKNMI_HANDLER_CALLBACK;

typedef struct _KAFFINITY_EX
{
	USHORT Count;                                                           //0x0
	USHORT Size;                                                            //0x2
	ULONG Reserved;                                                         //0x4
	ULONGLONG Bitmap[20];                                                   //0x8
} KAFFINITY_EX, * PKAFFINITY_EX;

void PreventNMIExecution() {
	void* ntoskrnl_base = reinterpret_cast<void*>((uintptr_t)get_ntos_base_address());
	if (ntoskrnl_base == NULL) {
		DbgPrint("[NMI] Failed to get ntoskrnl_base");
	}

	// Perform the pattern scanning to locate nmi_in_progress
	char* pattern = _("\xE8\x00\x00\x00\x00\x83\xCB\xFF\x48\x8B\xD6");
	char* mask = _("x????xxxxxx");

	char* NtoskrnlStr = _("ntoskrnl.exe");

	void* ModuleSig = static_cast<void*>(FindPatternImage((PCHAR)GetKernelModuleBase(NtoskrnlStr), pattern, mask));
	QWORD pattern_idt = reinterpret_cast<QWORD>(ModuleSig);
	// DbgPrint("[NMI] ModuleSig = %p\n", ModuleSig);
	// DbgPrint("[NMI] patternIDT = %p\n", pattern_idt);

	if (pattern_idt != NULL)
	{
		pattern_idt = PswResolveRelativeAddress(pattern_idt, 1, 5);
		pattern_idt = pattern_idt + 0x1a;
		pattern_idt = PswResolveRelativeAddress(pattern_idt, 3, 7);

		*(QWORD*)(pattern_idt + 0x38) = *(QWORD*)(pattern_idt + 0x1A0);
		*(QWORD*)(pattern_idt + 0x40) = *(QWORD*)(pattern_idt + 0x1A8);
		// DbgPrint(_("[NMI] IDT Patched / NMIs Blocked"));
	}
}