process & thread housekeeping functionality

This commit is contained in:
mrexodia 2015-03-25 21:25:25 +01:00
parent a1847472ba
commit 5f526bac56
10 changed files with 113 additions and 56 deletions

View File

@ -1,20 +0,0 @@
#ifndef _DEBUGGER_DATA_H
#define _DEBUGGER_DATA_H
#include "_global.h"
namespace GleeBug
{
/**
\brief Process information structure.
*/
struct ProcessInfo
{
HANDLE hProcess;
HANDLE hThread;
DWORD ProcessId;
DWORD MainThreadId;
};
}
#endif //_DEBUGGER_DATA_H

View File

@ -4,26 +4,47 @@ namespace GleeBug
{ {
void Debugger::createProcessEvent(CREATE_PROCESS_DEBUG_INFO* createProcess) void Debugger::createProcessEvent(CREATE_PROCESS_DEBUG_INFO* createProcess)
{ {
//process housekeeping
ProcessInfo process(createProcess->hProcess,
createProcess->hThread,
_debugEvent.dwProcessId,
_debugEvent.dwThreadId);
_processes.insert({ process.dwProcessId, process });
//call the callback
cbCreateProcessEvent(createProcess); cbCreateProcessEvent(createProcess);
} }
void Debugger::exitProcessEvent(EXIT_PROCESS_DEBUG_INFO* exitProcess) void Debugger::exitProcessEvent(EXIT_PROCESS_DEBUG_INFO* exitProcess)
{ {
if (_debugEvent.dwProcessId == _mainProcess.ProcessId) //check if the terminated process is the main debuggee
{ if (_debugEvent.dwProcessId == _mainProcess.dwProcessId)
_breakDebugger = true; _breakDebugger = true;
}
//call the callback
cbExitProcessEvent(exitProcess); cbExitProcessEvent(exitProcess);
//process housekeeping
_processes.erase(_debugEvent.dwProcessId);
} }
void Debugger::createThreadEvent(CREATE_THREAD_DEBUG_INFO* createThread) void Debugger::createThreadEvent(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 });
//call the callback
cbCreateThreadEvent(createThread); cbCreateThreadEvent(createThread);
} }
void Debugger::exitThreadEvent(EXIT_THREAD_DEBUG_INFO* exitThread) void Debugger::exitThreadEvent(EXIT_THREAD_DEBUG_INFO* exitThread)
{ {
//call the callback
cbExitThreadEvent(exitThread); cbExitThreadEvent(exitThread);
//thread housekeeping
_processes[_debugEvent.dwProcessId].threads.erase(_debugEvent.dwThreadId);
} }
void Debugger::loadDllEvent(LOAD_DLL_DEBUG_INFO* loadDll) void Debugger::loadDllEvent(LOAD_DLL_DEBUG_INFO* loadDll)

View File

@ -0,0 +1,36 @@
#ifndef _DEBUGGER_PROCESS_H
#define _DEBUGGER_PROCESS_H
#include "_global.h"
#include "Debugger.Thread.h"
namespace GleeBug
{
/**
\brief Process information structure.
*/
struct ProcessInfo
{
HANDLE hProcess;
HANDLE hThread;
DWORD dwProcessId;
DWORD dwMainThreadId;
ThreadMap threads;
ProcessInfo() {} //fixes a 'no default constructor available' error
ProcessInfo(HANDLE hProcess, HANDLE hThread, DWORD dwProcessId, DWORD dwMainThreadId)
{
this->hProcess = hProcess;
this->hThread = hThread;
this->dwProcessId = dwProcessId;
this->dwMainThreadId = dwMainThreadId;
this->threads.clear();
}
};
typedef std::map<DWORD, ProcessInfo> ProcessMap;
}
#endif //_DEBUGGER_PROCESS_H

30
GleeBug/Debugger.Thread.h Normal file
View File

@ -0,0 +1,30 @@
#ifndef _DEBUGGER_THREADS_H
#define _DEBUGGER_THREADS_H
#include "_global.h"
namespace GleeBug
{
/**
\brief Thread information structure.
*/
struct ThreadInfo
{
DWORD dwThreadId;
HANDLE hThread;
ULONG_PTR lpThreadLocalBase;
ULONG_PTR lpStartAddress;
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;
}
};
typedef std::map<DWORD, ThreadInfo> ThreadMap;
};
#endif //_DEBUGGER_THREADS_H

View File

