fixed some ugly code + added StepInternal function

This commit is contained in:
mrexodia 2015-08-15 19:37:06 +02:00
parent 3568de5680
commit a2fbad713b
10 changed files with 80 additions and 31 deletions

View File

@ -2,10 +2,10 @@
namespace GleeBug 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);
} }
}; };

View File

@ -21,7 +21,7 @@ namespace GleeBug
\param sizeOfImage Size of the image. \param sizeOfImage Size of the image.
\param entryPoint The entry point. \param entryPoint The entry point.
*/ */
DllInfo(LPVOID lpBaseOfDll, ptr sizeOfImage, LPVOID entryPoint); explicit DllInfo(LPVOID lpBaseOfDll, ptr sizeOfImage, LPVOID entryPoint);
}; };
}; };

View File

@ -36,6 +36,15 @@ namespace GleeBug
void Debugger::exceptionSingleStep(const EXCEPTION_RECORD & exceptionRecord, const bool firstChance) 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 if (_thread->isSingleStepping) //handle single step
{ {
//set internal status //set internal status

View File

@ -6,15 +6,15 @@ namespace GleeBug
{ {
//process housekeeping //process housekeeping
_processes.insert({ _debugEvent.dwProcessId, _processes.insert({ _debugEvent.dwProcessId,
ProcessInfo(_debugEvent.dwProcessId, ProcessInfo(createProcess.hProcess,
createProcess.hProcess, _debugEvent.dwProcessId,
_debugEvent.dwThreadId) }); _debugEvent.dwThreadId) });
_process = &_processes.find(_debugEvent.dwProcessId)->second; _process = &_processes.find(_debugEvent.dwProcessId)->second;
//thread housekeeping (main thread is created implicitly) //thread housekeeping (main thread is created implicitly)
_process->threads.insert({ _debugEvent.dwThreadId, _process->threads.insert({ _debugEvent.dwThreadId,
ThreadInfo(_debugEvent.dwThreadId, ThreadInfo(createProcess.hThread,
createProcess.hThread, _debugEvent.dwThreadId,
createProcess.lpThreadLocalBase, createProcess.lpThreadLocalBase,
createProcess.lpStartAddress) }); createProcess.lpStartAddress) });
_thread = _process->thread = &_process->threads.find(_debugEvent.dwThreadId)->second; _thread = _process->thread = &_process->threads.find(_debugEvent.dwThreadId)->second;

View File

@ -6,8 +6,8 @@ namespace GleeBug
{ {
//thread housekeeping //thread housekeeping
_process->threads.insert({ _debugEvent.dwThreadId, _process->threads.insert({ _debugEvent.dwThreadId,
ThreadInfo(_debugEvent.dwThreadId, ThreadInfo(createThread.hThread,
createThread.hThread, _debugEvent.dwThreadId,
createThread.lpThreadLocalBase, createThread.lpThreadLocalBase,
createThread.lpStartAddress) }); createThread.lpStartAddress) });

View File

@ -34,6 +34,7 @@ namespace GleeBug
if (!MemWrite(address, info.internal.software.newbytes, info.internal.software.size)) if (!MemWrite(address, info.internal.software.newbytes, info.internal.software.size))
return false; return false;
FlushInstructionCache(hProcess, nullptr, 0);
//insert in the breakpoint map //insert in the breakpoint map
breakpoints.insert({ { info.type, info.address }, info }); breakpoints.insert({ { info.type, info.address }, info });

View File

@ -2,11 +2,12 @@
namespace GleeBug 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;
} }
}; };

View File

@ -25,13 +25,15 @@ namespace GleeBug
DllMap dlls; DllMap dlls;
BreakpointMap breakpoints; BreakpointMap breakpoints;
BreakpointCallbackMap breakpointCallbacks; BreakpointCallbackMap breakpointCallbacks;
BreakpointInfo restoreSoftwareBreakpoint;
/** /**
\brief Constructor. \brief Constructor.
\param hProcess Process handle.
\param dwProcessId Identifier for the process. \param dwProcessId Identifier for the process.
\param dwMainThreadId Identifier for the main thread. \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. \brief Read memory from the process.

View File

@ -2,34 +2,41 @@
namespace GleeBug 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) : ThreadInfo::ThreadInfo(const ThreadInfo & other) :
dwThreadId(other.dwThreadId),
hThread(other.hThread), hThread(other.hThread),
dwThreadId(other.dwThreadId),
lpThreadLocalBase(other.lpThreadLocalBase), lpThreadLocalBase(other.lpThreadLocalBase),
lpStartAddress(other.lpStartAddress), lpStartAddress(other.lpStartAddress),
registers(), //create new registers registers(), //create new registers
stepCallbacks(other.stepCallbacks), stepCallbacks(other.stepCallbacks),
isSingleStepping(other.isSingleStepping) isSingleStepping(other.isSingleStepping),
isInternalStepping(other.isInternalStepping),
cbInternalStep(other.cbInternalStep)
{ {
} }
ThreadInfo & ThreadInfo::operator=(const ThreadInfo& other) ThreadInfo & ThreadInfo::operator=(const ThreadInfo& other)
{ {
dwThreadId = other.dwThreadId;
hThread = other.hThread; hThread = other.hThread;
dwThreadId = other.dwThreadId;
lpThreadLocalBase = other.lpThreadLocalBase; lpThreadLocalBase = other.lpThreadLocalBase;
lpStartAddress = other.lpStartAddress; lpStartAddress = other.lpStartAddress;
registers = Registers(); //create new registers registers = Registers(); //create new registers
stepCallbacks = other.stepCallbacks; stepCallbacks = other.stepCallbacks;
isSingleStepping = other.isSingleStepping; isSingleStepping = other.isSingleStepping;
isInternalStepping = other.isInternalStepping;
cbInternalStep = other.cbInternalStep;
return *this; return *this;
} }
@ -60,15 +67,22 @@ namespace GleeBug
return bReturn; return bReturn;
} }
void ThreadInfo::StepInto()
{
registers.TrapFlag.Set();
isSingleStepping = true;
}
void ThreadInfo::StepInto(const StepCallback & cbStep) void ThreadInfo::StepInto(const StepCallback & cbStep)
{ {
StepInto(); StepInto();
stepCallbacks.push_back(cbStep); stepCallbacks.push_back(cbStep);
} }
void ThreadInfo::StepInto() void ThreadInfo::StepInternal(const StepCallback & cbStep)
{ {
registers.TrapFlag.Set(); registers.TrapFlag.Set();
isSingleStepping = true; isInternalStepping = true;
cbInternalStep = cbStep;
} }
}; };

View File

@ -12,22 +12,25 @@ namespace GleeBug
class ThreadInfo class ThreadInfo
{ {
public: public:
uint32 dwThreadId;
HANDLE hThread; HANDLE hThread;
uint32 dwThreadId;
ptr lpThreadLocalBase; ptr lpThreadLocalBase;
ptr lpStartAddress; ptr lpStartAddress;
Registers registers; Registers registers;
StepCallbackVector stepCallbacks; StepCallbackVector stepCallbacks;
bool isSingleStepping; bool isSingleStepping;
bool isInternalStepping;
StepCallback cbInternalStep;
/** /**
\brief Constructor. \brief Constructor.
\param hThread Thread handle.
\param dwThreadId Identifier for the thread. \param dwThreadId Identifier for the thread.
\param lpThreadLocalBase The thread local base. \param lpThreadLocalBase The thread local base.
\param lpStartAddress The start address. \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. \brief Copy constructor.
@ -60,7 +63,7 @@ namespace GleeBug
/** /**
\brief Step into. \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); void StepInto(const StepCallback & cbStep);
@ -77,6 +80,25 @@ namespace GleeBug
StepInto(std::bind(callback, 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<typename T>
void StepInternal(T* debugger, void(T::*callback)())
{
static_cast<void>(static_cast<Debugger*>(debugger));
StepInternal(std::bind(callback, debugger));
}
private: private:
CONTEXT _oldContext; CONTEXT _oldContext;
}; };