better thread and process housekeeping

This commit is contained in:
Mr. eXoDia 2015-03-28 01:33:14 +01:00
parent ed7d8e453f
commit 6ddcb2d798
5 changed files with 133 additions and 87 deletions

View File

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

View File

@ -17,6 +17,7 @@ namespace GleeBug
DWORD dwMainThreadId;
ThreadMap threads;
ThreadInfo* curThread;
ProcessInfo() {} //fixes a 'no default constructor available' error

View File

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

View File

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

View File

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