Merge pull request #12 from GleeBug/dll_housekeeping

Dll housekeeping
This commit is contained in:
mrexodia 2015-03-28 15:23:00 +01:00
commit 7bd8d6c086
20 changed files with 430 additions and 153 deletions

15
GleeBug/Debugger.Dll.cpp Normal file
View File

@ -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;
}
};

24
GleeBug/Debugger.Dll.h Normal file
View File

@ -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

26
GleeBug/Debugger.Global.h Normal file
View File

@ -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

View File

@ -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);
}
};

View File

@ -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);
}
};

View File

@ -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);
}
};

View File

@ -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;
}
};

View File

@ -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);
}
};

View File

@ -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;
}
};

View File

@ -2,97 +2,21 @@
namespace GleeBug 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() void Debugger::Start()
{ {
_continueStatus = DBG_EXCEPTION_NOT_HANDLED; //initialize loop variables
_breakDebugger = false; _breakDebugger = false;
while (!_breakDebugger) while (!_breakDebugger)
{ {
//wait for a debug event
_isRunning = true;
if (!WaitForDebugEvent(&_debugEvent, INFINITE)) if (!WaitForDebugEvent(&_debugEvent, INFINITE))
break; break;
_isRunning = false;
//set default continue status
_continueStatus = DBG_CONTINUE;
//set the current process and thread //set the current process and thread
if (_processes.count(_debugEvent.dwProcessId)) if (_processes.count(_debugEvent.dwProcessId))
@ -106,6 +30,7 @@ namespace GleeBug
else else
_curProcess = nullptr; _curProcess = nullptr;
//dispatch the debug event
switch (_debugEvent.dwDebugEventCode) switch (_debugEvent.dwDebugEventCode)
{ {
case CREATE_PROCESS_DEBUG_EVENT: case CREATE_PROCESS_DEBUG_EVENT:
@ -137,8 +62,13 @@ namespace GleeBug
break; break;
} }
//continue the debug event
if (!ContinueDebugEvent(_debugEvent.dwProcessId, _debugEvent.dwThreadId, _continueStatus)) if (!ContinueDebugEvent(_debugEvent.dwProcessId, _debugEvent.dwThreadId, _continueStatus))
break; break;
} }
//cleanup
_processes.clear();
_curProcess = nullptr;
} }
}; };

View File

@ -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);
}
};

View File

@ -1,8 +1,9 @@
#ifndef _DEBUGGER_PROCESS_H #ifndef _DEBUGGER_PROCESS_H
#define _DEBUGGER_PROCESS_H #define _DEBUGGER_PROCESS_H
#include "_global.h" #include "Debugger.Global.h"
#include "Debugger.Thread.h" #include "Debugger.Thread.h"
#include "Debugger.Dll.h"
namespace GleeBug namespace GleeBug
{ {
@ -12,23 +13,18 @@ namespace GleeBug
struct ProcessInfo struct ProcessInfo
{ {
HANDLE hProcess; HANDLE hProcess;
HANDLE hThread;
DWORD dwProcessId; DWORD dwProcessId;
DWORD dwMainThreadId; DWORD dwMainThreadId;
ThreadMap threads;
ThreadInfo* curThread; 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) ProcessInfo();
{ ProcessInfo(DWORD dwProcessId, DWORD dwMainThreadId);
this->hProcess = hProcess; ~ProcessInfo();
this->hThread = hThread;
this->dwProcessId = dwProcessId;
this->dwMainThreadId = dwMainThreadId;
this->threads.clear();
}
}; };
typedef std::map<DWORD, ProcessInfo> ProcessMap; typedef std::map<DWORD, ProcessInfo> ProcessMap;

View File

@ -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);
}
};

View File

@ -1,7 +1,7 @@
#ifndef _DEBUGGER_THREADS_H #ifndef _DEBUGGER_THREADS_H
#define _DEBUGGER_THREADS_H #define _DEBUGGER_THREADS_H
#include "_global.h" #include "Debugger.Global.h"
namespace GleeBug namespace GleeBug
{ {
@ -15,15 +15,9 @@ namespace GleeBug
ULONG_PTR lpThreadLocalBase; ULONG_PTR lpThreadLocalBase;
ULONG_PTR lpStartAddress; ULONG_PTR lpStartAddress;
ThreadInfo() {} ThreadInfo();
ThreadInfo(DWORD dwThreadId, LPVOID lpThreadLocalBase, LPVOID lpStartAddress);
ThreadInfo(DWORD dwThreadId, HANDLE hThread, LPVOID lpThreadLocalBase, LPVOID lpStartAddress) ~ThreadInfo();
{
this->dwThreadId = dwThreadId;
this->hThread = hThread;
this->lpThreadLocalBase = (ULONG_PTR)lpThreadLocalBase;
this->lpStartAddress = (ULONG_PTR)lpStartAddress;
}
}; };
typedef std::map<DWORD, ThreadInfo> ThreadMap; typedef std::map<DWORD, ThreadInfo> ThreadMap;

