And here we are with the 4th and last blog post of this series, the one covering the final debugging tool, the one you take out when nothing else works: Windows Debuggers!
Now, what is Debugging?
Debugging is the process of finding and fixing errors or bugs in software. It involves identifying the cause of the issue, determining how the issue is affecting the software, and then taking steps to correct the issue. Debugging can be done by a software developer, or by a dedicated debugging tool, and is an essential part of the software development process to ensure that the software works as intended and meets its requirements. The process of debugging can range from simple problem-solving techniques to complex analysis and testing.
As the focus of these series if posts is on troubleshooting rather than software development we’ll be focusing on the utility this tool can bring to IT Professionals rather than Developers.
There are multiple debugging tools available for Windows, but most of them rely on an underlying debugging library called Dbgeng.dll which is included in Windows (with the exception of the Visual Studio debugger). The most notable ones are:
CDB (Microsoft Console Debugger) is a powerful and simple to use user mode debugging tool for Windows, capable of analyzing both console and graphical Windows applications. It allows for live analysis of memory, can display and execute program code, set breakpoints, and examine/change values in memory. CDB also supports debugging multiple threads and processes, can analyze binary and source code, and is extensible. It is a character-based console program that can be used for low-level analysis and is useful for debugging both working and failing applications, and can be used across a network.
Microsoft Kernel Debugger (KD) is a character-based console program for in-depth analysis of kernel-mode activity on all NT-based operating systems. It is used for debugging kernel-mode components and drivers or monitoring the behavior of the operating system. KD supports multiprocessor debugging and requires two computers, a host computer and a target computer, for kernel-mode debugging.
WinDbg is a Windows-based debugger that supports both user-mode and kernel-mode debugging. It provides debugging for the Windows kernel, kernel-mode drivers, system services, as well as user-mode applications and drivers. WinDbg uses Visual Studio debug symbols for source-level debugging, can view source code, set breakpoints, view variables, stack traces, and memory. Its Debugger Command window allows a wide range of commands to be issued. For kernel-mode debugging, two computers are typically required (host and target). Remote debugging options are available for both user-mode and kernel-mode targets. WinDbg is a graphical-interface alternative to CDB/NTSD and KD/NTKD. This will be the tool we’ll be focusing on in this post.
Additional information can be found here: https://learn.microsoft.com/en-us/windows-hardware/drivers/debugger/debuggers-in-the-debugging-tools-for-windows-package
Note: As I’m not an expert of this product and haven’t used it extensively this will be only a fairly superficial overview. Additional reading materials will be provided at the end of this post for deeper diving.
Before we can use the application we have to install it and configure it.
To do so first create a folder to store the downloaded symbols:
In this case I’m using C:\Temp\Symbols.
Then open the Windows Environmental Variables either manually or by using the command
Then click on “New”
Add the following strings:
Variable name: _NT_SYMBOL_PATH
Variable value: srv*C:\Temp\symbols*https://msdl.microsoft.com/download/symbols
And click OK
Click OK again to close the window:
Now, before we configure the Sysinternals suite with the newly configured symbol paths we need to install the correct version of the Windows Software Development Kit.
It can be downloaded from here if you have the latest version of Windows: https://developer.microsoft.com/en-us/windows/downloads/windows-sdk/
Or from here if you have an older version of Windows: https://developer.microsoft.com/en-us/windows/downloads/sdk-archive/
Once downloaded open it, select the first option and click Next:
Here select only “Debugging Tools for Windows” and then click on “Install”:
Now open WinDBG:
This will be the window you’ll see:
You can add additional windows with information by clicking on these buttons:
That said, I recommend installing one of the following themes which will make life much easier (and, more importantly, more pleasant): https://github.com/lololosys/windbg-theme
For the duration of this post I’ll be using the dark theme:
Now, let’s configure Symbols:
And then add the same string you’ve configured previously:
If you have the application’s source code you can also point to it:
And now we should be ready to play!
Basics of Windows Architecture
Windows operates in two distinct processor access modes to safeguard critical operating system (OS) data from being accessed or altered by user applications. These modes are known as user mode and kernel mode.
Applications run in user mode, while the OS code, such as system services and device drivers, operates in kernel mode. In kernel mode, a processor grants access to all system memory and all CPU instructions. This mode is also referred to as code privilege level, ring level, or supervisor mode by different processors. By giving the OS kernel a higher privilege level than user mode applications, the processor helps to prevent a misbehaving application from disrupting the overall stability of the system.
While each Windows process has its own private memory space, the kernel-mode OS and device-driver code share a single virtual address space. Each page in virtual memory is tagged to indicate the access mode required to read or write the page. Pages in system space are only accessible from kernel mode, while all pages in user address space are accessible from both user and kernel modes. Read-only pages, such as those containing static data, are not writable from any mode.
In processors that support no-execute memory protection, Windows marks data pages as non-executable to prevent accidental or malicious code execution in data areas. This feature, known as Data Execution Prevention (DEP), is enabled if supported by the processor. However, Windows does not provide protection for private read/write system memory being used by components in kernel mode. This means that once in kernel mode, the OS and device-driver code have complete access to system-space memory and can bypass Windows security to access objects.