Usermode Application Debugging Using KD
Posted on Wed 24 September 2014 in Reverse Engineering
I have started the Windows kernel hacking section with a simple explaination of the setup and a quick analysis of the crackme, that we analysed here, using the kd.exe kernel debugger.
I chose to do this instead of any actual Windows kernel stuff because its a steep learning experience learning how to use KD so its probably best to look at something you have already seen.
Setting Up The Environment
For this post I will be using a total of 4 machines, 3 virtual machines using VMware Player (you probably could use Virtualbox for this also though) hosted on a reasonably powerful machine and a laptop.
You can however do all of this with just 1 physical machine, hosting 1 virtual machine and I will explain the differences in the setup afterwards but I'll first explain the setup I am using.
Here is a visual representation of the network:
So I have 3 virtual machines on my machine running VMware Player:
1 Kali Linux, 1 Windows XP Professional and 1 Windows 7 Home Edition. All 3 of these are 32bit, although it doesn't matter but to follow along you would probably want the debuggee (the Windows 7 machine in my setup) to be 32bit. In my 2 machine setup described below the host (and debugger) is a Windows 7 64bit machine.
The Kali machine has 2 network interfaces, 1 setup in Bridged mode (so that I can SSH directly to it):
And the other setup in Host-only mode (So that it has access to the other 2 machines):
The Windows XP machine has 1 network interface setup in Host-only mode:
And the same for the Windows 7 machine:
The Windows XP and Windows 7 machines are also connected via a virtual serial cable, this is for the debugger connection.
The Windows XP machine will be the client (or the debugger):
And the Windows 7 machine will be the server (or the debuggee):
The Windows 7 machine needs both Visual Studio Express 2013 for Windows Desktop and the Windows Driver Kit (WDK) installed on it. You can get them both here.
The Windows XP machine needs Microsoft Windows SDK for Windows 7 installed, which you can get here. To install this you need to install the full version of Microsoft .NET Framework 4, which you can get here (Bare in mind that you might need an internet connection while you install these so just change the network adaptor configuration to NAT and then once it is installed change it back to Host-only again).
If the debugger is a Windows 7 machine then you will need to install the same software as on the debuggee.
Once these are installed, its best to add the path to the kd.exe application to the PATH variable.
You do this by going in to the properties of My Computer and, on Windows 7 going to Advanced system settings->Environment Variables... or on Windows XP going to Advanced->Environment Variables... and scroll down the Path and click Edit.
The path on Windows 7 should be something like C:\Program Files\Windows Kits\8.1\Debuggers\x86 and on Windows XP C:\Program Files\Debugging Tools for Windows (x86).
For remote administration I've installed TightVNC on both of the Windows machines.
I set it up with access through a Kali machine so that I can setup SSH tunnels and get VNC access to the Windows machines without giving them access to the outside network.
After TightVNC is up and running on your Windows machines, you can setup the SSH tunnels like this (For this explaination we'll imagine that the Windows XP machine is on the VMware virutal network with an IP of 172.16.188.130, the Windows 7 machine is on 172.16.188.131 and that our Kali machine is also on this network):
1 2 |
|
Now if you VNC to 127.0.0.1 you will have access to the Windows XP machine and to 127.0.0.1:1 you will have access to the Windows 7 machine.
1 VM Setup
You can also setup this up with 2 machines, the VMware host (running Windows, which will be the debugger) and the VMware guest (also running Windows, which will be the debuggee).
The serial port configuration for the debuggee in VMware in this setup should look like this:
Notice the different file path and name for Windows, the other end should be set to The other end is an application and Yeild CPU on poll should be checked.
The only other thing that is different is the command you will use to launch KD on the debugger (we haven't got to that but it is shown below for my 4 machine setup), you should instead use kd -k com:port=\\.\pipe\com_1,pipe
.
Using KD
On Windows 7 (the debuggee) you will need to tell it to lanuch the debugger on boot, for this you need to run an Administrator command prompt and:
1 2 3 4 5 |
|
The DEBUGPORT:2 option here is the port number of the COM port that you are going to use, for me it was COM2 hence the number 2.
Now we launch the kernel debugger on the Windows XP machine (this is the command that is different on the 2 machine setup):
1 2 3 4 5 6 7 |
|
Again the port=1 option here is the COM port that you are going to be using, I will be using COM1 on this machine hence the 1.
Then reboot the Windows 7 machine and watch the KD terminal on the Windows XP machine:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
Now run the crackme application on the debuggee (Windows 7):
Go back to the Windows XP machine and in the debugger terminal window press Control + C:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
Now we have broken into the kernel, this means that anything we do will be in the context of the kernel, we can see this in the debugger:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
|
On line 1 I run the .process command without any parameters and it tells us the process we are currently in (844bdae8 is the EPROCESS number).
On line 3 I run the !process extension with 0 0 as its arguments, this lists all of the running processes and some details about them, as you can see from lines 5-7, EPROCESS 844bdae8 is the System process, or the kernel.
What we want to do is change the context to our crackme application, which you can see from lines 141-143 has the EPROCESS of 85abfd40:
1 2 3 4 5 6 7 8 9 10 11 |
|
On line 1 I use the .process command to change the context to our crackme application but before the context can be changed execution needs to be resumed (which is done on line 5).
Now we can set a breakpoint anywhere in the crackme's virtual memory address space, we want to break with them calls to GetDlgItemTextA that were responsible for getting the text in the textboxes of the application (If you are unsure about what I am talking about, please go back and review the previous post):
1 2 3 4 |
|
Now that the breakpoint is set we can resume execution, wait for it to be hit and inspect the memory.
Remember that the prototype for GetDlgItemText is:
1 2 3 4 5 6 |
|
1 2 3 4 5 6 7 8 9 |
|
On line 5 I use the dd command to display 4 double words on the top of the stack. The first dword will be the return address (as you will see in a minute), then we have the first 3 arguments.
The 3rd argument is the address where the buffer for the string is, on line 7 I use the da command to display the ascii value at that address.
Keep in mind that this is the start of the function so the value hasn't been fetched yet, we can see the returned value by tracing through until we are in the calling function using the ug command and checking again:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
As you can see the value is the same (because we haven't changed the text in the textbox), you can also see the address which it returned back to after executing GetDlgItemTextA was 0040127f, which was the top value on the stack.
Lastly let's resume and make sure it does the same with the other textbox:
1 2 3 4 5 6 7 8 9 10 11 12 |
|
Conclusion
This was only a simple tutorial to get the environment set up and get a basic grasp of kd.exe and some of its commands.
This was by no means an exhaustive list of commands and extensions, the debugger comes with many and has very good documentation.
Hopefully you now have a better understanding of how to debug using kd.exe and you now have the environment to do it in.
Further Reading
The Debugging and Automation chapter in Practical Reverse Engineering by Bruce Dang, Alexandre Gazet and Elias Bachaalany.
Also the kd.exe documentation that ships with the WDK or SDK.