Windows x86 Debugger
Introduction
A tiny Windows x86 debugging framework written in C++20 that supports software breakpoints and hardware breakpoints. It can be used to create custom debuggers. Some design patterns came from GleeBug.
Getting Started
Prerequisites
- Install Visual Studio 2022.
- Install CMake.
- Set the
PATH
environment variables.
Building
Set the location to the project folder and run:
mkdir -p build
cd build
cmake .. -G "Visual Studio 17 2022" -A Win32
cmake --build .
Usage
Users can create derived classes inheriting from Debugger
class and override or implement provided event callbacks.
Debugger
does not provide any implementation for event callbacks whose names start withcb
.Debugger
provides the basic implementation for event callbacks whose names start withOn
.
class MyDebugger : public Debugger {
private:
void cbCreateProcess(const CREATE_PROCESS_DEBUG_INFO& details,
const Process& process) override {
std::cout << std::format("The process {} has been created.",
process.Id())
<< std::endl;
}
void cbExitProcess(const EXIT_PROCESS_DEBUG_INFO& details,
const Process& process) override {
std::cout << std::format("The process {} has exited.",
process.Id())
<< std::endl;
}
};
Documents
Code comments follow Doxygen specification.
Class Diagram
classDiagram
class RegisterIndex {
<<enumeration>>
EAX
EBX
ECX
EDX
}
class Register {
Set(int)
Reset()
Get() int
}
Register --> RegisterIndex
class Flag {
<<enumeration>>
CF
AF
PF
ZF
}
class FlagRegister {
SetCF()
ResetCF()
CF() bool
}
Register <|-- FlagRegister
FlagRegister ..> Flag
class DebugStatusRegister {
SetB0()
ResetB0()
B0() bool
}
Register <|-- DebugStatusRegister
class DebugControlRegister {
SetL0()
ResetL0()
L0() bool
SetRW0(val)
RW0() int
}
Register <|-- DebugControlRegister
class Registers {
Register EAX
FlagRegister EFLAGS
DebugStatusRegister DR6
DebugControlRegister DR7
}
Registers o-- Register
class Breakpoint {
int address
}
class HardwareBreakpointSlot {
<<enumeration>>
DR0
DR1
DR2
DR3
}
class HardwareBreakpointType {
<<enumeration>>
Execute
Write
ReadWrite
}
class HardwareBreakpointSize {
<<enumeration>>
Byte
Word
Dword
}
class HardwareBreakpoint {
HardwareBreakpointSlot slot
HardwareBreakpointType access
HardwareBreakpointSize size
}
Breakpoint <|-- HardwareBreakpoint
HardwareBreakpoint --> HardwareBreakpointSlot
HardwareBreakpoint --> HardwareBreakpointType
HardwareBreakpoint --> HardwareBreakpointSize
class SoftwareBreakpoint {
byte origin
}
Breakpoint <|-- SoftwareBreakpoint
class Thread {
Suspend()
Resume()
StepInto()
SetHardwareBreakpoint(addr, slot, type, size)
DeleteHardwareBreakpoint(slot)
}
Thread *-- HardwareBreakpoint
Thread --> Registers
class Process {
Suspend()
Resume()
FindThread(id) Thread
NewThread(thread)
RemoveThread(thread)
SetSoftwareBreakpoint(addr, callback)
DeleteSoftwareBreakpoint(addr)
FindSoftwareBreakpoint(addr) SoftwareBreakpoint
SetHardwareBreakpoint(addr, slot, type, size, callback)
DeleteHardwareBreakpoint(addr)
FindHardwareBreakpoint(addr) HardwareBreakpoint
WriteMemory(addr, data)
ReadMemory(addr, size) vector~byte~
}
Process *-- Thread
Process *-- SoftwareBreakpoint
class Debugger {
Create(file, cmd)
Attach(proc)
Start()
Detach()
Stop()
}
Debugger o-- Process
License
Distributed under the MIT License. See LICENSE
for more information.