mirror of https://github.com/x64dbg/GleeBug
initial breakpoint work + added MemIsValidPtr + fixed some documentation inaccuracies
This commit is contained in:
parent
43415e12aa
commit
3568de5680
|
|
@ -0,0 +1,78 @@
|
||||||
|
#ifndef _DEBUGGER_BREAKPOINT_H
|
||||||
|
#define _DEBUGGER_BREAKPOINT_H
|
||||||
|
|
||||||
|
#include "Debugger.Global.h"
|
||||||
|
|
||||||
|
namespace GleeBug
|
||||||
|
{
|
||||||
|
enum class BreakpointType
|
||||||
|
{
|
||||||
|
Software,
|
||||||
|
Hardware,
|
||||||
|
Memory
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class SoftwareBreakpointType
|
||||||
|
{
|
||||||
|
ShortInt3
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class HardwareBreakpointType
|
||||||
|
{
|
||||||
|
Access,
|
||||||
|
Write,
|
||||||
|
Execute
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class HardwareBreakpointSize
|
||||||
|
{
|
||||||
|
SizeByte,
|
||||||
|
SizeWord,
|
||||||
|
SizeDword,
|
||||||
|
#ifdef _WIN64
|
||||||
|
SizeQword
|
||||||
|
#endif //_WIN64
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class MemoryBreakpointType
|
||||||
|
{
|
||||||
|
Acess,
|
||||||
|
Write,
|
||||||
|
Execute
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BreakpointInternalInfo
|
||||||
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
SoftwareBreakpointType type;
|
||||||
|
ptr size;
|
||||||
|
uint8 newbytes[2];
|
||||||
|
uint8 oldbytes[2];
|
||||||
|
} software;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
HardwareBreakpointType type;
|
||||||
|
HardwareBreakpointSize size;
|
||||||
|
} hardware;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
MemoryBreakpointType type;
|
||||||
|
ptr size;
|
||||||
|
} memory;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BreakpointInfo
|
||||||
|
{
|
||||||
|
ptr address;
|
||||||
|
bool enabled;
|
||||||
|
bool singleshoot;
|
||||||
|
BreakpointType type;
|
||||||
|
BreakpointInternalInfo internal;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //_DEBUGGER_BREAKPOINT_H
|
||||||
|
|
@ -10,14 +10,22 @@ namespace GleeBug
|
||||||
class ProcessInfo;
|
class ProcessInfo;
|
||||||
class DllInfo;
|
class DllInfo;
|
||||||
class ThreadInfo;
|
class ThreadInfo;
|
||||||
|
enum class BreakpointType;
|
||||||
|
struct BreakpointInfo;
|
||||||
|
|
||||||
|
//key typedefs
|
||||||
|
typedef std::pair<BreakpointType, ptr> BreakpointKey;
|
||||||
|
|
||||||
|
//callback function typedefs
|
||||||
|
typedef std::function<void()> StepCallback;
|
||||||
|
typedef std::function<void(const BreakpointInfo & info)> BreakpointCallback;
|
||||||
|
|
||||||
//map typedefs
|
//map typedefs
|
||||||
typedef std::map<uint32, ProcessInfo> ProcessMap;
|
typedef std::map<uint32, ProcessInfo> ProcessMap;
|
||||||
typedef std::map<Range, DllInfo, RangeCompare> DllMap;
|
typedef std::map<Range, DllInfo, RangeCompare> DllMap;
|
||||||
typedef std::map<uint32, ThreadInfo> ThreadMap;
|
typedef std::map<uint32, ThreadInfo> ThreadMap;
|
||||||
|
typedef std::map<BreakpointKey, BreakpointInfo> BreakpointMap;
|
||||||
//callback function typedefs
|
typedef std::map<BreakpointKey, BreakpointCallback> BreakpointCallbackMap;
|
||||||
typedef std::function<void()> StepCallback;
|
|
||||||
|
|
||||||
//vector typedefs
|
//vector typedefs
|
||||||
typedef std::vector<StepCallback> StepCallbackVector;
|
typedef std::vector<StepCallback> StepCallbackVector;
|
||||||
|
|
|
||||||
|
|
@ -6,27 +6,50 @@ namespace GleeBug
|
||||||
{
|
{
|
||||||
if (!_process->systemBreakpoint) //handle system breakpoint
|
if (!_process->systemBreakpoint) //handle system breakpoint
|
||||||
{
|
{
|
||||||
|
//set internal state
|
||||||
_process->systemBreakpoint = true;
|
_process->systemBreakpoint = true;
|
||||||
_continueStatus = DBG_CONTINUE;
|
_continueStatus = DBG_CONTINUE;
|
||||||
|
|
||||||
//call the callback
|
//call the callback
|
||||||
cbSystemBreakpoint();
|
cbSystemBreakpoint();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//check if the breakpoint exists
|
||||||
|
auto foundInfo = _process->breakpoints.find({ BreakpointType::Software, ptr(exceptionRecord.ExceptionAddress) });
|
||||||
|
if (foundInfo == _process->breakpoints.end())
|
||||||
|
return;
|
||||||
|
const auto & info = foundInfo->second;
|
||||||
|
|
||||||
|
//set continue status
|
||||||
|
_continueStatus = DBG_CONTINUE;
|
||||||
|
|
||||||
|
//call the generic callback
|
||||||
|
cbBreakpoint(info);
|
||||||
|
|
||||||
|
//call the user callback
|
||||||
|
auto foundCallback = _process->breakpointCallbacks.find({ BreakpointType::Software, info.address });
|
||||||
|
if (foundCallback != _process->breakpointCallbacks.end())
|
||||||
|
foundCallback->second(info);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Debugger::exceptionSingleStep(const EXCEPTION_RECORD & exceptionRecord, const bool firstChance)
|
void Debugger::exceptionSingleStep(const EXCEPTION_RECORD & exceptionRecord, const bool firstChance)
|
||||||
{
|
{
|
||||||
if (_thread->isSingleStepping) //handle single step
|
if (_thread->isSingleStepping) //handle single step
|
||||||
{
|
{
|
||||||
|
//set internal status
|
||||||
_thread->isSingleStepping = false;
|
_thread->isSingleStepping = false;
|
||||||
_continueStatus = DBG_CONTINUE;
|
_continueStatus = DBG_CONTINUE;
|
||||||
|
|
||||||
//call the callbacks
|
//call the generic callback
|
||||||
StepCallbackVector cbStepCopy = _thread->stepCallbacks;
|
cbStep();
|
||||||
|
|
||||||
|
//call the user callbacks
|
||||||
|
auto cbStepCopy = _thread->stepCallbacks;
|
||||||
_thread->stepCallbacks.clear();
|
_thread->stepCallbacks.clear();
|
||||||
for (auto cbStep : cbStepCopy)
|
for (auto cbStep : cbStepCopy)
|
||||||
cbStep();
|
cbStep();
|
||||||
cbStep();
|
|
||||||
}
|
}
|
||||||
else //handle other single step exceptions
|
else //handle other single step exceptions
|
||||||
{
|
{
|
||||||
|
|
@ -39,7 +62,10 @@ namespace GleeBug
|
||||||
_continueStatus = DBG_EXCEPTION_NOT_HANDLED;
|
_continueStatus = DBG_EXCEPTION_NOT_HANDLED;
|
||||||
|
|
||||||
const EXCEPTION_RECORD & exceptionRecord = exceptionInfo.ExceptionRecord;
|
const EXCEPTION_RECORD & exceptionRecord = exceptionInfo.ExceptionRecord;
|
||||||
const bool firstChance = exceptionInfo.dwFirstChance == 1;
|
bool firstChance = exceptionInfo.dwFirstChance == 1;
|
||||||
|
|
||||||
|
//call the debug event callback
|
||||||
|
cbExceptionEvent(exceptionInfo);
|
||||||
|
|
||||||
//dispatch the exception
|
//dispatch the exception
|
||||||
switch (exceptionInfo.ExceptionRecord.ExceptionCode)
|
switch (exceptionInfo.ExceptionRecord.ExceptionCode)
|
||||||
|
|
@ -55,8 +81,5 @@ namespace GleeBug
|
||||||
//call the unhandled exception callback
|
//call the unhandled exception callback
|
||||||
if (_continueStatus == DBG_EXCEPTION_NOT_HANDLED)
|
if (_continueStatus == DBG_EXCEPTION_NOT_HANDLED)
|
||||||
cbUnhandledException(exceptionRecord, firstChance);
|
cbUnhandledException(exceptionRecord, firstChance);
|
||||||
|
|
||||||
//call the debug event callback
|
|
||||||
cbExceptionEvent(exceptionInfo);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
#include "Debugger.Process.h"
|
||||||
|
|
||||||
|
namespace GleeBug
|
||||||
|
{
|
||||||
|
bool ProcessInfo::SetBreakpoint(ptr address, bool singleshoot, SoftwareBreakpointType type)
|
||||||
|
{
|
||||||
|
//check the address
|
||||||
|
if (!MemIsValidPtr(address) ||
|
||||||
|
breakpoints.find({BreakpointType::Software, address}) != breakpoints.end())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
//setup the breakpoint information struct
|
||||||
|
BreakpointInfo info = {};
|
||||||
|
info.address = address;
|
||||||
|
info.enabled = true;
|
||||||
|
info.singleshoot = singleshoot;
|
||||||
|
info.type = BreakpointType::Software;
|
||||||
|
|
||||||
|
//determine breakpoint byte and size from the type
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case SoftwareBreakpointType::ShortInt3:
|
||||||
|
info.internal.software.newbytes[0] = 0xCC;
|
||||||
|
info.internal.software.size = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//read/write the breakpoint
|
||||||
|
if (!MemRead(address, info.internal.software.oldbytes, info.internal.software.size))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!MemWrite(address, info.internal.software.newbytes, info.internal.software.size))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
//insert in the breakpoint map
|
||||||
|
breakpoints.insert({ { info.type, info.address }, info });
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ProcessInfo::SetBreakpoint(ptr address, const BreakpointCallback & cbBreakpoint, bool singleshoot, SoftwareBreakpointType type)
|
||||||
|
{
|
||||||
|
if (!SetBreakpoint(address, singleshoot, type))
|
||||||
|
return false;
|
||||||
|
auto found = breakpointCallbacks.find({ BreakpointType::Software, address });
|
||||||
|
if (found != breakpointCallbacks.end())
|
||||||
|
return false;
|
||||||
|
breakpointCallbacks.insert({ { BreakpointType::Software, address }, cbBreakpoint });
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
#include "Debugger.Process.h"
|
||||||
|
|
||||||
|
namespace GleeBug
|
||||||
|
{
|
||||||
|
bool ProcessInfo::MemRead(ptr address, void* buffer, ptr size) const
|
||||||
|
{
|
||||||
|
return !!ReadProcessMemory(this->hProcess, reinterpret_cast<const void*>(address), buffer, size, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ProcessInfo::MemWrite(ptr address, const void* buffer, ptr size)
|
||||||
|
{
|
||||||
|
return !!WriteProcessMemory(this->hProcess, reinterpret_cast<void*>(address), buffer, size, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ProcessInfo::MemIsValidPtr(ptr address) const
|
||||||
|
{
|
||||||
|
uint8 byte;
|
||||||
|
return MemRead(address, &byte, sizeof(byte));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -9,14 +9,4 @@ namespace GleeBug
|
||||||
this->dwProcessId = dwProcessId;
|
this->dwProcessId = dwProcessId;
|
||||||
this->dwMainThreadId = dwMainThreadId;
|
this->dwMainThreadId = dwMainThreadId;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ProcessInfo::MemRead(ptr address, void* buffer, const size_t size) const
|
|
||||||
{
|
|
||||||
return !!ReadProcessMemory(this->hProcess, reinterpret_cast<const void*>(address), buffer, size, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ProcessInfo::MemWrite(ptr address, const void* buffer, const size_t size) const
|
|
||||||
{
|
|
||||||
return !!WriteProcessMemory(this->hProcess, reinterpret_cast<void*>(address), buffer, size, nullptr);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
#include "Debugger.Global.h"
|
#include "Debugger.Global.h"
|
||||||
#include "Debugger.Thread.h"
|
#include "Debugger.Thread.h"
|
||||||
#include "Debugger.Dll.h"
|
#include "Debugger.Dll.h"
|
||||||
|
#include "Debugger.Breakpoint.h"
|
||||||
|
|
||||||
namespace GleeBug
|
namespace GleeBug
|
||||||
{
|
{
|
||||||
|
|
@ -22,6 +23,8 @@ namespace GleeBug
|
||||||
|
|
||||||
ThreadMap threads;
|
ThreadMap threads;
|
||||||
DllMap dlls;
|
DllMap dlls;
|
||||||
|
BreakpointMap breakpoints;
|
||||||
|
BreakpointCallbackMap breakpointCallbacks;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Constructor.
|
\brief Constructor.
|
||||||
|
|
@ -37,7 +40,7 @@ namespace GleeBug
|
||||||
\param size The size to read.
|
\param size The size to read.
|
||||||
\return true if it succeeds, false if it fails.
|
\return true if it succeeds, false if it fails.
|
||||||
*/
|
*/
|
||||||
bool MemRead(ptr address, void* buffer, const size_t size) const;
|
bool MemRead(ptr address, void* buffer, ptr size) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Write memory to the process.
|
\brief Write memory to the process.
|
||||||
|
|
@ -46,7 +49,50 @@ namespace GleeBug
|
||||||
\param size The size to write.
|
\param size The size to write.
|
||||||
\return true if it succeeds, false if it fails.
|
\return true if it succeeds, false if it fails.
|
||||||
*/
|
*/
|
||||||
bool MemWrite(ptr address, const void* buffer, const size_t size) const;
|
bool MemWrite(ptr address, const void* buffer, ptr size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Check if an address is a valid read pointer.
|
||||||
|
\param address The address to check.
|
||||||
|
\return true if the address is valid, false otherwise.
|
||||||
|
*/
|
||||||
|
bool MemIsValidPtr(ptr address) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Sets a software breakpoint.
|
||||||
|
\param address The address to put the breakpoint on.
|
||||||
|
\param singleshoot (Optional) True to remove the breakpoint after the first hit.
|
||||||
|
\param type (Optional) The software breakpoint type.
|
||||||
|
\return true if the breakpoint was set, false otherwise.
|
||||||
|
*/
|
||||||
|
bool SetBreakpoint(ptr address, bool singleshoot = false, SoftwareBreakpointType type = SoftwareBreakpointType::ShortInt3);
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Sets a software breakpoint.
|
||||||
|
\param address The address to put the breakpoint on.
|
||||||
|
\param cbBreakpoint The breakpoint callback. Can be written using BIND1(this, MyDebugger::cb).
|
||||||
|
\param singleshoot (Optional) True to remove the breakpoint after the first hit.
|
||||||
|
\param type (Optional) The software breakpoint type.
|
||||||
|
\return true if the breakpoint was set, false otherwise.
|
||||||
|
*/
|
||||||
|
bool SetBreakpoint(ptr address, const BreakpointCallback & cbBreakpoint, bool singleshoot = false, SoftwareBreakpointType type = SoftwareBreakpointType::ShortInt3);
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Sets a software breakpoint.
|
||||||
|
\tparam T Generic type parameter. Must be a subclass of Debugger.
|
||||||
|
\param address The address to put the breakpoint on.
|
||||||
|
\param debugger This pointer to a subclass of Debugger.
|
||||||
|
\param callback Pointer to the callback. Written like: &MyDebugger::cb
|
||||||
|
\param singleshoot (Optional) True to remove the breakpoint after the first hit.
|
||||||
|
\param type (Optional) The software breakpoint type.
|
||||||
|
\return true if the breakpoint was set, false otherwise.
|
||||||
|
*/
|
||||||
|
template <typename T>
|
||||||
|
bool SetBreakpoint(ptr address, T* debugger, void(T::*callback)(const BreakpointInfo & info), bool singleshoot = false, SoftwareBreakpointType type = SoftwareBreakpointType::ShortInt3)
|
||||||
|
{
|
||||||
|
static_cast<void>(static_cast<Debugger*>(debugger));
|
||||||
|
return SetBreakpoint(address, std::bind(callback, debugger, std::placeholders::_1), singleshoot, type);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include "Debugger.Global.h"
|
#include "Debugger.Global.h"
|
||||||
#include "Debugger.Process.h"
|
#include "Debugger.Process.h"
|
||||||
|
#include "Debugger.Breakpoint.h"
|
||||||
|
|
||||||
namespace GleeBug
|
namespace GleeBug
|
||||||
{
|
{
|
||||||
|
|
@ -52,55 +53,55 @@ namespace GleeBug
|
||||||
|
|
||||||
protected: //debug event callbacks
|
protected: //debug event callbacks
|
||||||
/**
|
/**
|
||||||
\brief Process creation debug event callback. Provide an implementation to use this callback.
|
\brief Process creation debug event callback. Called after the event is internally processed. Provide an implementation to use this callback.
|
||||||
\param createProcess Information about the process created.
|
\param createProcess Information about the process created.
|
||||||
*/
|
*/
|
||||||
virtual void cbCreateProcessEvent(const CREATE_PROCESS_DEBUG_INFO & createProcess, const ProcessInfo & process) {};
|
virtual void cbCreateProcessEvent(const CREATE_PROCESS_DEBUG_INFO & createProcess, const ProcessInfo & process) {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Process termination debug event callback. Provide an implementation to use this callback.
|
\brief Process termination debug event callback. Called before the event is internally processed. Provide an implementation to use this callback.
|
||||||
\param exitProcess Information about the process terminated.
|
\param exitProcess Information about the process terminated.
|
||||||
*/
|
*/
|
||||||
virtual void cbExitProcessEvent(const EXIT_PROCESS_DEBUG_INFO & exitProcess, const ProcessInfo & process) {};
|
virtual void cbExitProcessEvent(const EXIT_PROCESS_DEBUG_INFO & exitProcess, const ProcessInfo & process) {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Thread creation debug event callback. Provide an implementation to use this callback.
|
\brief Thread creation debug event callback. Called after the event is internally processed. Provide an implementation to use this callback.
|
||||||
\param createThread Information about the thread created.
|
\param createThread Information about the thread created.
|
||||||
*/
|
*/
|
||||||
virtual void cbCreateThreadEvent(const CREATE_THREAD_DEBUG_INFO & createThread, const ThreadInfo & thread) {};
|
virtual void cbCreateThreadEvent(const CREATE_THREAD_DEBUG_INFO & createThread, const ThreadInfo & thread) {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Thread termination debug event callback. Provide an implementation to use this callback.
|
\brief Thread termination debug event callback. Called before the event is internally processed. Provide an implementation to use this callback.
|
||||||
\param exitThread Information about the thread terminated.
|
\param exitThread Information about the thread terminated.
|
||||||
*/
|
*/
|
||||||
virtual void cbExitThreadEvent(const EXIT_THREAD_DEBUG_INFO & exitThread, const ThreadInfo & thread) {};
|
virtual void cbExitThreadEvent(const EXIT_THREAD_DEBUG_INFO & exitThread, const ThreadInfo & thread) {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief DLL load debug event callback. Provide an implementation to use this callback.
|
\brief DLL load debug event callback. Called after event is internally processed. Provide an implementation to use this callback.
|
||||||
\param loadDll Information about the DLL loaded.
|
\param loadDll Information about the DLL loaded.
|
||||||
*/
|
*/
|
||||||
virtual void cbLoadDllEvent(const LOAD_DLL_DEBUG_INFO & loadDll, const DllInfo & dll) {};
|
virtual void cbLoadDllEvent(const LOAD_DLL_DEBUG_INFO & loadDll, const DllInfo & dll) {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief DLL unload debug event callback. Provide an implementation to use this callback.
|
\brief DLL unload debug event callback. Called before event is internally processed. Provide an implementation to use this callback.
|
||||||
\param unloadDll Information about the DLL unloaded.
|
\param unloadDll Information about the DLL unloaded.
|
||||||
*/
|
*/
|
||||||
virtual void cbUnloadDllEvent(const UNLOAD_DLL_DEBUG_INFO & unloadDll, const DllInfo & dll) {};
|
virtual void cbUnloadDllEvent(const UNLOAD_DLL_DEBUG_INFO & unloadDll, const DllInfo & dll) {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Exception debug event callback. Provide an implementation to use this callback.
|
\brief Exception debug event callback. Called before the event is internally processed. Provide an implementation to use this callback.
|
||||||
\param exceptionInfo Information about the exception.
|
\param exceptionInfo Information about the exception.
|
||||||
*/
|
*/
|
||||||
virtual void cbExceptionEvent(const EXCEPTION_DEBUG_INFO & exceptionInfo) {};
|
virtual void cbExceptionEvent(const EXCEPTION_DEBUG_INFO & exceptionInfo) {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Debug string debug event callback. Provide an implementation to use this callback.
|
\brief Debug string debug event callback. Called before the event is internally processed. Provide an implementation to use this callback.
|
||||||
\param debugString Information about the debug string.
|
\param debugString Information about the debug string.
|
||||||
*/
|
*/
|
||||||
virtual void cbDebugStringEvent(const OUTPUT_DEBUG_STRING_INFO & debugString) {};
|
virtual void cbDebugStringEvent(const OUTPUT_DEBUG_STRING_INFO & debugString) {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief RIP debug event callback. Provide an implementation to use this callback.
|
\brief RIP debug event callback. Called before the event is internally processed. Provide an implementation to use this callback.
|
||||||
\param rip Information about the RIP event.
|
\param rip Information about the RIP event.
|
||||||
*/
|
*/
|
||||||
virtual void cbRipEvent(const RIP_INFO & rip) {};
|
virtual void cbRipEvent(const RIP_INFO & rip) {};
|
||||||
|
|
@ -113,22 +114,28 @@ namespace GleeBug
|
||||||
virtual void cbInternalError(const std::string & error) {};
|
virtual void cbInternalError(const std::string & error) {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Unhandled exception callback. Provide an implementation to use this callback.
|
\brief Unhandled exception callback. Called after the exception event is processed. Provide an implementation to use this callback.
|
||||||
\param exceptionRecord The exception record.
|
\param exceptionRecord The exception record.
|
||||||
\param firstChance True if the exception is a first chance exception, false otherwise.
|
\param firstChance True if the exception is a first chance exception, false otherwise.
|
||||||
*/
|
*/
|
||||||
virtual void cbUnhandledException(const EXCEPTION_RECORD & exceptionRecord, const bool firstChance) {};
|
virtual void cbUnhandledException(const EXCEPTION_RECORD & exceptionRecord, bool firstChance) {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief System breakpoint callback. Provide an implementation to use this callback.
|
\brief System breakpoint callback. Called after the event is internally processed. Provide an implementation to use this callback.
|
||||||
*/
|
*/
|
||||||
virtual void cbSystemBreakpoint() {};
|
virtual void cbSystemBreakpoint() {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Step callback. Provide an implementation to use this callback.
|
\brief Step callback. Called before any user callbacks. Provide an implementation to use this callback.
|
||||||
*/
|
*/
|
||||||
virtual void cbStep() {};
|
virtual void cbStep() {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Breakpoint callback. Called before any user callbacks. Provide an implementation to use this callback.
|
||||||
|
\param info The breakpoint information.
|
||||||
|
*/
|
||||||
|
virtual void cbBreakpoint(const BreakpointInfo & info) {}
|
||||||
|
|
||||||
protected: //core debug event handlers
|
protected: //core debug event handlers
|
||||||
/**
|
/**
|
||||||
\brief Process creation debug event. Do not override this unless you know what you are doing!
|
\brief Process creation debug event. Do not override this unless you know what you are doing!
|
||||||
|
|
@ -190,14 +197,14 @@ namespace GleeBug
|
||||||
\param exceptionRecord The exception record.
|
\param exceptionRecord The exception record.
|
||||||
\param firstChance True if the exception is a first chance exception, false otherwise.
|
\param firstChance True if the exception is a first chance exception, false otherwise.
|
||||||
*/
|
*/
|
||||||
virtual void exceptionBreakpoint(const EXCEPTION_RECORD & exceptionRecord, const bool firstChance);
|
virtual void exceptionBreakpoint(const EXCEPTION_RECORD & exceptionRecord, bool firstChance);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Single step exception handler. Do not override this unless you know what you are doing!
|
\brief Single step exception handler. Do not override this unless you know what you are doing!
|
||||||
\param exceptionRecord The exception record.
|
\param exceptionRecord The exception record.
|
||||||
\param firstChance True if the exception is a first chance exception, false otherwise.
|
\param firstChance True if the exception is a first chance exception, false otherwise.
|
||||||
*/
|
*/
|
||||||
virtual void exceptionSingleStep(const EXCEPTION_RECORD & exceptionRecord, const bool firstChance);
|
virtual void exceptionSingleStep(const EXCEPTION_RECORD & exceptionRecord, bool firstChance);
|
||||||
|
|
||||||
protected: //variables
|
protected: //variables
|
||||||
PROCESS_INFORMATION _mainProcess;
|
PROCESS_INFORMATION _mainProcess;
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@
|
||||||
|
|
||||||
//macros
|
//macros
|
||||||
#define BIND(thisPtr, funcPtr) std::bind(&funcPtr, thisPtr)
|
#define BIND(thisPtr, funcPtr) std::bind(&funcPtr, thisPtr)
|
||||||
|
#define BIND1(thisPtr, funcPtr) std::bind(&funcPtr, thisPtr, std::placeholders::_1)
|
||||||
|
|
||||||
namespace GleeBug
|
namespace GleeBug
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -155,12 +155,15 @@
|
||||||
<ClCompile Include="Debugger.Loop.Process.cpp" />
|
<ClCompile Include="Debugger.Loop.Process.cpp" />
|
||||||
<ClCompile Include="Debugger.Loop.Rip.cpp" />
|
<ClCompile Include="Debugger.Loop.Rip.cpp" />
|
||||||
<ClCompile Include="Debugger.Loop.Thread.cpp" />
|
<ClCompile Include="Debugger.Loop.Thread.cpp" />
|
||||||
|
<ClCompile Include="Debugger.Process.Breakpoint.cpp" />
|
||||||
<ClCompile Include="Debugger.Process.cpp" />
|
<ClCompile Include="Debugger.Process.cpp" />
|
||||||
|
<ClCompile Include="Debugger.Process.Memory.cpp" />
|
||||||
<ClCompile Include="Debugger.Thread.cpp" />
|
<ClCompile Include="Debugger.Thread.cpp" />
|
||||||
<ClCompile Include="Debugger.Thread.Registers.cpp" />
|
<ClCompile Include="Debugger.Thread.Registers.cpp" />
|
||||||
<ClCompile Include="Debugger.Thread.Registers.GetSet.cpp" />
|
<ClCompile Include="Debugger.Thread.Registers.GetSet.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClInclude Include="Debugger.Breakpoint.h" />
|
||||||
<ClInclude Include="Debugger.Dll.h" />
|
<ClInclude Include="Debugger.Dll.h" />
|
||||||
<ClInclude Include="Debugger.Process.h" />
|
<ClInclude Include="Debugger.Process.h" />
|
||||||
<ClInclude Include="Debugger.h" />
|
<ClInclude Include="Debugger.h" />
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,12 @@
|
||||||
<ClCompile Include="Debugger.Thread.Registers.GetSet.cpp">
|
<ClCompile Include="Debugger.Thread.Registers.GetSet.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="Debugger.Process.Memory.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Debugger.Process.Breakpoint.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="Debugger.h">
|
<ClInclude Include="Debugger.h">
|
||||||
|
|
@ -79,5 +85,8 @@
|
||||||
<ClInclude Include="Debugger.Thread.Registers.Flag.h">
|
<ClInclude Include="Debugger.Thread.Registers.Flag.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="Debugger.Breakpoint.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
@ -8,11 +8,21 @@ using namespace GleeBug;
|
||||||
class MyDebugger : public Debugger
|
class MyDebugger : public Debugger
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
void myBreakpoint(const BreakpointInfo & info)
|
||||||
|
{
|
||||||
|
puts("myBreakpoint()");
|
||||||
|
}
|
||||||
|
|
||||||
void cbCreateProcessEvent(const CREATE_PROCESS_DEBUG_INFO & createProcess, const ProcessInfo & process) override
|
void cbCreateProcessEvent(const CREATE_PROCESS_DEBUG_INFO & createProcess, const ProcessInfo & process) override
|
||||||
{
|
{
|
||||||
|
ptr entry = ptr(createProcess.lpStartAddress);
|
||||||
printf("Process %d created with entry 0x%p\n",
|
printf("Process %d created with entry 0x%p\n",
|
||||||
_debugEvent.dwProcessId,
|
_debugEvent.dwProcessId,
|
||||||
createProcess.lpStartAddress);
|
entry);
|
||||||
|
if(_process->SetBreakpoint(entry, this, &MyDebugger::myBreakpoint))
|
||||||
|
printf("Breakpoint set at 0x%p!\n", entry);
|
||||||
|
else
|
||||||
|
printf("Failed to set breakpoint at 0x%p...\b", entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cbExitProcessEvent(const EXIT_PROCESS_DEBUG_INFO & exitProcess, const ProcessInfo & process) override
|
void cbExitProcessEvent(const EXIT_PROCESS_DEBUG_INFO & exitProcess, const ProcessInfo & process) override
|
||||||
|
|
@ -50,7 +60,9 @@ protected:
|
||||||
|
|
||||||
void cbExceptionEvent(const EXCEPTION_DEBUG_INFO & exceptionInfo) override
|
void cbExceptionEvent(const EXCEPTION_DEBUG_INFO & exceptionInfo) override
|
||||||
{
|
{
|
||||||
printf("Exception with code 0x%08X at 0x%p\n",
|
const char* exceptionType = exceptionInfo.dwFirstChance ? "First Chance" : "Second Chance";
|
||||||
|
printf("%s exception with code 0x%08X at 0x%p\n",
|
||||||
|
exceptionType,
|
||||||
exceptionInfo.ExceptionRecord.ExceptionCode,
|
exceptionInfo.ExceptionRecord.ExceptionCode,
|
||||||
exceptionInfo.ExceptionRecord.ExceptionAddress);
|
exceptionInfo.ExceptionRecord.ExceptionAddress);
|
||||||
}
|
}
|
||||||
|
|
@ -87,7 +99,7 @@ protected:
|
||||||
{
|
{
|
||||||
printf("System breakpoint reached, CIP: 0x%p\n",
|
printf("System breakpoint reached, CIP: 0x%p\n",
|
||||||
_registers->Gip.Get());
|
_registers->Gip.Get());
|
||||||
_thread->StepInto(BIND(this, MyDebugger::boobs));
|
_thread->StepInto(this, &MyDebugger::boobs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cbInternalError(const std::string & error) override
|
void cbInternalError(const std::string & error) override
|
||||||
|
|
@ -95,6 +107,12 @@ protected:
|
||||||
printf("Internal Error: %s\n",
|
printf("Internal Error: %s\n",
|
||||||
error.c_str());
|
error.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cbBreakpoint(const BreakpointInfo & info) override
|
||||||
|
{
|
||||||
|
printf("Breakpoint on 0x%p!\n",
|
||||||
|
info.address);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //_MYDEBUGGER_H
|
#endif //_MYDEBUGGER_H
|
||||||
Loading…
Reference in New Issue