View File

@ -1,7 +1,7 @@
#ifndef _DEBUGGER_H #ifndef _DEBUGGER_H
#define _DEBUGGER_H #define _DEBUGGER_H
#include "_global.h" #include "Debugger.Global.h"
#include "Debugger.Process.h" #include "Debugger.Process.h"
namespace GleeBug namespace GleeBug
@ -45,42 +45,42 @@ namespace GleeBug
*/ */
void Start(); void Start();
protected: //callbacks protected: //debug event callbacks
/** /**
\brief Process creation debug event callback. Provide an implementation to use this callback. \brief Process creation debug event callback. 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) {}; 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. 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) {}; 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. 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) {}; 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. 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) {}; 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. 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) {}; 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. 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) {}; 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. Provide an implementation to use this callback.
@ -100,7 +100,20 @@ namespace GleeBug
*/ */
virtual void cbRipEvent(const RIP_INFO & rip) {}; 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! \brief Process creation debug event. Do not override this unless you know what you are doing!
\param createProcess Information about the process created. \param createProcess Information about the process created.
@ -155,6 +168,21 @@ namespace GleeBug
*/ */
virtual void ripEvent(const RIP_INFO & rip); 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 protected: //variables
PROCESS_INFORMATION _mainProcess; PROCESS_INFORMATION _mainProcess;
DWORD _continueStatus; DWORD _continueStatus;
@ -162,6 +190,7 @@ namespace GleeBug
DEBUG_EVENT _debugEvent; DEBUG_EVENT _debugEvent;
ProcessMap _processes; ProcessMap _processes;
ProcessInfo* _curProcess; ProcessInfo* _curProcess;
bool _isRunning;
}; };
}; };

View File

@ -91,6 +91,9 @@
<Link> <Link>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
</Link> </Link>
<Lib>
<AdditionalDependencies>psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile> <ClCompile>
@ -102,6 +105,9 @@
<Link> <Link>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
</Link> </Link>
<Lib>
<AdditionalDependencies>psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile> <ClCompile>
@ -117,6 +123,9 @@
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
</Link> </Link>
<Lib>
<AdditionalDependencies>psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile> <ClCompile>
@ -132,17 +141,29 @@
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
</Link> </Link>
<Lib>
<AdditionalDependencies>psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="Debugger.cpp" /> <ClCompile Include="Debugger.cpp" />
<ClCompile Include="Debugger.Dll.cpp" />
<ClCompile Include="Debugger.Loop.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>
<ItemGroup> <ItemGroup>
<ClInclude Include="Debugger.Dll.h" />
<ClInclude Include="Debugger.Process.h" /> <ClInclude Include="Debugger.Process.h" />
<ClInclude Include="Debugger.h" /> <ClInclude Include="Debugger.h" />
<ClInclude Include="Debugger.Thread.h" /> <ClInclude Include="Debugger.Thread.h" />
<ClInclude Include="_global.h" /> <ClInclude Include="Debugger.Global.h" />
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">

View File

@ -15,20 +15,41 @@
</Filter> </Filter>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="_global.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Debugger.cpp"> <ClCompile Include="Debugger.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="Debugger.Loop.cpp"> <ClCompile Include="Debugger.Loop.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </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>
<ItemGroup> <ItemGroup>
<ClInclude Include="_global.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Debugger.h"> <ClInclude Include="Debugger.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
@ -38,5 +59,11 @@
<ClInclude Include="Debugger.Thread.h"> <ClInclude Include="Debugger.Thread.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Debugger.Dll.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Debugger.Global.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -1 +0,0 @@
#include "_global.h"

View File

@ -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

View File

@ -3,52 +3,44 @@
#include "../GleeBug/Debugger.h" #include "../GleeBug/Debugger.h"
class MyDebugger : public GleeBug::Debugger using namespace GleeBug;
class MyDebugger : public Debugger
{ {
protected: 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); 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); 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); printf("Thread %d created with entry 0x%p\n", _debugEvent.dwThreadId, createThread.lpStartAddress);
}; };
virtual void cbException_single_spep(EXCEPTION_RECORD & except_inf) virtual void cbExitThreadEvent(const EXIT_THREAD_DEBUG_INFO & exitThread, const ThreadInfo & thread)
{
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)
{ {
printf("Thread %d terminated with exit code 0x%08X\n", _debugEvent.dwThreadId, exitThread.dwExitCode); 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); 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); printf("DLL 0x%p unloaded\n", unloadDll.lpBaseOfDll);
}; };
virtual void cbExceptionEvent(const EXCEPTION_DEBUG_INFO & exceptionInfo) 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) 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); printf("RIP event type 0x%X, error 0x%X", rip.dwType, rip.dwError);
}; };
virtual void cbSystemBreakpoint()
{
printf("System breakpoint reached!");
}
}; };
#endif //_MYDEBUGGER_H #endif //_MYDEBUGGER_H