mirror of https://github.com/x64dbg/GleeBug
fixed some ugly code + added StepInternal function
This commit is contained in:
parent
3568de5680
commit
a2fbad713b
|
|
@ -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);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -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);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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) });
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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 });
|
||||||
|
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -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);
|
||||||
|
|
||||||
|
|
@ -70,13 +73,32 @@ namespace GleeBug
|
||||||
\param debugger This pointer to a subclass of Debugger.
|
\param debugger This pointer to a subclass of Debugger.
|
||||||
\param callback Pointer to the callback. Written like: &MyDebugger::cb
|
\param callback Pointer to the callback. Written like: &MyDebugger::cb
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template<typename T>
|
||||||
void StepInto(T* debugger, void(T::*callback)())
|
void StepInto(T* debugger, void(T::*callback)())
|
||||||
{
|
{
|
||||||
static_cast<void>(static_cast<Debugger*>(debugger));
|
static_cast<void>(static_cast<Debugger*>(debugger));
|
||||||
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;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue