mirror of https://github.com/x64dbg/GleeBug
92 lines
2.8 KiB
C++
92 lines
2.8 KiB
C++
#include "Debugger.Thread.h"
|
|
|
|
namespace GleeBug
|
|
{
|
|
Thread::Thread(HANDLE hThread, uint32 dwThreadId, LPVOID lpThreadLocalBase, LPVOID lpStartAddress) :
|
|
hThread(hThread),
|
|
dwThreadId(dwThreadId),
|
|
lpThreadLocalBase(ptr(lpThreadLocalBase)),
|
|
lpStartAddress(ptr(lpStartAddress)),
|
|
isSingleStepping(false),
|
|
isInternalStepping(false),
|
|
cbInternalStep(nullptr)
|
|
{
|
|
}
|
|
|
|
Thread::Thread(const Thread & other) :
|
|
hThread(other.hThread),
|
|
dwThreadId(other.dwThreadId),
|
|
lpThreadLocalBase(other.lpThreadLocalBase),
|
|
lpStartAddress(other.lpStartAddress),
|
|
registers(), //create new registers
|
|
stepCallbacks(other.stepCallbacks),
|
|
isSingleStepping(other.isSingleStepping),
|
|
isInternalStepping(other.isInternalStepping),
|
|
cbInternalStep(other.cbInternalStep)
|
|
{
|
|
}
|
|
|
|
Thread & Thread::operator=(const Thread& other)
|
|
{
|
|
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;
|
|
}
|
|
|
|
bool Thread::RegReadContext()
|
|
{
|
|
memset(&this->mOldContext, 0, sizeof(CONTEXT));
|
|
this->mOldContext.ContextFlags = CONTEXT_ALL; //TODO: granular control over what's required
|
|
if (GetThreadContext(this->hThread, &this->mOldContext))
|
|
{
|
|
this->registers.SetContext(this->mOldContext);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool Thread::RegWriteContext() const
|
|
{
|
|
//check if something actually changed
|
|
if (memcmp(&this->mOldContext, this->registers.GetContext(), sizeof(CONTEXT)) == 0)
|
|
return true;
|
|
//update the context
|
|
return !!SetThreadContext(this->hThread, this->registers.GetContext());
|
|
}
|
|
|
|
void Thread::StepInto()
|
|
{
|
|
registers.TrapFlag.Set();
|
|
isSingleStepping = true;
|
|
}
|
|
|
|
void Thread::StepInto(const StepCallback & cbStep)
|
|
{
|
|
StepInto();
|
|
|
|
auto target = cbStep.target<void()>();
|
|
for (const auto & cb : stepCallbacks)
|
|
{
|
|
if (target == cb.target<void()>())
|
|
{
|
|
puts("duplicate StepInto callback detected!");
|
|
return;
|
|
}
|
|
}
|
|
stepCallbacks.push_back(cbStep);
|
|
}
|
|
|
|
void Thread::StepInternal(const StepCallback & cbStep)
|
|
{
|
|
registers.TrapFlag.Set();
|
|
isInternalStepping = true;
|
|
cbInternalStep = cbStep;
|
|
}
|
|
}; |