@ -4,6 +4,7 @@ namespace GleeBug
{ {
Debugger::Debugger() Debugger::Debugger()
{ {
_processes.clear();
} }
bool Debugger::Init(const wchar_t* szFilePath, bool Debugger::Init(const wchar_t* szFilePath,
@ -12,8 +13,6 @@ namespace GleeBug
{ {
STARTUPINFOW si; STARTUPINFOW si;
memset(&si, 0, sizeof(si)); memset(&si, 0, sizeof(si));
PROCESS_INFORMATION pi;
memset(&pi, 0, sizeof(pi));
const wchar_t* szFileNameCreateProcess; const wchar_t* szFileNameCreateProcess;
wchar_t* szCommandLineCreateProcess; wchar_t* szCommandLineCreateProcess;
if (szCommandLine == NULL || !wcslen(szCommandLine)) if (szCommandLine == NULL || !wcslen(szCommandLine))
@ -29,7 +28,7 @@ namespace GleeBug
szFileNameCreateProcess = 0; szFileNameCreateProcess = 0;
} }
if (!CreateProcessW(szFileNameCreateProcess, return !!CreateProcessW(szFileNameCreateProcess,
szCommandLineCreateProcess, szCommandLineCreateProcess,
NULL, NULL,
NULL, NULL,
@ -38,15 +37,7 @@ namespace GleeBug
NULL, NULL,
szCurrentDirectory, szCurrentDirectory,
&si, &si,
&pi)) &_mainProcess);
{
return false;
}
_mainProcess.hProcess = pi.hProcess;
_mainProcess.hThread = pi.hThread;
_mainProcess.ProcessId = pi.dwProcessId;
_mainProcess.MainThreadId = pi.dwThreadId;
return true;
} }
bool Debugger::Stop() bool Debugger::Stop()
@ -56,11 +47,6 @@ namespace GleeBug
bool Debugger::Detach() bool Debugger::Detach()
{ {
return !!DebugActiveProcessStop(_mainProcess.ProcessId); return !!DebugActiveProcessStop(_mainProcess.dwProcessId);
}
const ProcessInfo & Debugger::GetMainProcess()
{
return _mainProcess;
} }
}; };

View File

@ -2,7 +2,7 @@
#define _DEBUGGER_H #define _DEBUGGER_H
#include "_global.h" #include "_global.h"
#include "Debugger.Data.h" #include "Debugger.Process.h"
namespace GleeBug namespace GleeBug
{ {
@ -45,12 +45,6 @@ namespace GleeBug
*/ */
void Start(); void Start();
/**
\brief Gets main process info.
\return The main process info.
*/
const ProcessInfo & GetMainProcess();
protected: protected:
/** /**
\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.
@ -129,12 +123,11 @@ namespace GleeBug
virtual void debugStringEvent(OUTPUT_DEBUG_STRING_INFO* debugString); virtual void debugStringEvent(OUTPUT_DEBUG_STRING_INFO* debugString);
virtual void ripEvent(RIP_INFO* rip); virtual void ripEvent(RIP_INFO* rip);
PROCESS_INFORMATION _mainProcess;
ProcessInfo _mainProcess;
DWORD _continueStatus; DWORD _continueStatus;
bool _breakDebugger; bool _breakDebugger;
DEBUG_EVENT _debugEvent; DEBUG_EVENT _debugEvent;
ProcessMap _processes;
}; };
}; };

View File

@ -139,8 +139,9 @@
<ClCompile Include="_global.cpp" /> <ClCompile Include="_global.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="Debugger.Data.h" /> <ClInclude Include="Debugger.Process.h" />
<ClInclude Include="Debugger.h" /> <ClInclude Include="Debugger.h" />
<ClInclude Include="Debugger.Thread.h" />
<ClInclude Include="_global.h" /> <ClInclude Include="_global.h" />
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

View File

@ -29,10 +29,13 @@
<ClInclude Include="_global.h"> <ClInclude Include="_global.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Debugger.Data.h"> <ClInclude Include="Debugger.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Debugger.h"> <ClInclude Include="Debugger.Process.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Debugger.Thread.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
</ItemGroup> </ItemGroup>

View File

@ -3,6 +3,9 @@
#include <cstdio> #include <cstdio>
#include <string> #include <string>
#include <vector>
#include <unordered_map>
#include <map>
#include <windows.h> #include <windows.h>
#endif //_GLOBAL_H #endif //_GLOBAL_H

View File

@ -3,9 +3,13 @@
int main() int main()
{ {
wchar_t szFilePath[256] = L"c:\\CodeBlocks\\arma_cert_bin_info\\bin\\arma_cert_bin_info.exe"; #ifdef _WIN64
wchar_t szFilePath[256] = L"c:\\test64.exe";
#else //x86
wchar_t szFilePath[256] = L"c:\\test32.exe";
#endif //_WIN64
wchar_t szCommandLine[256] = L""; wchar_t szCommandLine[256] = L"";
wchar_t szCurrentDir[256] = L"c:\\CodeBlocks\\arma_cert_bin_info\\bin"; wchar_t szCurrentDir[256] = L"c:\\";
MyDebugger dbg; MyDebugger dbg;
if (dbg.Init(szFilePath, szCommandLine, szCurrentDir)) if (dbg.Init(szFilePath, szCommandLine, szCurrentDir))
{ {