dll housekeeping done

This commit is contained in:
Mr. eXoDia 2015-03-28 02:27:10 +01:00
parent cd6b15fd8c
commit a3529f8b27
11 changed files with 112 additions and 53 deletions

View File

@ -1,7 +1,7 @@
#ifndef _DEBUGGER_DLL_H #ifndef _DEBUGGER_DLL_H
#define _DEBUGGER_DLL_H #define _DEBUGGER_DLL_H
#include "_global.h" #include "Debugger.Global.h"
namespace GleeBug namespace GleeBug
{ {
@ -10,8 +10,21 @@ namespace GleeBug
*/ */
struct DllInfo struct DllInfo
{ {
ULONG_PTR lpBaseOfDll;
DWORD sizeOfImage;
ULONG_PTR entryPoint;
DllInfo() {}
DllInfo(LPVOID lpBaseOfDll, DWORD sizeOfImage, LPVOID entryPoint)
{
this->lpBaseOfDll = (ULONG_PTR)lpBaseOfDll;
this->sizeOfImage = sizeOfImage;
this->entryPoint = (ULONG_PTR)entryPoint;
}
}; };
typedef std::map<Range, DllInfo, RangeCompare> DllMap;
}; };
#endif //_DEBUGGER_DLL_H #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

@ -16,7 +16,10 @@ namespace GleeBug
_curProcess->curThread = &_curProcess->threads[process.dwMainThreadId]; _curProcess->curThread = &_curProcess->threads[process.dwMainThreadId];
//call the callback //call the callback
cbCreateProcessEvent(createProcess); cbCreateProcessEvent(createProcess, *_curProcess);
//close the file handle
CloseHandle(createProcess.hFile);
} }
void Debugger::exitProcessEvent(const EXIT_PROCESS_DEBUG_INFO & exitProcess) void Debugger::exitProcessEvent(const EXIT_PROCESS_DEBUG_INFO & exitProcess)
@ -26,7 +29,7 @@ namespace GleeBug
_breakDebugger = true; _breakDebugger = true;
//call the callback //call the callback
cbExitProcessEvent(exitProcess); cbExitProcessEvent(exitProcess, *_curProcess);
//process housekeeping //process housekeeping
_processes.erase(_debugEvent.dwProcessId); _processes.erase(_debugEvent.dwProcessId);
@ -45,13 +48,13 @@ namespace GleeBug
_curProcess->curThread = &_curProcess->threads[thread.dwThreadId]; _curProcess->curThread = &_curProcess->threads[thread.dwThreadId];
//call the callback //call the callback
cbCreateThreadEvent(createThread); cbCreateThreadEvent(createThread, *_curProcess->curThread);
} }
void Debugger::exitThreadEvent(const EXIT_THREAD_DEBUG_INFO & exitThread) void Debugger::exitThreadEvent(const EXIT_THREAD_DEBUG_INFO & exitThread)
{ {
//call the callback //call the callback
cbExitThreadEvent(exitThread); cbExitThreadEvent(exitThread, *_curProcess->curThread);
//thread housekeeping //thread housekeeping
_curProcess->threads.erase(_debugEvent.dwThreadId); _curProcess->threads.erase(_debugEvent.dwThreadId);
@ -62,12 +65,36 @@ namespace GleeBug
void Debugger::loadDllEvent(const LOAD_DLL_DEBUG_INFO & loadDll) void Debugger::loadDllEvent(const LOAD_DLL_DEBUG_INFO & loadDll)
{ {
cbLoadDllEvent(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 callback
cbLoadDllEvent(loadDll, dll);
//close the file handle
CloseHandle(loadDll.hFile);
} }
void Debugger::unloadDllEvent(const UNLOAD_DLL_DEBUG_INFO & unloadDll) void Debugger::unloadDllEvent(const UNLOAD_DLL_DEBUG_INFO & unloadDll)
{ {
cbUnloadDllEvent(unloadDll); //call the 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);
} }
void Debugger::exceptionEvent(const EXCEPTION_DEBUG_INFO & exceptionInfo) void Debugger::exceptionEvent(const EXCEPTION_DEBUG_INFO & exceptionInfo)
@ -140,5 +167,8 @@ namespace GleeBug
if (!ContinueDebugEvent(_debugEvent.dwProcessId, _debugEvent.dwThreadId, _continueStatus)) if (!ContinueDebugEvent(_debugEvent.dwProcessId, _debugEvent.dwThreadId, _continueStatus))
break; break;
} }
_processes.clear();
_curProcess = nullptr;
} }
}; };

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
{ {
@ -18,6 +19,7 @@ namespace GleeBug
ThreadMap threads; ThreadMap threads;
ThreadInfo* curThread; ThreadInfo* curThread;
DllMap dlls;
ProcessInfo() {} //fixes a 'no default constructor available' error ProcessInfo() {} //fixes a 'no default constructor available' error

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

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
@ -50,37 +50,37 @@ namespace GleeBug
\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.

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,18 +141,20 @@
<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.Loop.cpp" /> <ClCompile Include="Debugger.Loop.cpp" />
<ClCompile Include="_global.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="Debugger.Dll.h" /> <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,9 +15,6 @@
</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>
@ -26,9 +23,6 @@
</ClCompile> </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>
@ -41,5 +35,8 @@
<ClInclude Include="Debugger.Dll.h"> <ClInclude Include="Debugger.Dll.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </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,45 +3,37 @@
#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);
}; };