mirror of https://github.com/x64dbg/GleeBug
commit
7bd8d6c086
|
|
@ -0,0 +1,15 @@
|
|||
#include "Debugger.Dll.h"
|
||||
|
||||
namespace GleeBug
|
||||
{
|
||||
DllInfo::DllInfo()
|
||||
{
|
||||
}
|
||||
|
||||
DllInfo::DllInfo(LPVOID lpBaseOfDll, DWORD sizeOfImage, LPVOID entryPoint)
|
||||
{
|
||||
this->lpBaseOfDll = (ULONG_PTR)lpBaseOfDll;
|
||||
this->sizeOfImage = sizeOfImage;
|
||||
this->entryPoint = (ULONG_PTR)entryPoint;
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
#ifndef _DEBUGGER_DLL_H
|
||||
#define _DEBUGGER_DLL_H
|
||||
|
||||
#include "Debugger.Global.h"
|
||||
|
||||
namespace GleeBug
|
||||
{
|
||||
/**
|
||||
\brief DLL information structure.
|
||||
*/
|
||||
struct DllInfo
|
||||
{
|
||||
ULONG_PTR lpBaseOfDll;
|
||||
DWORD sizeOfImage;
|
||||
ULONG_PTR entryPoint;
|
||||
|
||||
DllInfo();
|
||||
DllInfo(LPVOID lpBaseOfDll, DWORD sizeOfImage, LPVOID entryPoint);
|
||||
};
|
||||
|
||||
typedef std::map<Range, DllInfo, RangeCompare> DllMap;
|
||||
};
|
||||
|
||||
#endif //_DEBUGGER_DLL_H
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
#ifndef _DEBUGGER_GLOBAL_H
|
||||
#define _DEBUGGER_GLOBAL_H
|
||||
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <map>
|
||||
|
||||
#include <windows.h>
|
||||
#include <psapi.h>
|
||||
|
||||
namespace GleeBug
|
||||
{
|
||||
typedef std::pair<ULONG_PTR, ULONG_PTR> Range;
|
||||
|
||||
struct RangeCompare
|
||||
{
|
||||
inline bool operator()(const Range & a, const Range & b) const //a before b?
|
||||
{
|
||||
return a.second < b.first;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
#endif //_DEBUGGER_GLOBAL_H
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
#include "Debugger.h"
|
||||
|
||||
namespace GleeBug
|
||||
{
|
||||
void Debugger::debugStringEvent(const OUTPUT_DEBUG_STRING_INFO & debugString)
|
||||
{
|
||||
//prevent anti-debug trick (debug string events are actually exceptions)
|
||||
_continueStatus = DBG_EXCEPTION_NOT_HANDLED;
|
||||
|
||||
//call the debug event callback
|
||||
cbDebugStringEvent(debugString);
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
#include "Debugger.h"
|
||||
|
||||
namespace GleeBug
|
||||
{
|
||||
void Debugger::loadDllEvent(const LOAD_DLL_DEBUG_INFO & loadDll)
|
||||
{
|
||||
//DLL housekeeping
|
||||
MODULEINFO modinfo;
|
||||
memset(&modinfo, 0, sizeof(MODULEINFO));
|
||||
GetModuleInformation(_curProcess->hProcess,
|
||||
(HMODULE)loadDll.lpBaseOfDll,
|
||||
&modinfo,
|
||||
sizeof(MODULEINFO));
|
||||
DllInfo dll(loadDll.lpBaseOfDll, modinfo.SizeOfImage, modinfo.EntryPoint);
|
||||
_curProcess->dlls.insert({ Range(dll.lpBaseOfDll, dll.lpBaseOfDll + dll.sizeOfImage - 1), dll });
|
||||
|
||||
//call the debug event callback
|
||||
cbLoadDllEvent(loadDll, dll);
|
||||
|
||||
//close the file handle
|
||||
CloseHandle(loadDll.hFile);
|
||||
}
|
||||
|
||||
void Debugger::unloadDllEvent(const UNLOAD_DLL_DEBUG_INFO & unloadDll)
|
||||
{
|
||||
//call the debug event callback
|
||||
ULONG_PTR lpBaseOfDll = (ULONG_PTR)unloadDll.lpBaseOfDll;
|
||||
auto dll = _curProcess->dlls.find(Range(lpBaseOfDll, lpBaseOfDll));
|
||||
if (dll != _curProcess->dlls.end())
|
||||
cbUnloadDllEvent(unloadDll, dll->second);
|
||||
else
|
||||
cbUnloadDllEvent(unloadDll, DllInfo(unloadDll.lpBaseOfDll, 0, 0));
|
||||
|
||||
//DLL housekeeping
|
||||
if (dll != _curProcess->dlls.end())
|
||||
_curProcess->dlls.erase(dll);
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
#include "Debugger.h"
|
||||
|
||||
namespace GleeBug
|
||||
{
|
||||
void Debugger::exceptionBreakpoint(const EXCEPTION_RECORD & exceptionRecord, const bool firstChance)
|
||||
{
|
||||
if (!_curProcess->systemBreakpoint) //handle system breakpoint
|
||||
{
|
||||
_curProcess->systemBreakpoint = true;
|
||||
_continueStatus = DBG_CONTINUE;
|
||||
|
||||
//call the callback
|
||||
cbSystemBreakpoint();
|
||||
}
|
||||
else //handle other breakpoint exceptions
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
void Debugger::exceptionSingleStep(const EXCEPTION_RECORD & exceptionRecord, const bool firstChance)
|
||||
{
|
||||
}
|
||||
|
||||
void Debugger::exceptionEvent(const EXCEPTION_DEBUG_INFO & exceptionInfo)
|
||||
{
|
||||
//let the debuggee handle exceptions per default
|
||||
_continueStatus = DBG_EXCEPTION_NOT_HANDLED;
|
||||
|
||||
const EXCEPTION_RECORD & exceptionRecord = exceptionInfo.ExceptionRecord;
|
||||
const bool firstChance = exceptionInfo.dwFirstChance == 1;
|
||||
|
||||
//dispatch the exception
|
||||
switch (exceptionInfo.ExceptionRecord.ExceptionCode)
|
||||
{
|
||||
case STATUS_BREAKPOINT:
|
||||
exceptionBreakpoint(exceptionRecord, firstChance);
|
||||
break;
|
||||
case STATUS_SINGLE_STEP:
|
||||
exceptionSingleStep(exceptionRecord, firstChance);
|
||||
break;
|
||||
}
|
||||
|
||||
//call the unhandled exception callback
|
||||
if (_continueStatus == DBG_EXCEPTION_NOT_HANDLED)
|
||||
cbUnhandledException(exceptionRecord, firstChance);
|
||||
|
||||
//call the debug event callback
|
||||
cbExceptionEvent(exceptionInfo);
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
#include "Debugger.h"
|
||||
|
||||
namespace GleeBug
|
||||
{
|
||||
void Debugger::createProcessEvent(const CREATE_PROCESS_DEBUG_INFO & createProcess)
|
||||
{
|
||||
//process housekeeping
|
||||
ProcessInfo process(_debugEvent.dwProcessId,
|
||||
_debugEvent.dwThreadId);
|
||||
_processes.insert({ process.dwProcessId, process });
|
||||
|
||||
//set the current process and current thread
|
||||
_curProcess = &_processes[process.dwProcessId];
|
||||
_curProcess->curThread = &_curProcess->threads[process.dwMainThreadId];
|
||||
|
||||
//call the debug event callback
|
||||
cbCreateProcessEvent(createProcess, *_curProcess);
|
||||
|
||||
//close the file handle
|
||||
CloseHandle(createProcess.hFile);
|
||||
}
|
||||
|
||||
void Debugger::exitProcessEvent(const EXIT_PROCESS_DEBUG_INFO & exitProcess)
|
||||
{
|
||||
//check if the terminated process is the main debuggee
|
||||
if (_debugEvent.dwProcessId == _mainProcess.dwProcessId)
|
||||
_breakDebugger = true;
|
||||
|
||||
//call the debug event callback
|
||||
cbExitProcessEvent(exitProcess, *_curProcess);
|
||||
|
||||
//process housekeeping
|
||||
_processes.erase(_debugEvent.dwProcessId);
|
||||
|
||||
//set the current process
|
||||
_curProcess = nullptr;
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
#include "Debugger.h"
|
||||
|
||||
namespace GleeBug
|
||||
{
|
||||
void Debugger::ripEvent(const RIP_INFO & rip)
|
||||
{
|
||||
//prevent anti-debug trick (RIP events are actually exceptions)
|
||||
_continueStatus = DBG_EXCEPTION_NOT_HANDLED;
|
||||
|
||||
//call the debug event callback
|
||||
cbRipEvent(rip);
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
#include "Debugger.h"
|
||||
|
||||
namespace GleeBug
|
||||
{
|
||||
void Debugger::createThreadEvent(const CREATE_THREAD_DEBUG_INFO & createThread)
|
||||
{
|
||||
//thread housekeeping
|
||||
ThreadInfo thread(_debugEvent.dwThreadId, createThread.lpThreadLocalBase, createThread.lpStartAddress);
|
||||
_curProcess->threads.insert({ thread.dwThreadId, thread });
|
||||
|
||||
//set the current thread
|
||||
_curProcess->curThread = &_curProcess->threads[thread.dwThreadId];
|
||||
|
||||
//call the debug event callback
|
||||
cbCreateThreadEvent(createThread, *_curProcess->curThread);
|
||||
}
|
||||
|
||||
void Debugger::exitThreadEvent(const EXIT_THREAD_DEBUG_INFO & exitThread)
|
||||
{
|
||||
//call the debug event callback
|
||||
cbExitThreadEvent(exitThread, *_curProcess->curThread);
|
||||
|
||||
//thread housekeeping
|
||||
_curProcess->threads.erase(_debugEvent.dwThreadId);
|
||||
|
||||
//set the current thread
|
||||
_curProcess->curThread = nullptr;
|
||||
}
|
||||
};
|
||||
|
|
@ -2,97 +2,21 @@
|
|||
|
||||
namespace GleeBug
|
||||
{
|
||||
void Debugger::createProcessEvent(const CREATE_PROCESS_DEBUG_INFO & createProcess)
|
||||
{
|
||||
//process housekeeping
|
||||
ProcessInfo process(createProcess.hProcess,
|
||||
createProcess.hThread,
|
||||
_debugEvent.dwProcessId,
|
||||
_debugEvent.dwThreadId);
|
||||
_processes.insert({ process.dwProcessId, process });
|
||||
|
||||
//set the current process and current thread
|
||||
_curProcess = &_processes[process.dwProcessId];
|
||||
_curProcess->curThread = &_curProcess->threads[process.dwMainThreadId];
|
||||
|
||||
//call the callback
|
||||
cbCreateProcessEvent(createProcess);
|
||||
}
|
||||
|
||||
void Debugger::exitProcessEvent(const EXIT_PROCESS_DEBUG_INFO & exitProcess)
|
||||
{
|
||||
//check if the terminated process is the main debuggee
|
||||
if (_debugEvent.dwProcessId == _mainProcess.dwProcessId)
|
||||
_breakDebugger = true;
|
||||
|
||||
//call the callback
|
||||
cbExitProcessEvent(exitProcess);
|
||||
|
||||
//process housekeeping
|
||||
_processes.erase(_debugEvent.dwProcessId);
|
||||
|
||||
//set the current process
|
||||
_curProcess = nullptr;
|
||||
}
|
||||
|
||||
void Debugger::createThreadEvent(const CREATE_THREAD_DEBUG_INFO & createThread)
|
||||
{
|
||||
//thread housekeeping
|
||||
ThreadInfo thread(_debugEvent.dwThreadId, createThread.hThread, createThread.lpThreadLocalBase, createThread.lpStartAddress);
|
||||
_curProcess->threads.insert({ thread.dwThreadId, thread });
|
||||
|
||||
//set the current thread
|
||||
_curProcess->curThread = &_curProcess->threads[thread.dwThreadId];
|
||||
|
||||
//call the callback
|
||||
cbCreateThreadEvent(createThread);
|
||||
}
|
||||
|
||||
void Debugger::exitThreadEvent(const EXIT_THREAD_DEBUG_INFO & exitThread)
|
||||
{
|
||||
//call the callback
|
||||
cbExitThreadEvent(exitThread);
|
||||
|
||||
//thread housekeeping
|
||||
_curProcess->threads.erase(_debugEvent.dwThreadId);
|
||||
|
||||
//set the current thread
|
||||
_curProcess->curThread = nullptr;
|
||||
}
|
||||
|
||||
void Debugger::loadDllEvent(const LOAD_DLL_DEBUG_INFO & loadDll)
|
||||
{
|
||||
cbLoadDllEvent(loadDll);
|
||||
}
|
||||
|
||||
void Debugger::unloadDllEvent(const UNLOAD_DLL_DEBUG_INFO & unloadDll)
|
||||
{
|
||||
cbUnloadDllEvent(unloadDll);
|
||||
}
|
||||
|
||||
void Debugger::exceptionEvent(const EXCEPTION_DEBUG_INFO & exceptionInfo)
|
||||
{
|
||||
cbExceptionEvent(exceptionInfo);
|
||||
}
|
||||
|
||||
void Debugger::debugStringEvent(const OUTPUT_DEBUG_STRING_INFO & debugString)
|
||||
{
|
||||
cbDebugStringEvent(debugString);
|
||||
}
|
||||
|
||||
void Debugger::ripEvent(const RIP_INFO & rip)
|
||||
{
|
||||
cbRipEvent(rip);
|
||||
}
|
||||
|
||||
void Debugger::Start()
|
||||
{
|
||||
_continueStatus = DBG_EXCEPTION_NOT_HANDLED;
|
||||
//initialize loop variables
|
||||
_breakDebugger = false;
|
||||
|
||||
while (!_breakDebugger)
|
||||
{
|
||||
//wait for a debug event
|
||||
_isRunning = true;
|
||||
if (!WaitForDebugEvent(&_debugEvent, INFINITE))
|
||||
break;
|
||||
_isRunning = false;
|
||||
|
||||
//set default continue status
|
||||
_continueStatus = DBG_CONTINUE;
|
||||
|
||||
//set the current process and thread
|
||||
if (_processes.count(_debugEvent.dwProcessId))
|
||||
|
|
@ -106,6 +30,7 @@ namespace GleeBug
|
|||
else
|
||||
_curProcess = nullptr;
|
||||
|
||||
//dispatch the debug event
|
||||
switch (_debugEvent.dwDebugEventCode)
|
||||
{
|
||||
case CREATE_PROCESS_DEBUG_EVENT:
|
||||
|
|
@ -137,8 +62,13 @@ namespace GleeBug
|
|||
break;
|
||||
}
|
||||
|
||||
//continue the debug event
|
||||
if (!ContinueDebugEvent(_debugEvent.dwProcessId, _debugEvent.dwThreadId, _continueStatus))
|
||||
break;
|
||||
}
|
||||
|
||||
//cleanup
|
||||
_processes.clear();
|
||||
_curProcess = nullptr;
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
#include "Debugger.Process.h"
|
||||
|
||||
namespace GleeBug
|
||||
{
|
||||
ProcessInfo::ProcessInfo()
|
||||
{
|
||||
this->curThread = nullptr;
|
||||
this->systemBreakpoint = false;
|
||||
this->hProcess = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
ProcessInfo::ProcessInfo(DWORD dwProcessId, DWORD dwMainThreadId)
|
||||
{
|
||||
this->systemBreakpoint = false;
|
||||
this->hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
|
||||
this->dwProcessId = dwProcessId;
|
||||
this->dwMainThreadId = dwMainThreadId;
|
||||
this->threads.clear();
|
||||
}
|
||||
|
||||
ProcessInfo::~ProcessInfo()
|
||||
{
|
||||
if (this->hProcess != INVALID_HANDLE_VALUE)
|
||||
CloseHandle(hProcess);
|
||||
}
|
||||
};
|
||||
|
|
@ -1,8 +1,9 @@
|
|||
#ifndef _DEBUGGER_PROCESS_H
|
||||
#define _DEBUGGER_PROCESS_H
|
||||
|
||||
#include "_global.h"
|
||||
#include "Debugger.Global.h"
|
||||
#include "Debugger.Thread.h"
|
||||
#include "Debugger.Dll.h"
|
||||
|
||||
namespace GleeBug
|
||||
{
|
||||
|
|
@ -12,23 +13,18 @@ namespace GleeBug
|
|||
struct ProcessInfo
|
||||
{
|
||||
HANDLE hProcess;
|
||||
HANDLE hThread;
|
||||
DWORD dwProcessId;
|
||||
DWORD dwMainThreadId;
|
||||
|
||||
ThreadMap threads;
|
||||
ThreadInfo* curThread;
|
||||
bool systemBreakpoint;
|
||||
|
||||
ProcessInfo() {} //fixes a 'no default constructor available' error
|
||||
ThreadMap threads;
|
||||
DllMap dlls;
|
||||
|
||||
ProcessInfo(HANDLE hProcess, HANDLE hThread, DWORD dwProcessId, DWORD dwMainThreadId)
|
||||
{
|
||||
this->hProcess = hProcess;
|
||||
this->hThread = hThread;
|
||||
this->dwProcessId = dwProcessId;
|
||||
this->dwMainThreadId = dwMainThreadId;
|
||||
this->threads.clear();
|
||||
}
|
||||
ProcessInfo();
|
||||
ProcessInfo(DWORD dwProcessId, DWORD dwMainThreadId);
|
||||
~ProcessInfo();
|
||||
};
|
||||
|
||||
typedef std::map<DWORD, ProcessInfo> ProcessMap;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
#include "Debugger.Thread.h"
|
||||
|
||||
namespace GleeBug
|
||||
{
|
||||
ThreadInfo::ThreadInfo()
|
||||
{
|
||||
this->hThread = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
ThreadInfo::ThreadInfo(DWORD dwThreadId, LPVOID lpThreadLocalBase, LPVOID lpStartAddress)
|
||||
{
|
||||
this->dwThreadId = dwThreadId;
|
||||
this->hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, dwThreadId);
|
||||
this->lpThreadLocalBase = (ULONG_PTR)lpThreadLocalBase;
|
||||
this->lpStartAddress = (ULONG_PTR)lpStartAddress;
|
||||
}
|
||||
|
||||
ThreadInfo::~ThreadInfo()
|
||||
{
|
||||
if (this->hThread != INVALID_HANDLE_VALUE)
|
||||
CloseHandle(hThread);
|
||||
}
|
||||
};
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef _DEBUGGER_THREADS_H
|
||||
#define _DEBUGGER_THREADS_H
|
||||
|
||||
#include "_global.h"
|
||||
#include "Debugger.Global.h"
|
||||
|
||||
namespace GleeBug
|
||||
{
|
||||
|
|
@ -15,15 +15,9 @@ namespace GleeBug
|
|||
ULONG_PTR lpThreadLocalBase;
|
||||
ULONG_PTR lpStartAddress;
|
||||
|
||||
ThreadInfo() {}
|
||||
|
||||
ThreadInfo(DWORD dwThreadId, HANDLE hThread, LPVOID lpThreadLocalBase, LPVOID lpStartAddress)
|
||||
{
|
||||
this->dwThreadId = dwThreadId;
|
||||
this->hThread = hThread;
|
||||
this->lpThreadLocalBase = (ULONG_PTR)lpThreadLocalBase;
|
||||
this->lpStartAddress = (ULONG_PTR)lpStartAddress;
|
||||
}
|
||||
ThreadInfo();
|
||||
ThreadInfo(DWORD dwThreadId, LPVOID lpThreadLocalBase, LPVOID lpStartAddress);
|
||||
~ThreadInfo();
|
||||
};
|
||||
|
||||
typedef std::map<DWORD, ThreadInfo> ThreadMap;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef _DEBUGGER_H
|
||||
#define _DEBUGGER_H
|
||||
|
||||
#include "_global.h"
|
||||
#include "Debugger.Global.h"
|
||||
#include "Debugger.Process.h"
|
||||
|
||||
namespace GleeBug
|
||||
|
|
@ -45,42 +45,42 @@ namespace GleeBug
|
|||
*/
|
||||
void Start();
|
||||
|
||||
protected: //callbacks
|
||||
protected: //debug event callbacks
|
||||
/**
|
||||
\brief Process creation debug event callback. Provide an implementation to use this callback.
|
||||
\param createProcess Information about the process created.
|
||||
*/
|
||||
virtual void cbCreateProcessEvent(const CREATE_PROCESS_DEBUG_INFO & createProcess) {};
|
||||
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.
|
||||
\param exitProcess Information about the process terminated.
|
||||
*/
|
||||
virtual void cbExitProcessEvent(const EXIT_PROCESS_DEBUG_INFO & exitProcess) {};
|
||||
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.
|
||||
\param createThread Information about the thread created.
|
||||
*/
|
||||
virtual void cbCreateThreadEvent(const CREATE_THREAD_DEBUG_INFO & createThread) {};
|
||||
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.
|
||||
\param exitThread Information about the thread terminated.
|
||||
*/
|
||||
virtual void cbExitThreadEvent(const EXIT_THREAD_DEBUG_INFO & exitThread) {};
|
||||
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.
|
||||
\param loadDll Information about the DLL loaded.
|
||||
*/
|
||||
virtual void cbLoadDllEvent(const LOAD_DLL_DEBUG_INFO & loadDll) {};
|
||||
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.
|
||||
\param unloadDll Information about the DLL unloaded.
|
||||
*/
|
||||
virtual void cbUnloadDllEvent(const UNLOAD_DLL_DEBUG_INFO & unloadDll) {};
|
||||
virtual void cbUnloadDllEvent(const UNLOAD_DLL_DEBUG_INFO & unloadDll, const DllInfo & dll) {};
|
||||
|
||||
/**
|
||||
\brief Exception debug event callback. Provide an implementation to use this callback.
|
||||
|
|
@ -100,7 +100,20 @@ namespace GleeBug
|
|||
*/
|
||||
virtual void cbRipEvent(const RIP_INFO & rip) {};
|
||||
|
||||
protected: //core functionality
|
||||
protected: //other callbacks
|
||||
/**
|
||||
\brief Unhandled exception callback. Provide an implementation to use this callback.
|
||||
\param exceptionRecord The exception record.
|
||||
\param firstChance True if the exception is a first chance exception, false otherwise.
|
||||
*/
|
||||
virtual void cbUnhandledException(const EXCEPTION_RECORD & exceptionRecord, const bool firstChance) {};
|
||||
|
||||
/**
|
||||
\brief System breakpoint callback. Provide an implementation to use this callback.
|
||||
*/
|
||||
virtual void cbSystemBreakpoint() {};
|
||||
|
||||
protected: //core debug event handlers
|
||||
/**
|
||||
\brief Process creation debug event. Do not override this unless you know what you are doing!
|
||||
\param createProcess Information about the process created.
|
||||
|
|
@ -155,6 +168,21 @@ namespace GleeBug
|
|||
*/
|
||||
virtual void ripEvent(const RIP_INFO & rip);
|
||||
|
||||
protected: //core exception handlers
|
||||
/**
|
||||
\brief Breakpoint exception handler. Do not override this unless you know what you are doing!
|
||||
\param exceptionRecord The exception record.
|
||||
\param firstChance True if the exception is a first chance exception, false otherwise.
|
||||
*/
|
||||
virtual void exceptionBreakpoint(const EXCEPTION_RECORD & exceptionRecord, const bool firstChance);
|
||||
|
||||
/**
|
||||
\brief Single step exception handler. Do not override this unless you know what you are doing!
|
||||
\param exceptionRecord The exception record.
|
||||
\param firstChance True if the exception is a first chance exception, false otherwise.
|
||||
*/
|
||||
virtual void exceptionSingleStep(const EXCEPTION_RECORD & exceptionRecord, const bool firstChance);
|
||||
|
||||
protected: //variables
|
||||
PROCESS_INFORMATION _mainProcess;
|
||||
DWORD _continueStatus;
|
||||
|
|
@ -162,6 +190,7 @@ namespace GleeBug
|
|||
DEBUG_EVENT _debugEvent;
|
||||
ProcessMap _processes;
|
||||
ProcessInfo* _curProcess;
|
||||
bool _isRunning;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -91,6 +91,9 @@
|
|||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
<Lib>
|
||||
<AdditionalDependencies>psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
|
|
@ -102,6 +105,9 @@
|
|||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
<Lib>
|
||||
<AdditionalDependencies>psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
|
|
@ -117,6 +123,9 @@
|
|||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
<Lib>
|
||||
<AdditionalDependencies>psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
|
|
@ -132,17 +141,29 @@
|
|||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
<Lib>
|
||||
<AdditionalDependencies>psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Debugger.cpp" />
|
||||
<ClCompile Include="Debugger.Dll.cpp" />
|
||||
<ClCompile Include="Debugger.Loop.cpp" />
|
||||
<ClCompile Include="_global.cpp" />
|
||||
<ClCompile Include="Debugger.Loop.DebugString.cpp" />
|
||||
<ClCompile Include="Debugger.Loop.Dll.cpp" />
|
||||
<ClCompile Include="Debugger.Loop.Exception.cpp" />
|
||||
<ClCompile Include="Debugger.Loop.Process.cpp" />
|
||||
<ClCompile Include="Debugger.Loop.Rip.cpp" />
|
||||
<ClCompile Include="Debugger.Loop.Thread.cpp" />
|
||||
<ClCompile Include="Debugger.Process.cpp" />
|
||||
<ClCompile Include="Debugger.Thread.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Debugger.Dll.h" />
|
||||
<ClInclude Include="Debugger.Process.h" />
|
||||
<ClInclude Include="Debugger.h" />
|
||||
<ClInclude Include="Debugger.Thread.h" />
|
||||
<ClInclude Include="_global.h" />
|
||||
<ClInclude Include="Debugger.Global.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
|
|
|
|||
|
|
@ -15,20 +15,41 @@
|
|||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="_global.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Debugger.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Debugger.Loop.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Debugger.Thread.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Debugger.Process.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Debugger.Dll.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Debugger.Loop.Dll.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Debugger.Loop.Exception.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Debugger.Loop.Process.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Debugger.Loop.Thread.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Debugger.Loop.DebugString.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Debugger.Loop.Rip.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="_global.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Debugger.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
|
|
@ -38,5 +59,11 @@
|
|||
<ClInclude Include="Debugger.Thread.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Debugger.Dll.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Debugger.Global.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
@ -1 +0,0 @@
|
|||
#include "_global.h"
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
#ifndef _GLOBAL_H
|
||||
#define _GLOBAL_H
|
||||
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <map>
|
||||
#include <windows.h>
|
||||
|
||||
#endif //_GLOBAL_H
|
||||
|
|
@ -3,52 +3,44 @@
|
|||
|
||||
#include "../GleeBug/Debugger.h"
|
||||
|
||||
class MyDebugger : public GleeBug::Debugger
|
||||
using namespace GleeBug;
|
||||
|
||||
class MyDebugger : public Debugger
|
||||
{
|
||||
protected:
|
||||
virtual void cbCreateProcessEvent(const CREATE_PROCESS_DEBUG_INFO & createProcess)
|
||||
virtual void cbCreateProcessEvent(const CREATE_PROCESS_DEBUG_INFO & createProcess, const ProcessInfo & process)
|
||||
{
|
||||
printf("Process %d created with entry 0x%p\n", _debugEvent.dwProcessId, createProcess.lpStartAddress);
|
||||
};
|
||||
|
||||
virtual void cbExitProcessEvent(const EXIT_PROCESS_DEBUG_INFO & exitProcess)
|
||||
virtual void cbExitProcessEvent(const EXIT_PROCESS_DEBUG_INFO & exitProcess, const ProcessInfo & process)
|
||||
{
|
||||
printf("Process %d terminated with exit code 0x%08X\n", _debugEvent.dwProcessId, exitProcess.dwExitCode);
|
||||
}
|
||||
|
||||
virtual void cbCreateThreadEvent(const CREATE_THREAD_DEBUG_INFO & createThread)
|
||||
virtual void cbCreateThreadEvent(const CREATE_THREAD_DEBUG_INFO & createThread, const ThreadInfo & thread)
|
||||
{
|
||||
printf("Thread %d created with entry 0x%p\n", _debugEvent.dwThreadId, createThread.lpStartAddress);
|
||||
};
|
||||
|
||||
virtual void cbException_single_spep(EXCEPTION_RECORD & except_inf)
|
||||
{
|
||||
printf("a single step occurred at location 0x%X", except_inf.ExceptionAddress);
|
||||
};
|
||||
|
||||
virtual void cbExcpetion_breakpoint(EXCEPTION_RECORD & except_inf)
|
||||
{
|
||||
printf("a breakpoint occurred at location 0x%X", except_inf.ExceptionAddress);
|
||||
};
|
||||
|
||||
virtual void cbExitThreadEvent(const EXIT_THREAD_DEBUG_INFO & exitThread)
|
||||
virtual void cbExitThreadEvent(const EXIT_THREAD_DEBUG_INFO & exitThread, const ThreadInfo & thread)
|
||||
{
|
||||
printf("Thread %d terminated with exit code 0x%08X\n", _debugEvent.dwThreadId, exitThread.dwExitCode);
|
||||
};
|
||||
|
||||
virtual void cbLoadDllEvent(const LOAD_DLL_DEBUG_INFO & loadDll)
|
||||
virtual void cbLoadDllEvent(const LOAD_DLL_DEBUG_INFO & loadDll, const DllInfo & dll)
|
||||
{
|
||||
printf("DLL loaded at 0x%p\n", loadDll.lpBaseOfDll);
|
||||
};
|
||||
|
||||
virtual void cbUnloadDllEvent(const UNLOAD_DLL_DEBUG_INFO & unloadDll)
|
||||
virtual void cbUnloadDllEvent(const UNLOAD_DLL_DEBUG_INFO & unloadDll, const DllInfo & dll)
|
||||
{
|
||||
printf("DLL 0x%p unloaded\n", unloadDll.lpBaseOfDll);
|
||||
};
|
||||
|
||||
virtual void cbExceptionEvent(const EXCEPTION_DEBUG_INFO & exceptionInfo)
|
||||
{
|
||||
printf("Exception with code 0x%08X\n", exceptionInfo.ExceptionRecord);
|
||||
printf("Exception with code 0x%08X\n", exceptionInfo.ExceptionRecord.ExceptionCode);
|
||||
};
|
||||
|
||||
virtual void cbDebugStringEvent(const OUTPUT_DEBUG_STRING_INFO & debugString)
|
||||
|
|
@ -60,6 +52,11 @@ protected:
|
|||
{
|
||||
printf("RIP event type 0x%X, error 0x%X", rip.dwType, rip.dwError);
|
||||
};
|
||||
|
||||
virtual void cbSystemBreakpoint()
|
||||
{
|
||||
printf("System breakpoint reached!");
|
||||
}
|
||||
};
|
||||
|
||||
#endif //_MYDEBUGGER_H
|
||||
Loading…
Reference in New Issue