How to setup Windows Kernel Debugging between two VMs on a Linux host using VMWare.
If for one reason or another, like me, you prefer to have a Linux host and couldn’t be bothered to dual boot every time you want to debug a Windows VM and, every now and then, you prefer to debug VM to VM using VMware as your hypervisor, then this is just the post for you.
There are a couple of other write ups on the same out there, this is just my approach on the same.
Requirements:
- A Linux host of your choice — I’m using Ubuntu 20.04.3 LTS.
- Hypervisor — I’m using VMware Workstation 16.2.1 build-18811642.
- Two Windows 10 VMs — I’m using Windows 10 Pro 64-bit (10.0, Build 19043) (19041.vb_release.191206–1406).
- WinDbg preview — Yes, you can install this from the Microsoft Store without having signed in just click “No, thanks” when they ask you to sign in.
Assuming you have the two VMs running already at this point, make sure you take a snapshot of them before we make any changes, in case anything goes wrong.
Setting up Windbg.
On the debugging machine:
- Download WinDbg Preview from the Microsoft Store.
Add symbols to your Windbg.
Go to File -> Settings -> Debugging settings and set it up like so:
This basically tells WinDbg where to look for symbols.
Symbols are pdbs (program databases) that resolve function names. We’ve set up a local ‘repository’ of symbols where WinDbg will save downloaded symbols (c:\Symbols) and a remote URL where WinDbg will look for symbols whenever it encounters functions whose symbols are not already stored locally.
A note about symbols: Windows does not provide symbols for all its APIs (you might have heard of ‘undocumented APIs’? ) so you’ll have to either Reverse Engineer the functions yourself or look for their documentation in unofficial places such as ntinternals for NTAPI undocumented functions or the vergilius project for kernel APIs — but that’s beyond the scope of this post.
Setting up a Communication Channel between our VMs — KDNET Network Kernel Debugging.
We need a channel through which our debugging VM can communicate with the debugee VM. In this case, we’re going to use networking as our communication medium because it’s the fastest method.
On the debugging VM:
- Add a new ‘host-only’ network adapter that we’ll use solely for debugging purposes.
VM -> Settings -> Add -> Network Adapter -> Finish
- Then on that new network adapter, change it to Host-only. A new Network adapter should show up under Network adapters on your VM.
Start -> Search Device Manager
- Double-click on the Network adapter with a trailing ‘#2’. This is what we’ll use as our channel.
- We are looking for it’s bus parameters in the location field which we’ll interpret as 27:0:0 with the format
<BusNumber>:<DeviceNumber>:<FunctionNumber>
File -> Attach to kernel
- Fill in a port you expect connections from as well as a key you will set for the connection to be established (we’ll set the same key on the debugee shortly) then press OK.
- At this point our debugger is waiting for a connection..
On the Debugee:
Create a channel just like you did with the debugger:
- Add a new ‘host-only’ network adapter.
VM -> Settings -> Add -> Network Adapter -> Finish
- Change it to Host-only.
- Confirm that it’s on the same location as the debugging machine by checking the network adapters under Device Manager.
2. Open cmd as admin. We’ll use bcdedit to edit its boot configuration so that we can be able to boot into debug mode.
- Enabling debug mode:
bcdedit /debug on
- Setting up network properties:
bcdedit /dbgsettings net hostip:172.16.22.132 port:50005 key:Back.To.The.Basics
where hostip — debugger ip (hostonly interface ip)
- Setting up the bus parameters:
bcdedit /set {dbgsettings} busparams 27.0.0
- Restart the VM.
That’s it!
At this point you should see some activity on WinDbg
Links & Resources: