diff --git a/GleeBug/Debugger.Loop.cpp b/GleeBug/Debugger.Loop.cpp index e18f8fa..b7c4668 100644 --- a/GleeBug/Debugger.Loop.cpp +++ b/GleeBug/Debugger.Loop.cpp @@ -2,20 +2,24 @@ namespace GleeBug { - void Debugger::createProcessEvent(CREATE_PROCESS_DEBUG_INFO* createProcess) + void Debugger::createProcessEvent(const CREATE_PROCESS_DEBUG_INFO & createProcess) { //process housekeeping - ProcessInfo process(createProcess->hProcess, - createProcess->hThread, + 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(EXIT_PROCESS_DEBUG_INFO* exitProcess) + void Debugger::exitProcessEvent(const EXIT_PROCESS_DEBUG_INFO & exitProcess) { //check if the terminated process is the main debuggee if (_debugEvent.dwProcessId == _mainProcess.dwProcessId) @@ -28,17 +32,20 @@ namespace GleeBug _processes.erase(_debugEvent.dwProcessId); } - void Debugger::createThreadEvent(CREATE_THREAD_DEBUG_INFO* createThread) + void Debugger::createThreadEvent(const CREATE_THREAD_DEBUG_INFO & createThread) { //thread housekeeping - ThreadInfo thread(_debugEvent.dwThreadId, createThread->hThread, createThread->lpThreadLocalBase, createThread->lpStartAddress); - _processes[_debugEvent.dwProcessId].threads.insert({ thread.dwThreadId, thread }); + 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(EXIT_THREAD_DEBUG_INFO* exitThread) + void Debugger::exitThreadEvent(const EXIT_THREAD_DEBUG_INFO & exitThread) { //call the callback cbExitThreadEvent(exitThread); @@ -47,37 +54,27 @@ namespace GleeBug _processes[_debugEvent.dwProcessId].threads.erase(_debugEvent.dwThreadId); } - void Debugger::loadDllEvent(LOAD_DLL_DEBUG_INFO* loadDll) + void Debugger::loadDllEvent(const LOAD_DLL_DEBUG_INFO & loadDll) { cbLoadDllEvent(loadDll); } - void Debugger::unloadDllEvent(UNLOAD_DLL_DEBUG_INFO* unloadDll) + void Debugger::unloadDllEvent(const UNLOAD_DLL_DEBUG_INFO & unloadDll) { cbUnloadDllEvent(unloadDll); } - void Debugger::exceptionEvent(EXCEPTION_DEBUG_INFO* exceptionInfo) + void Debugger::exceptionEvent(const EXCEPTION_DEBUG_INFO & exceptionInfo) { - switch (exceptionInfo->ExceptionRecord.ExceptionCode){ - case EXCEPTION_SINGLE_STEP: - cbException_single_spep(&exceptionInfo->ExceptionRecord); - break; - case EXCEPTION_BREAKPOINT: - cbExcpetion_breakpoint(&exceptionInfo->ExceptionRecord); - break; - default: - cbExceptionEvent(exceptionInfo); - break; - } + cbExceptionEvent(exceptionInfo); } - void Debugger::debugStringEvent(OUTPUT_DEBUG_STRING_INFO* debugString) + void Debugger::debugStringEvent(const OUTPUT_DEBUG_STRING_INFO & debugString) { cbDebugStringEvent(debugString); } - void Debugger::ripEvent(RIP_INFO* rip) + void Debugger::ripEvent(const RIP_INFO & rip) { cbRipEvent(rip); } @@ -91,34 +88,46 @@ namespace GleeBug if (!WaitForDebugEvent(&_debugEvent, INFINITE)) break; + //set the current process and thread + if (_processes.count(_debugEvent.dwProcessId)) + { + _curProcess = &_processes[_debugEvent.dwProcessId]; + if (_curProcess->threads.count(_debugEvent.dwThreadId)) + _curProcess->curThread = &_curProcess->threads[_debugEvent.dwThreadId]; + else + _curProcess->curThread = nullptr; + } + else + _curProcess = nullptr; + switch (_debugEvent.dwDebugEventCode) { case CREATE_PROCESS_DEBUG_EVENT: - createProcessEvent(&_debugEvent.u.CreateProcessInfo); + createProcessEvent(_debugEvent.u.CreateProcessInfo); break; case EXIT_PROCESS_DEBUG_EVENT: - exitProcessEvent(&_debugEvent.u.ExitProcess); + exitProcessEvent(_debugEvent.u.ExitProcess); break; case CREATE_THREAD_DEBUG_EVENT: - createThreadEvent(&_debugEvent.u.CreateThread); + createThreadEvent(_debugEvent.u.CreateThread); break; case EXIT_THREAD_DEBUG_EVENT: - exitThreadEvent(&_debugEvent.u.ExitThread); + exitThreadEvent(_debugEvent.u.ExitThread); break; case LOAD_DLL_DEBUG_EVENT: - loadDllEvent(&_debugEvent.u.LoadDll); + loadDllEvent(_debugEvent.u.LoadDll); break; case UNLOAD_DLL_DEBUG_EVENT: - unloadDllEvent(&_debugEvent.u.UnloadDll); + unloadDllEvent(_debugEvent.u.UnloadDll); break; case EXCEPTION_DEBUG_EVENT: - exceptionEvent(&_debugEvent.u.Exception); + exceptionEvent(_debugEvent.u.Exception); break; case OUTPUT_DEBUG_STRING_EVENT: - debugStringEvent(&_debugEvent.u.DebugString); + debugStringEvent(_debugEvent.u.DebugString); break; case RIP_EVENT: - ripEvent(&_debugEvent.u.RipInfo); + ripEvent(_debugEvent.u.RipInfo); break; } diff --git a/GleeBug/Debugger.Process.h b/GleeBug/Debugger.Process.h index e92b008..fb6f151 100644 --- a/GleeBug/Debugger.Process.h +++ b/GleeBug/Debugger.Process.h @@ -17,6 +17,7 @@ namespace GleeBug DWORD dwMainThreadId; ThreadMap threads; + ThreadInfo* curThread; ProcessInfo() {} //fixes a 'no default constructor available' error diff --git a/GleeBug/Debugger.Thread.h b/GleeBug/Debugger.Thread.h index 4d2ee43..7dddb53 100644 --- a/GleeBug/Debugger.Thread.h +++ b/GleeBug/Debugger.Thread.h @@ -15,6 +15,8 @@ namespace GleeBug ULONG_PTR lpThreadLocalBase; ULONG_PTR lpStartAddress; + ThreadInfo() {} + ThreadInfo(DWORD dwThreadId, HANDLE hThread, LPVOID lpThreadLocalBase, LPVOID lpStartAddress) { this->dwThreadId = dwThreadId; diff --git a/GleeBug/Debugger.h b/GleeBug/Debugger.h index e8e146e..c004c2f 100644 --- a/GleeBug/Debugger.h +++ b/GleeBug/Debugger.h @@ -11,7 +11,7 @@ namespace GleeBug */ class Debugger { - public: + public: //public functionality /** \brief Constructs the Debugger instance. */ @@ -45,89 +45,123 @@ namespace GleeBug */ void Start(); - protected: + protected: //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) {}; /** \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) {}; /** \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) {}; /** \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) {}; /** \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) {}; /** \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) {}; /** \brief Exception debug event callback. Provide an implementation to use this callback. \param exceptionInfo Information about the exception. */ - virtual void cbExceptionEvent(const EXCEPTION_DEBUG_INFO* exceptionInfo) {}; - - /* - single step event - these will execute instead of cbExceptionEvent. - */ - virtual void cbException_single_spep(EXCEPTION_RECORD* except_inf) {}; - - /* - breakpoint event - Will also execute instead of cbExceptionEvent. - */ - virtual void cbExcpetion_breakpoint(EXCEPTION_RECORD* except_inf) {}; + virtual void cbExceptionEvent(const EXCEPTION_DEBUG_INFO & exceptionInfo) {}; /** \brief Debug string debug event callback. Provide an implementation to use this callback. \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. \param rip Information about the RIP event. */ - virtual void cbRipEvent(const RIP_INFO* rip) {}; + virtual void cbRipEvent(const RIP_INFO & rip) {}; + protected: //core functionality + /** + \brief Process creation debug event. Do not override this unless you know what you are doing! + \param createProcess Information about the process created. + */ + virtual void createProcessEvent(const CREATE_PROCESS_DEBUG_INFO & createProcess); - virtual void createProcessEvent(CREATE_PROCESS_DEBUG_INFO* createProcess); - virtual void exitProcessEvent(EXIT_PROCESS_DEBUG_INFO* exitProcess); - virtual void createThreadEvent(CREATE_THREAD_DEBUG_INFO* createThread); - virtual void exitThreadEvent(EXIT_THREAD_DEBUG_INFO* exitThread); - virtual void loadDllEvent(LOAD_DLL_DEBUG_INFO* loadDll); - virtual void unloadDllEvent(UNLOAD_DLL_DEBUG_INFO* unloadDll); - virtual void exceptionEvent(EXCEPTION_DEBUG_INFO* exceptionInfo); - virtual void debugStringEvent(OUTPUT_DEBUG_STRING_INFO* debugString); - virtual void ripEvent(RIP_INFO* rip); + /** + \brief Process termination debug event. Do not override this unless you know what you are doing! + \param exitProcess Information about the process terminated. + */ + virtual void exitProcessEvent(const EXIT_PROCESS_DEBUG_INFO & exitProcess); + /** + \brief Thread creation debug event. Do not override this unless you know what you are doing! + \param createThread Information about the thread created. + */ + virtual void createThreadEvent(const CREATE_THREAD_DEBUG_INFO & createThread); + + /** + \brief Thread termination debug event. Do not override this unless you know what you are doing! + \param exitThread Information about the thread terminated. + */ + virtual void exitThreadEvent(const EXIT_THREAD_DEBUG_INFO & exitThread); + + /** + \brief DLL load debug event. Do not override this unless you know what you are doing! + \param loadDll Information about the DLL loaded. + */ + virtual void loadDllEvent(const LOAD_DLL_DEBUG_INFO & loadDll); + + /** + \brief DLL unload debug event. Do not override this unless you know what you are doing! + \param unloadDll Information about the DLL unloaded. + */ + virtual void unloadDllEvent(const UNLOAD_DLL_DEBUG_INFO & unloadDll); + + /** + \brief Exception debug event. Do not override this unless you know what you are doing! + \param exceptionInfo Information about the exception. + */ + virtual void exceptionEvent(const EXCEPTION_DEBUG_INFO & exceptionInfo); + + /** + \brief Debug string debug event. Do not override this unless you know what you are doing! + \param debugString Information about the debug string. + */ + virtual void debugStringEvent(const OUTPUT_DEBUG_STRING_INFO & debugString); + + /** + \brief RIP debug event. Do not override this unless you know what you are doing! + \param rip Information about the RIP event. + */ + virtual void ripEvent(const RIP_INFO & rip); + + protected: //variables PROCESS_INFORMATION _mainProcess; DWORD _continueStatus; bool _breakDebugger; DEBUG_EVENT _debugEvent; ProcessMap _processes; + ProcessInfo* _curProcess; }; }; diff --git a/MyDebugger/MyDebugger.h b/MyDebugger/MyDebugger.h index ca1dd6c..86b18ee 100644 --- a/MyDebugger/MyDebugger.h +++ b/MyDebugger/MyDebugger.h @@ -6,59 +6,59 @@ class MyDebugger : public GleeBug::Debugger { protected: - virtual void cbCreateProcessEvent(const CREATE_PROCESS_DEBUG_INFO* createProcess) + virtual void cbCreateProcessEvent(const CREATE_PROCESS_DEBUG_INFO & createProcess) { - 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) { - 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) { - 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 cbException_single_spep(EXCEPTION_RECORD & except_inf) { - printf("a single step occurred at location 0x%X", except_inf->ExceptionAddress); + printf("a single step occurred at location 0x%X", except_inf.ExceptionAddress); }; - virtual void cbExcpetion_breakpoint(EXCEPTION_RECORD* except_inf) + virtual void cbExcpetion_breakpoint(EXCEPTION_RECORD & except_inf) { - printf("a breakpoint occurred at location 0x%X", except_inf->ExceptionAddress); + 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) { - 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) { - 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) { - 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); }; - virtual void cbDebugStringEvent(const OUTPUT_DEBUG_STRING_INFO* debugString) + virtual void cbDebugStringEvent(const OUTPUT_DEBUG_STRING_INFO & debugString) { - printf("Debug string at 0x%p with length %d\n", debugString->lpDebugStringData, debugString->nDebugStringLength); + printf("Debug string at 0x%p with length %d\n", debugString.lpDebugStringData, debugString.nDebugStringLength); }; - virtual void cbRipEvent(const RIP_INFO* rip) + virtual void cbRipEvent(const RIP_INFO & rip) { - 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); }; };