/Windows-x86-Debugger

🐞 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.

Primary LanguageC++MIT LicenseMIT

Windows x86 Debugger

C++ CMake Visual-Studio Windows License

Introduction

Cover

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

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 with cb.
  • Debugger provides the basic implementation for event callbacks whose names start with On.
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.