The NMI Blocker intercepts Non-Maskable Interrupts (NMI) by patching IDT on every active processor.
Our IDT patch reads the current processor, checks the allocated array of allowed processors, and let's it continue or blocks it with a IRETQ instruction.
The IDT patch blocks NMIs via a IRETQ instruction, any driver that acquires a lock or handle inside its NMI handler and waits for the NMI to release it could deadlock.
A Non-Maskable Interrupt (NMI) is a hardware interrupt that cannot be disabled by software using CLI or STI.
The Windows kernel uses NMIs for:
- Watchdog timers - Detecting hung processors
- Anti-cheat / Patch-Guard - Stack walking and thread observation on all processors
- Hypervisor communication - Inter-processor signaling in virtualized environments
The NMI Blocker hooks the IDT entry on every active processor, replacing it with a stub allocated in ntoskrnl.
The stub intercepts every NMI before PoIdle processes it, PoIdle is the default NMI handler on idle processors.
Commonly Anti-cheat software ( EasyAntiCheat, e.g.. ) bypasses PoIdle by registering callbacks directly to KiNmiCallbackHeadList.
NMI fires
└── stub executes
├── RDMSR 0xC0000103 → get processor index
├── load &disabled_processors → load the allocated array of processors
├── MOVZX [disabled_processors + processor_index] → check if the processor is disabled
├── TEST eax, eax
│ ├── ZF=0 (disabled) → IRETQ → block the NMI
│ └── ZF=1 (enabled) → JMP original_handler → send to the original handler
Below are the best case scenarios to apply selective NMI blocking:
- Kernel Debugging — Block NMIs on specific processors while debugging kernel architecture.
- Driver Development — See how your driver reacts to an emulated environment without NMIs.
- NMI Research — Study the Windows NMI dispatch flow by observing which callbacks in KiNmiCallbackHeadList fire.
The NMI Blocker provides a lightweight mechanism for per-processor NMI blocking by patching the IDT directly.
The stub is allocated inside ntoskrnl and intercepts NMIs before PoIdle or any KiNmiCallbackHeadList callback can process them.
Be aware that blocking NMIs on a processor that holds a lock inside its NMI handler will deadlock that processor indefinitely.
If you find errors or have improvements, create a issue or contact me on Discord (see profile).