What EXDi can do for you that DCI can’t

In the previous post, I discussed the hardware debugger that I managed to “build” and “use”. For the purpose I wanted to use it (debugging a fully secured Windows System with WinDbg) it was not useful at all. But not everything was lost. Because I enjoy figuring out how things work and (in particular) why they don’t work, I invested my time and take a thorough analysis. So (as somebody referred to this accurately) I actually “debugged the debugger”. And because what I’ve found is (somehow) documented (documented == there_is_sample_code) and (literally) right in the front of us, I modified what I found to make it work with QEMU. 

So let’s briefly discuss all pieces.

Intel Windbg plugin

So how does the mentioned Windbg debugger work with DCI? The whole idea is quite simple: it uses something that is called EXDi or EXDI.

I’m not sure what EXDi means; I would say it is an acronym for EXtended Debugging iNterface (it is even possible that I saw this name somewhere, but it’s not that important). It is also hard to say when Microsoft introduced this concept – I briefly looked at some of Windows XP code that leaked online looong time ago and I’ve found some headers or so. So let’s say it’s rather old.

So what is this for? EXDi makes it possible to write a plugin that WinDbg can use for debugging various types of Windows (and not only Windows) targets using JTAG like interfaces, so interfaces that are not known to Microsoft and thus WinDbg. 

The idea is simple: we are writing simple plugin where we have to implement only a few interfaces (functions). Then WinDbg loads this plugin (that connects to target using own protocol) and uses those functions to provide functionality for (almost*) regular WinDbg debugging. How does it work? We have to “feed” the plugin with correct target’s context (registers), functions to read/write memory, for setting/clearing a breakpoint, etc. Based on that, WinDbg will figure out everything else – kernel in memory, modules in memory, stackframes, etc. So it will translate this information from unreadable, ugly binary-like form to beautiful, shinning, fully readable form through heuristics.

Sounds cool, but why and where we should use it? To use WinDbg with the system that has no debugger enabled at all. So if you have Secure Boot enabled – it’s going to work. And because EXDi uses internal heuristics in WinDbg for memory scanning and extracting important information from registers, we can use the EXDi plugin for debugging modules that can’t be debugged even with debugger enabled – like (infamous) securekernel.exe**

/ **The only drawback is that it requires stopping the target when it is in the correct context – i.e. securekernel.exe context; which can be a bit tricky/

Qemu as a JTAG

Qemu has already a JTAG-like equivalent implemented – which is just a GDB server based on GDB protocol. In contrary to DCI, system doesn’t crash after connecting to the guest!

So the bright idea is to implement EXDi plugin that talks with QEMU’s target using GDB protocol. 

And this is the right way of thinking! And guess what? There is a sample already written by Microsoft that is doing that. Where is that sample? Installed together with WinDbg tools. Yes, hidden in the plain sight…

/ hint: After installing Debugging Tools check the location “C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\sdk\samples\exdi\ExdiGdbSrvSample” /

The sample plugin 

This sample has a code for EXDi plugin and GDB protocol – but for 32 bit x86 VMware guests, and only this code has been tested by Microsoft. We live in the 21st Century – nobody wants to debug 32 bit x86 system anymore, right?! (OK, I have to confess it – I’m debugging 32 bit x86 Windows guests in QEMU from time to time; but you get my point).

Anyway – I started changing the sample to get it working with QEMU instead of VMware.

What are the differences? Not so many. The first thing is that VMware keeps separate GDB connection for each CPU. But the major differences are in context (registers’ state) and breakpoints instructions.

After getting 32 bit (x86) working with a bit of hacking here and there (QEMU GDB server stub doesn’t provide all the registers for 32 bit debugging that are required by EXDi and WinDbg) I started looking at 64 bit x86 bit and finally… got it working.

And that’s all for today – in the last post in the series I’ll discuss the code and the usage!

PS I did a presentation for the KVM forum about my findings. Because I was disappointed that I had only 20 minutes for the presentation (this is a tiny amount of time for discussing interesting things), I wrote a set of three blog posts sharing knowledge and extending what I couldn’t explain during the presentation. This is the 2nd post in the series.

*Note that his whole EXDi is still under investigation, as there are some limitations. Because it uses heuristics, it can’t replace the WinDbg when it comes to command like sxe ld my_module_name. But it’s the only way for debugging specific scenarios that I described.

Leave a Comment