mirror of https://github.com/x64dbg/GleeBug
better thread and process housekeeping
This commit is contained in:
parent
ed7d8e453f
commit
6ddcb2d798
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ namespace GleeBug
|
|||
DWORD dwMainThreadId;
|
||||
|
||||
ThreadMap threads;
|
||||
ThreadInfo* curThread;
|
||||
|
||||
ProcessInfo() {} //fixes a 'no default constructor available' error
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue