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

View File

@ -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;

View File

@ -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) });

View File

@ -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 });

View File

@ -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;
}
};

View File

@ -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.

View File

@ -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;
}
};

View File

@ -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 <typename T>
template<typename T>
void StepInto(T* debugger, void(T::*callback)())
{
static_cast<void>(static_cast<Debugger*>(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:
CONTEXT _oldContext;
};