10#pragma comment(lib, "Advapi32.lib")
11#pragma comment(lib, "ntdll.lib")
20#include <unordered_map>
116 enum class Flags64 : DWORD64 {
150 enum class Register64 {
151 RAX, RBX, RCX, RDX, RSI, RDI, RBP, RSP,
152 R8, R9, R10, R11, R12, R13, R14, R15,
161 EAX, EBX, ECX, EDX, ESI, EDI, EBP, ESP,
175 LPVOID bpAddrToRestore;
176 bool needToRestoreBreakpoint;
181 HANDLE hwBPThreadToRestore;
191 uintptr_t baseAddressOffset = 0;
198 std::map<LPVOID, BYTE> breakpoints;
199 std::map<LPVOID, hwBp_t> hwBreakpoints;
200 std::map<LPVOID, BYTE> dlls;
201 std::vector<thread_t> threads;
203 HANDLE hProcessGlobal =
nullptr;
204 HANDLE hThreadGlobal =
nullptr;
213 virtual void onStart(uintptr_t imageBase, uintptr_t entryPoint);
234 virtual void onThreadCreate(HANDLE hThread,
DWORD threadId, uintptr_t threadBase, uintptr_t startAddress);
249 virtual bool onDLLLoad(uintptr_t address, std::string dllName, uintptr_t entryPoint);
256 virtual void onDLLUnload(uintptr_t address, std::string dllName);
280 virtual void onSinglestep(uintptr_t address, HANDLE hThread);
294 virtual void onAccessViolation(uintptr_t address, uintptr_t faultingAddress,
long accessType);
406 bool writeMemory(LPVOID address,
const void* buffer, SIZE_T size);
415 bool readMemory(LPVOID address,
void* buffer, SIZE_T size);
452 std::vector<uintptr_t>
searchInMemory(
const std::vector<BYTE>& pattern);
461 uintptr_t
ASLR(LPVOID address);
468 uintptr_t
ASLR(uintptr_t address);
489 bool getFlag(HANDLE hThread, Flags64 flag);
497 void setFlag(HANDLE hThread, Flags64 flag,
bool enabled);
505 int64_t
getRegister(HANDLE hThread, Register64 reg);
513 void setRegister(HANDLE hThread, Register64 reg, int64_t value);
599 hwBp_t bp = { hThread, address, reg, type, len };
612 hwBp_t bp = { (HANDLE)
nullptr, address, reg, type, len };
625 hwBp_t bp = { (HANDLE)
nullptr,
reinterpret_cast<LPVOID
>(
static_cast<intptr_t
>(address)), reg, type, len };
647 inline bool writeMemory(uintptr_t address,
const void* buffer, SIZE_T size) {
648 return writeMemory(
reinterpret_cast<LPVOID
>(address), buffer, size);
658 inline bool readMemory(uintptr_t address,
void* buffer, SIZE_T size) {
659 return readMemory(
reinterpret_cast<LPVOID
>(address), buffer, size);
671 SIZE_T bytesWritten = 0;
672 if (!WriteProcessMemory(hProcessGlobal,
reinterpret_cast<LPVOID
>(address), &value,
sizeof(T), &bytesWritten) || bytesWritten !=
sizeof(T)) {
675 FlushInstructionCache(hProcessGlobal,
reinterpret_cast<LPVOID
>(address),
sizeof(T));
688 SIZE_T bytesRead = 0;
689 if (!ReadProcessMemory(hProcessGlobal,
reinterpret_cast<LPCVOID
>(address), &value,
sizeof(T), &bytesRead) || bytesRead !=
sizeof(T)) {
702 return a ==
reinterpret_cast<LPCVOID
>(b);
711 return hProcessGlobal;
730 int start(std::string exeName);
738 int start(std::string exeName,
const std::vector<std::string>& args);
745 int attach(std::string exeName);
int start(std::string exeName)
Starts a process under debugging.
virtual void onAttach()
Called after successfully attaching to an already running process.
DRReg isHardwareBreakpointAt(LPVOID address)
Checks if a hardware breakpoint exists at an address.
bool setHardwareBreakpoint(LPVOID address, DRReg reg, AccessType type, BreakpointLength len)
Sets a hardware breakpoint process-wide (current/future threads as applicable).
void enableSingleStep(HANDLE hThread)
Enables trap flag (single-step) for a thread.
int32_t getRegister(HANDLE hThread, Register32 reg)
Reads a 32-bit general-purpose register.
int loop()
Main debugger message loop.
bool changeMemoryProtection(uintptr_t baseAddress, SIZE_T regionSize, DWORD newProtect)
Changes memory protection on a region (uintptr_t overload).
int attach(std::string exeName)
Attaches to a running process by name.
HANDLE getProcessHandle()
Returns HANDLE of debugged process.
bool hideDebugger()
Attempts to hide the debugger from basic anti-debug checks.
uintptr_t ASLR(LPVOID address)
Applies the module ASLR slide to an LPVOID.
bool clearHardwareBreakpoint(DRReg reg)
Clears a DRx slot across threads.
virtual void onAccessViolation(uintptr_t address, uintptr_t faultingAddress, long accessType)
Called on access violation (AV).
virtual void onThreadExit(DWORD threadID)
Called when a thread exits.
void setFlag(HANDLE hThread, Flags32 flag, bool enabled)
Sets or clears a status flag in EFLAGS.
std::vector< hwBp_t > getHardwareBreakpoints()
Enumerates current hardware breakpoints.
bool writeMemory(uintptr_t address, const void *buffer, SIZE_T size)
Writes raw bytes to target memory (uintptr_t overload).
virtual void onEnd(DWORD exitCode, DWORD pid)
Called when the debuggee exits.
bool getFlag(HANDLE hThread, Flags32 flag)
Reads a status flag from EFLAGS.
MemoryRegion_t getPageByAddress(LPVOID baseAddress)
Gets information for the page containing an address.
bool isEqual(LPVOID a, uintptr_t b)
Compares an LPVOID to a uintptr_t for equality.
bool setHardwareBreakpointOnThread(hwBp_t bp)
Sets a hardware breakpoint for a specific thread.
virtual void onDLLUnload(uintptr_t address, std::string dllName)
Called when a DLL is unloaded.
virtual void onUnknownException(uintptr_t addr, DWORD code)
Called on unknown exception.
virtual void onStart(uintptr_t imageBase, uintptr_t entryPoint)
Called when a new debuggee process is started.
T readMemory(uintptr_t address)
Reads a POD value from target memory (typed helper).
std::vector< uintptr_t > searchInMemory(const std::vector< BYTE > &pattern)
Scans process memory for a byte pattern.
virtual void onThreadCreate(HANDLE hThread, DWORD threadId, uintptr_t threadBase, uintptr_t startAddress)
Called when a thread is created in the debuggee.
int detach()
Detaches from the current debuggee.
void setBreakpoint(LPVOID address)
Sets a software INT3 breakpoint at an address.
std::vector< MemoryRegion_t > getMemoryPages()
Enumerates readable/committed pages of the process.
bool clearHardwareBreakpointOnThread(HANDLE hThread, DRReg reg)
Clears a DRx slot on a single thread.
hwBp_t getBreakpointByReg(DRReg reg)
Gets the breakpoint definition bound to a DRx register.
void decrementIP(HANDLE hThread)
Moves the instruction pointer one instruction backward (post-breakpoint fixup).
void PrintMemoryPages()
Prints a formatted list of memory pages (debug helper).
bool readMemory(LPVOID address, void *buffer, SIZE_T size)
Reads raw bytes from target memory.
void setRegister(HANDLE hThread, Register32 reg, int32_t value)
Writes a 32-bit general-purpose register.
virtual void onRIPError(const RIP_INFO &rip)
Called on RIP error (native debug port issues).
virtual bool onDLLLoad(uintptr_t address, std::string dllName, uintptr_t entryPoint)
Called when a DLL is loaded.
void restoreBreakpoint(LPVOID address)
Restores the original byte at a software breakpoint address.
virtual BreakpointAction onBreakpoint(uintptr_t address, HANDLE hThread)
Called on software breakpoint (INT3).
virtual void onDebugString(std::string dbgString)
Called when OutputDebugString is emitted by the debuggee.
void setBreakpoint(uintptr_t address)
Sets a software INT3 breakpoint.
bool setHardwareBreakpoint(hwBp_t bp)
Sets a hardware breakpoint for all existing (and future) threads where applicable.
bool setHardwareBreakpointOnThread(HANDLE hThread, LPVOID address, DRReg reg, AccessType type, BreakpointLength len)
Sets a hardware breakpoint on a specific thread.
bool writeMemory(uintptr_t address, const T &value)
Writes a POD value to target memory (typed helper).
MemoryRegion_t getPageByAddress(uintptr_t baseAddress)
Gets page information for an address.
void printIP(HANDLE hThread)
Prints the current instruction pointer (IP/EIP/RIP) of a thread.
virtual BreakpointAction onHardwareBreakpoint(uintptr_t address, HANDLE hThread, DRReg reg)
Called on hardware breakpoint hit.
DRReg isHardwareBreakpointAt(uintptr_t address)
Checks if a hardware breakpoint exists at an address.
bool writeMemory(LPVOID address, const void *buffer, SIZE_T size)
Writes raw bytes to target memory.
bool changeMemoryProtection(LPVOID baseAddress, SIZE_T regionSize, DWORD newProtect)
Changes memory protection on a region.
bool readMemory(uintptr_t address, void *buffer, SIZE_T size)
Reads raw bytes from target memory (uintptr_t overload).
void restoreBreakpoint(uintptr_t address)
Restores the original byte at a software breakpoint.
virtual void onUnknownDebugEvent(DWORD code)
Called on unhandled/unknown debug events.
Debugger()
Constructs a Debugger with default settings.
uintptr_t baseImageBase
Typical image base (with ASLR).
bool setHardwareBreakpoint(int address, DRReg reg, AccessType type, BreakpointLength len)
Sets a hardware breakpoint using a 32-bit int address (for convenience).
void actualizeThreadList()
Refreshes the internal thread list by querying the target process.
virtual void onSinglestep(uintptr_t address, HANDLE hThread)
Called on single-step exception.
Flags32
x86 CPU status flags.
@ AF
Auxiliary Carry Flag.
@ IF
Interrupt Enable Flag.
AccessType
Specifies the type of memory access that triggers a hardware breakpoint.
@ READWRITE
Trigger when reading from or writing to the address.
@ EXECUTE
Trigger when executing instructions at the address.
@ WRITE
Trigger when writing to the address.
Register32
32-bit x86 general-purpose registers.
@ EIP
Instruction Pointer.
BreakpointLength
Length of the hardware breakpoint watch.
BreakpointAction
Specifies the action to take when a breakpoint is hit.
@ SINGLE_STEP
Perform a single-step execution after hitting the breakpoint.
@ RESTORE
Restore the original instruction at the breakpoint.
@ BREAK
Stop execution at the breakpoint.
DRReg
Hardware debug registers used for breakpoints.
@ NOP
No register assigned.
Represents a memory region in a process.
DWORD Protect
Protection flags (e.g., PAGE_READWRITE).
SIZE_T RegionSize
Size of the memory region in bytes.
LPVOID BaseAddress
Base address of the memory region.
DWORD Type
Type (MEM_IMAGE, MEM_MAPPED, MEM_PRIVATE).
DWORD State
State (MEM_COMMIT, MEM_FREE, MEM_RESERVE).
Hardware breakpoint configuration.
BreakpointLength len
Length of the watch region.
LPVOID address
Address to watch.
AccessType type
Type of access that triggers the breakpoint.
DRReg reg
Debug register used.
HANDLE hThread
Target thread handle.
Represents a thread in a debugged process.
LPVOID threadBase
Base address of the thread.
HANDLE hThread
Thread handle.
LPVOID startAddress
Start address of the thread.
Various high-level Utility functions.