Continuing on from the last post, it’s time to make two big changes. We’re moving from Windows 7 to Windows 8.1, and we’re moving from x86 to x64.

Like before, Windows 8.1 isn’t necessarily just available for download, so I’m providing a link to the ISO hosted on my Google Drive here.

We’ll be using the same bug from the HackSysExtremeVulnerableDriver as last time, just modifying it to work on 64 bit Windows 8.1. If you want to read more about the bug, please see the last post.

Time to develop the first exploit of the series - a stack based buffer overflow for Windows 7.

I’ll be using the HackSysExtremeVulnerableDriver when writing exploits for this section. This is an intentionally vulnerable driver that has a large number of different vulnerabilities coded into it for people to practice on. I highly recommend downloading it and following along.

Why Windows 7?

Kernel exploit development on Windows is a bit different from user land exploit development. There are different goals and different mitigations that prevent an exploit developer from achieving them.

There are two main ways people set up kernel debuggers for Windows - via the network and a via a virtual serial cable.

When possible, I recommend using the network variation. It is a lot faster and more stable, and is what is currently recommended by Microsoft. That said, for some older operating systems, particularly if dealing with Windows 7, the serial option is the only one possible.

I use VMware Workstation Pro as my hypervisor for kernel debugging so all examples given here will use that. Many people also use Hyper-V though, and it should be easy enough to modify these instructions for that as well.

Finally, time to get to what I promised in the first place - reversing a driver!

The first step, of course, will be to set up a debugger. Then we’ll put our driver into IDA, rebase the .text segment, and look at some IRPs flowing through it.

Install the VM

I’ll be using VMWare Workstation Pro as my hypervisor for this. It’s the most ubiquitous hypervisor out there (and in my opinion the easiest to use).

Alright, all the work in the previous posts has led up to this: a driver that does something!

Admittedly, it won’t do much. The driver I will be going over here heavily takes code from the example IOCTL driver in the Windows driver samples repo, and all that does is copy data from one buffer to another. It will, however, give a good idea of how drivers handle I/O from their calling applications, as well as some of the benefits and drawbacks of different IO methods.

If you’ve been following along with this series, in the last post I walked through how to build a minimum viable driver and how to load it into Windows.

That said, the previous driver simply loaded and unloaded itself, nothing more. In this post we’re going to go over how to send messages to our driver and have it respond.

The IRP

As I explained in part 2, a driver in Windows is a small piece of software that sits in kernel space and responds to requests.

Alright, enough talk. The best way to learn is by doing, and by coding our own simple driver, we’ll get a good idea of what function driver code looks like.

Setting up the dev environment

There are several tools you’ll need in order to compile your driver. Driver development has gotten easier over the years, but it is still more complex than just compiling a userland C++ program. You may benefit from installing all of this in a VM and saving a snapshot so you have it configured and ready to go whenever you want it, but it’s also perfectly fine to install the tools on bare metal.

If you’ve used Windows long enough, chances are you’ve heard the term driver before. Admittedly, it was probably in the context of something like this:

Driver Unable to Install

or this:

Blue Screen of Death

or potentially, given the audience for this kind of blog post, this?

Anti-Cheat Detected Cheating on Apex Legends

However, if we’re going to be doing exploit development work on drivers, it’s important to have a fundemental understanding of what a driver does and the role it plays in a modern operating system.

What is this?

During the last semester of my master’s degree at UMass Amherst, I was fortunate enough to be able to take an exploit development class taught by Lurene Grenier. I had previous experience in CTF style pwn, but this class pushed us all to move past CTF challenges to real world targets as fast as possible. The thought process behind this was that although CTFs are great for learning the basics, because of their contrived nature, the skills they impart don’t always translate to hacking on real software.

This is a challenge I wrote for UMass CTF 2025 using a special version theLEG™ computer architecture. I’ll have a separate series of blog posts on the architecture itself and why it is interesting, but for this I want to go over the specifics of the challenge.

The Challenge

Participants in the CTF were given the following prompt:

TheLEG™ just got updated with a brand new UI and speculative execution extension! Surely no one can read data from kernel space…