ntoseye

Windows kernel debugger for Linux hosts running Windows under KVM/QEMU. Essentially, WinDbg for Linux.
Features
- Command line interface
- WinDbg style commands
- Kernel debugging
- PDB fetching & parsing for offsets
- Breakpointing (kernel, usermode)
- Two debug backends: QEMU's
gdbstub(default) and Windows KD over a serial pipe (KDCOM, see Choosing a backend)
Supported Windows
ntoseye currently only supports Windows 10 and 11 guests.
Disclaimer
ntoseye needs to download symbols to initialize required offsets, it will only download symbols from Microsoft's official symbol server. All files which will be read/written to will be located in $XDG_CONFIG_HOME/ntoseye.
Preview

Getting started
Install via cargo
Building
Usage
It is recommended that you run the following command before running ntoseye or a VM:
|
Note that you may need to run ntoseye with sudo aswell (last resort, try command above first).
To view command line arguments, run ntoseye --help. The debugger is self documented, so pressing tab will display completions and descriptions for commands, symbols, and types.
For examples, refer here.
Choosing a backend
ntoseye can talk to the guest two ways. Pick with --backend gdb (default) or --backend kd.
gdb (default) |
kd |
|
|---|---|---|
| Transport | QEMU's gdbstub |
Windows KD over a serial pipe (KDCOM) |
| Requires in-guest configuration | No (guest is unaware it's being debugged) | Yes (bcdedit /debug on; anti-debug code, PatchGuard, and some Windows behaviour change once enabled) |
| Supports usermode breakpoints | No | Yes |
| Native breakpoints | gdb Z0 packets |
DbgKdWriteBreakPointApi |
See VM configuration for the host-side setup of each backend.
VM configuration
It is recommended to disable memory paging and memory compression within the guest operating system to avoid memory-related issues. This only needs to be done once per Windows installation. Run the following commands in PowerShell (Run as Administrator):
Get-CimInstance Win32_ComputerSystem | Set-CimInstance -Property @{ AutomaticManagedPagefile = $false }
Get-CimInstance Win32_PageFileSetting | Remove-CimInstance
Disable-MMAgent -MemoryCompression
Restart-Computer
GDBSTUB
Default backend. Expose QEMU's gdbstub on 127.0.0.1:1234 by passing -s -S.
QEMU
Append -s -S to the qemu command.
virt-manager
Add the following to the XML configuration:
...
KDCOM
Run with --backend kd. In the guest, enable kernel debugging (run as Administrator, then reboot):
bcdedit /debug on
bcdedit /dbgsettings serial debugport:1 baudrate:115200
Use debugport:2 instead of :1 if the KD chardev ends up as COM2 (see the virt-manager subsection below).
QEMU
Add a Unix-socket chardev and route a serial port to it:
-chardev socket,id=kd,path=/tmp/ntoseye-kd.sock,server=on,wait=off -serial chardev:kd
Then connect: ntoseye --backend kd.
virt-manager
[!WARNING] virt-manager auto-adds a
<serial>console device on every VM, which claims COM1. Either replace that device with one pointing at the KD socket (KD becomes COM1, usedebugport:1), or leave it and add the KD chardev viaqemu:commandline(KD becomes COM2, usedebugport:2).
Option A (recommended): replace the auto-added serial. KD is COM1, debugport:1 is correct.
Option B: keep the auto-added serial and append the KD chardev via qemu:commandline. KD is COM2, use debugport:2.
...
Credits
Functionality regarding initialization of guest information was written with the help of the following sources:
Usage examples
Privilege escalation
- Run
ps <filter>to get theEPROCESSaddress of the process you wish to escalate - Run
eq (_EPROCESS)(AddressOfEPROCESS)->Token *(_EPROCESS)*PsInitialSystemProcess->TokenwhereAddressOfEPROCESSis the address from step 1