mirror of
https://github.com/QubesOS/qubes-doc.git
synced 2025-01-13 08:19:43 -05:00
9da0acc630
Signed-off-by: Rafał Wojdyła <omeg@invisiblethingslab.com>
90 lines
4.9 KiB
Markdown
90 lines
4.9 KiB
Markdown
---
|
|
lang: en
|
|
layout: doc
|
|
permalink: /doc/windows-debugging/
|
|
redirect_from:
|
|
- /en/doc/windows-debugging/
|
|
- /doc/WindowsDebugging/
|
|
- /wiki/WindowsDebugging/
|
|
ref: 50
|
|
title: Windows debugging
|
|
---
|
|
|
|
Debugging Windows code can be tricky in a virtualized environment. The guide below assumes Qubes 4.2 and Windows 7 or later VMs.
|
|
|
|
User-mode debugging is usually straightforward if it can be done on one machine. Just duplicate your normal debugging environment in the VM.
|
|
|
|
Things get complicated if you need to perform kernel debugging or troubleshoot problems that only manifest on system boot, user logoff or similar. For that you need two Windows VMs: the *host* and the *target*. The *host* will contain the debugger, your source code and private symbols. The *target* will run the code being debugged. We will use kernel debugging over network which is supported from Windows 7 onwards. The main caveat is that Windows kernel supports only specific network adapters for this, and the default one in Qubes won't work.
|
|
|
|
## Important note
|
|
|
|
- Do not install Xen network PV drivers in the target VM. Network kernel debugging needs a specific type of NIC or it won't work, the network PV drivers interfere with that.
|
|
|
|
- If you have kernel debugging active when the Xen PV drivers are being installed, make sure to disable it before rebooting (`bcdedit /set debug off`). You can re-enable debugging after the reboot. The OS won't boot otherwise. I'm not sure what's the exact cause. I know that busparams for the debugging NIC change when PV drivers are installed (see later), but even changing that accordingly in the debug settings doesn't help -- so it's best to disable debug for this one reboot.
|
|
|
|
## Modifying the NIC of the target VM
|
|
|
|
You will need to create a custom libvirt config for the target VM. See [the documentation](https://dev.qubes-os.org/projects/core-admin/en/latest/libvirt.html) for overview of how libvirt templates work in Qubes. The following assumes the target VM is named `target-vm`.
|
|
|
|
- Edit `/usr/share/qubes/templates/libvirt/xen.xml` to prepare our custom config to override just the NIC part of the global template:
|
|
- add `{% raw %}{% block network %}{% endraw %}` before `{% raw %}{% if vm.netvm %}{% endraw %}`
|
|
- add `{% raw %}{% endblock %}{% endraw %}` after the matching `{% raw %}{% endif %}{% endraw %}`
|
|
- Copy `/usr/share/qubes/templates/libvirt/devices/net.xml` to `/etc/qubes/templates/libvirt/xen/by-name/target-vm.xml`.
|
|
- Add `<model type='e1000'/>` to the `<interface>` section.
|
|
- Enclose everything within `{% raw %}{% block network %}{% endraw %}` + `{% raw %}{% endblock %}{% endraw %}`.
|
|
- Add `{% raw %}{% extends 'libvirt/xen.xml' %}{% endraw %}` at the start.
|
|
- The final `target-vm.xml` should look something like this:
|
|
|
|
~~~
|
|
{% raw %}
|
|
{% extends 'libvirt/xen.xml' %}
|
|
{% block network %}
|
|
<interface type='ethernet'>
|
|
<mac address="{{ vm.mac }}" />
|
|
<ip address="{{ vm.ip }}" />
|
|
<backenddomain name="{{ vm.netvm.name }}" />
|
|
<script path='vif-route-qubes' />
|
|
<model type='e1000' />
|
|
</interface>
|
|
{% endblock %}
|
|
{% endraw %}
|
|
~~~
|
|
|
|
- Start `target-vm` and verify in the device manager that a "Intel PRO/1000 MT" adapter is present.
|
|
|
|
## Host and target preparation
|
|
|
|
- On `host-vm` you will need WinDbg, which is a part of the [Windows SDK](https://developer.microsoft.com/en-us/windows/downloads/windows-sdk/).
|
|
- Copy the `Debuggers` directory from Windows SDK to `target-vm`.
|
|
- In both `host-vm` and `target-vm` switch the windows network to private (it tends to be public by default).
|
|
- Either turn off the windows firewall or enable all ICMP-in rules in both VMs.
|
|
- In `firewall-vm` edit `/rw/config/qubes-firewall-user-script` to connect both Windows VMs, add:
|
|
- `iptables -I FORWARD 2 -s <target-vm-ip> -d <host-vm-ip> -j ACCEPT`
|
|
- `iptables -I FORWARD 2 -s <host-vm-ip> -d <target-vm-ip> -j ACCEPT`
|
|
- run `/rw/config/qubes-firewall-user-script` so the changes take effect immediately
|
|
- Make sure both VMs can ping each other.
|
|
- In `target-vm`:
|
|
- start elevated `cmd` session
|
|
- `cd sdk\Debuggers\x64`
|
|
- `kdnet` should show that the NIC is supported, note the busparams:
|
|
|
|
~~~
|
|
Network debugging is supported on the following NICs:
|
|
busparams=0.6.0, Intel(R) PRO/1000 MT Network Connection, KDNET is running on this NIC.
|
|
~~~
|
|
|
|
- `bcdedit /debug on`
|
|
- `bcdedit /dbgsettings net hostip:<host-vm-ip> port:50000 key:1.1.1.1` (you can customize the key)
|
|
- `bcdedit /set "{dbgsettings}" busparams x.y.z` (use the busparams `kdnet` has shown earlier)
|
|
- In `host-vm` start WinDbg: `windbg -k net:port=50000,key=1.1.1.1`. It will listen for target's connection.
|
|
- Reboot `target-vm`, debugging should start:
|
|
|
|
~~~
|
|
Waiting to reconnect...
|
|
Connected to target 10.137.0.19 on port 50000 on local IP 10.137.0.20.
|
|
You can get the target MAC address by running .kdtargetmac command.
|
|
Connected to Windows 10 19041 x64 target at (Thu Aug 3 14:05:48.069 2023 (UTC + 2:00)), ptr64 TRUE
|
|
~~~
|
|
|
|
Happy debugging!
|