diff --git a/GleeBug/Debugger.Dll.cpp b/GleeBug/Debugger.Dll.cpp index 3e0a294..0ba5ffd 100644 --- a/GleeBug/Debugger.Dll.cpp +++ b/GleeBug/Debugger.Dll.cpp @@ -2,10 +2,10 @@ namespace GleeBug { - DllInfo::DllInfo(LPVOID lpBaseOfDll, ptr sizeOfImage, LPVOID entryPoint) + DllInfo::DllInfo(LPVOID lpBaseOfDll, ptr sizeOfImage, LPVOID entryPoint) : + lpBaseOfDll(ptr(lpBaseOfDll)), + sizeOfImage(sizeOfImage), + entryPoint(ptr(entryPoint)) { - this->lpBaseOfDll = ptr(lpBaseOfDll); - this->sizeOfImage = sizeOfImage; - this->entryPoint = ptr(entryPoint); } }; \ No newline at end of file diff --git a/GleeBug/Debugger.Dll.h b/GleeBug/Debugger.Dll.h index a7bfff1..4e69709 100644 --- a/GleeBug/Debugger.Dll.h +++ b/GleeBug/Debugger.Dll.h @@ -21,7 +21,7 @@ namespace GleeBug \param sizeOfImage Size of the image. \param entryPoint The entry point. */ - DllInfo(LPVOID lpBaseOfDll, ptr sizeOfImage, LPVOID entryPoint); + explicit DllInfo(LPVOID lpBaseOfDll, ptr sizeOfImage, LPVOID entryPoint); }; }; diff --git a/GleeBug/Debugger.Loop.Exception.cpp b/GleeBug/Debugger.Loop.Exception.cpp index 7b5f61d..c81c05a 100644 --- a/GleeBug/Debugger.Loop.Exception.cpp +++ b/GleeBug/Debugger.Loop.Exception.cpp @@ -36,6 +36,15 @@ namespace GleeBug void Debugger::exceptionSingleStep(const EXCEPTION_RECORD & exceptionRecord, const bool firstChance) { + if (_thread->isInternalStepping) //handle internal steps + { + //set internal status + _thread->isSingleStepping = false; + _continueStatus = DBG_CONTINUE; + + //call the internal step callback + _thread->cbInternalStep(); + } if (_thread->isSingleStepping) //handle single step { //set internal status diff --git a/GleeBug/Debugger.Loop.Process.cpp b/GleeBug/Debugger.Loop.Process.cpp index 8971fa1..fbb15c2 100644 --- a/GleeBug/Debugger.Loop.Process.cpp +++ b/GleeBug/Debugger.Loop.Process.cpp @@ -6,15 +6,15 @@ namespace GleeBug { //process housekeeping _processes.insert({ _debugEvent.dwProcessId, - ProcessInfo(_debugEvent.dwProcessId, - createProcess.hProcess, + ProcessInfo(createProcess.hProcess, + _debugEvent.dwProcessId, _debugEvent.dwThreadId) }); _process = &_processes.find(_debugEvent.dwProcessId)->second; //thread housekeeping (main thread is created implicitly) _process->threads.insert({ _debugEvent.dwThreadId, - ThreadInfo(_debugEvent.dwThreadId, - createProcess.hThread, + ThreadInfo(createProcess.hThread, + _debugEvent.dwThreadId, createProcess.lpThreadLocalBase, createProcess.lpStartAddress) }); _thread = _process->thread = &_process->threads.find(_debugEvent.dwThreadId)->second; diff --git a/GleeBug/Debugger.Loop.Thread.cpp b/GleeBug/Debugger.Loop.Thread.cpp index aa5283c..2dfda94 100644 --- a/GleeBug/Debugger.Loop.Thread.cpp +++ b/GleeBug/Debugger.Loop.Thread.cpp @@ -6,8 +6,8 @@ namespace GleeBug { //thread housekeeping _process->threads.insert({ _debugEvent.dwThreadId, - ThreadInfo(_debugEvent.dwThreadId, - createThread.hThread, + ThreadInfo(createThread.hThread, + _debugEvent.dwThreadId, createThread.lpThreadLocalBase, createThread.lpStartAddress) }); diff --git a/GleeBug/Debugger.Process.Breakpoint.cpp b/GleeBug/Debugger.Process.Breakpoint.cpp index d8e6668..c49bcbb 100644 --- a/GleeBug/Debugger.Process.Breakpoint.cpp +++ b/GleeBug/Debugger.Process.Breakpoint.cpp @@ -34,6 +34,7 @@ namespace GleeBug if (!MemWrite(address, info.internal.software.newbytes, info.internal.software.size)) return false; + FlushInstructionCache(hProcess, nullptr, 0); //insert in the breakpoint map breakpoints.insert({ { info.type, info.address }, info }); diff --git a/GleeBug/Debugger.Process.cpp b/GleeBug/Debugger.Process.cpp index 98a2de7..167872d 100644 --- a/GleeBug/Debugger.Process.cpp +++ b/GleeBug/Debugger.Process.cpp @@ -2,11 +2,12 @@ namespace GleeBug { - ProcessInfo::ProcessInfo(uint32 dwProcessId, HANDLE hProcess, uint32 dwMainThreadId) + ProcessInfo::ProcessInfo(HANDLE hProcess, uint32 dwProcessId, uint32 dwMainThreadId) : + hProcess(hProcess), + dwProcessId(dwProcessId), + dwMainThreadId(dwMainThreadId), + thread(nullptr), + systemBreakpoint(false) { - this->systemBreakpoint = false; - this->hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId); - this->dwProcessId = dwProcessId; - this->dwMainThreadId = dwMainThreadId; } }; \ No newline at end of file diff --git a/GleeBug/Debugger.Process.h b/GleeBug/Debugger.Process.h index bad63d1..317ab3d 100644 --- a/GleeBug/Debugger.Process.h +++ b/GleeBug/Debugger.Process.h @@ -25,13 +25,15 @@ namespace GleeBug DllMap dlls; BreakpointMap breakpoints; BreakpointCallbackMap breakpointCallbacks; + BreakpointInfo restoreSoftwareBreakpoint; /** \brief Constructor. + \param hProcess Process handle. \param dwProcessId Identifier for the process. \param dwMainThreadId Identifier for the main thread. */ - ProcessInfo(uint32 dwProcessId, HANDLE hProcess, uint32 dwMainThreadId); + explicit ProcessInfo(HANDLE hProcess, uint32 dwProcessId, uint32 dwMainThreadId); /** \brief Read memory from the process. diff --git a/GleeBug/Debugger.Thread.cpp b/GleeBug/Debugger.Thread.cpp index 5cb0e7b..f05d445 100644 --- a/GleeBug/Debugger.Thread.cpp +++ b/GleeBug/Debugger.Thread.cpp @@ -2,34 +2,41 @@ namespace GleeBug { - ThreadInfo::ThreadInfo(uint32 dwThreadId, HANDLE hThread, LPVOID lpThreadLocalBase, LPVOID lpStartAddress) + ThreadInfo::ThreadInfo(HANDLE hThread, uint32 dwThreadId, LPVOID lpThreadLocalBase, LPVOID lpStartAddress) : + hThread(hThread), + dwThreadId(dwThreadId), + lpThreadLocalBase(ptr(lpThreadLocalBase)), + lpStartAddress(ptr(lpStartAddress)), + isSingleStepping(false), + isInternalStepping(false), + cbInternalStep(nullptr) { - this->dwThreadId = dwThreadId; - this->hThread = hThread; - this->lpThreadLocalBase = ptr(lpThreadLocalBase); - this->lpStartAddress = ptr(lpStartAddress); } ThreadInfo::ThreadInfo(const ThreadInfo & other) : - dwThreadId(other.dwThreadId), hThread(other.hThread), + dwThreadId(other.dwThreadId), lpThreadLocalBase(other.lpThreadLocalBase), lpStartAddress(other.lpStartAddress), registers(), //create new registers stepCallbacks(other.stepCallbacks), - isSingleStepping(other.isSingleStepping) + isSingleStepping(other.isSingleStepping), + isInternalStepping(other.isInternalStepping), + cbInternalStep(other.cbInternalStep) { } ThreadInfo & ThreadInfo::operator=(const ThreadInfo& other) { - dwThreadId = other.dwThreadId; hThread = other.hThread; + dwThreadId = other.dwThreadId; lpThreadLocalBase = other.lpThreadLocalBase; lpStartAddress = other.lpStartAddress; registers = Registers(); //create new registers stepCallbacks = other.stepCallbacks; isSingleStepping = other.isSingleStepping; + isInternalStepping = other.isInternalStepping; + cbInternalStep = other.cbInternalStep; return *this; } @@ -60,15 +67,22 @@ namespace GleeBug return bReturn; } + void ThreadInfo::StepInto() + { + registers.TrapFlag.Set(); + isSingleStepping = true; + } + void ThreadInfo::StepInto(const StepCallback & cbStep) { StepInto(); stepCallbacks.push_back(cbStep); } - void ThreadInfo::StepInto() + void ThreadInfo::StepInternal(const StepCallback & cbStep) { registers.TrapFlag.Set(); - isSingleStepping = true; + isInternalStepping = true; + cbInternalStep = cbStep; } }; \ No newline at end of file diff --git a/GleeBug/Debugger.Thread.h b/GleeBug/Debugger.Thread.h index 91bdb1e..d5081fc 100644 --- a/GleeBug/Debugger.Thread.h +++ b/GleeBug/Debugger.Thread.h @@ -12,22 +12,25 @@ namespace GleeBug class ThreadInfo { public: - uint32 dwThreadId; HANDLE hThread; + uint32 dwThreadId; ptr lpThreadLocalBase; ptr lpStartAddress; Registers registers; StepCallbackVector stepCallbacks; bool isSingleStepping; + bool isInternalStepping; + StepCallback cbInternalStep; /** \brief Constructor. + \param hThread Thread handle. \param dwThreadId Identifier for the thread. \param lpThreadLocalBase The thread local base. \param lpStartAddress The start address. */ - ThreadInfo(uint32 dwThreadId, HANDLE hThread, LPVOID lpThreadLocalBase, LPVOID lpStartAddress); + explicit ThreadInfo(HANDLE hThread, uint32 dwThreadId, LPVOID lpThreadLocalBase, LPVOID lpStartAddress); /** \brief Copy constructor. @@ -60,7 +63,7 @@ namespace GleeBug /** \brief Step into. - \param cbStep StepCallback. Can be written using BIND(this, MyDebugger::cb). + \param cbStep Step callback. Can be written using BIND(this, MyDebugger::cb). */ void StepInto(const StepCallback & cbStep); @@ -70,13 +73,32 @@ namespace GleeBug \param debugger This pointer to a subclass of Debugger. \param callback Pointer to the callback. Written like: &MyDebugger::cb */ - template + template void StepInto(T* debugger, void(T::*callback)()) { static_cast(static_cast(debugger)); StepInto(std::bind(callback, debugger)); } + /** + \brief Perform an internal step (not reported to the outside) + \param cbStep Step callback. Can be written using BIND(this, MyDebugger::cb). + */ + void StepInternal(const StepCallback & cbStep); + + /** + \brief Perform an internal step (not reported to the outside) + \tparam T Generic type parameter. Must be a subclass of Debugger. + \param debugger This pointer to a subclass of Debugger. + \param callback Pointer to the callback. Written like: &MyDebugger::cb + */ + template + void StepInternal(T* debugger, void(T::*callback)()) + { + static_cast(static_cast(debugger)); + StepInternal(std::bind(callback, debugger)); + } + private: CONTEXT _oldContext; };