mirror of https://github.com/x64dbg/GleeBug
remove lazy context
This commit is contained in:
parent
22c5c2189c
commit
0b18c04e1e
|
|
@ -2,6 +2,7 @@
|
||||||
#define DEBUGGER_GLOBAL_H
|
#define DEBUGGER_GLOBAL_H
|
||||||
|
|
||||||
#include "GleeBug.h"
|
#include "GleeBug.h"
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
//defines
|
//defines
|
||||||
#define GLEEBUG_HWBP_COUNT 4
|
#define GLEEBUG_HWBP_COUNT 4
|
||||||
|
|
@ -30,9 +31,9 @@ namespace GleeBug
|
||||||
typedef std::function<void(const BreakpointInfo & info)> BreakpointCallback;
|
typedef std::function<void(const BreakpointInfo & info)> BreakpointCallback;
|
||||||
|
|
||||||
//map typedefs
|
//map typedefs
|
||||||
typedef std::map<uint32, Process> ProcessMap;
|
typedef std::map<uint32, std::unique_ptr<Process>> ProcessMap;
|
||||||
typedef std::map<Range, Dll, RangeCompare> DllMap;
|
typedef std::map<Range, Dll, RangeCompare> DllMap;
|
||||||
typedef std::map<uint32, Thread> ThreadMap;
|
typedef std::map<uint32, std::unique_ptr<Thread>> ThreadMap;
|
||||||
typedef std::map<BreakpointKey, BreakpointInfo> BreakpointMap;
|
typedef std::map<BreakpointKey, BreakpointInfo> BreakpointMap;
|
||||||
typedef std::map<BreakpointKey, BreakpointCallback> BreakpointCallbackMap;
|
typedef std::map<BreakpointKey, BreakpointCallback> BreakpointCallbackMap;
|
||||||
typedef std::unordered_map<ptr, BreakpointMap::iterator> SoftwareBreakpointMap;
|
typedef std::unordered_map<ptr, BreakpointMap::iterator> SoftwareBreakpointMap;
|
||||||
|
|
|
||||||
|
|
@ -16,19 +16,19 @@ namespace GleeBug
|
||||||
|
|
||||||
//process housekeeping
|
//process housekeeping
|
||||||
mProcesses.insert({ mDebugEvent.dwProcessId,
|
mProcesses.insert({ mDebugEvent.dwProcessId,
|
||||||
Process(createProcess.hProcess,
|
std::make_unique<Process>(createProcess.hProcess,
|
||||||
mDebugEvent.dwProcessId,
|
mDebugEvent.dwProcessId,
|
||||||
mDebugEvent.dwThreadId,
|
mDebugEvent.dwThreadId,
|
||||||
createProcess) });
|
createProcess) });
|
||||||
mProcess = &mProcesses.find(mDebugEvent.dwProcessId)->second;
|
mProcess = mProcesses.find(mDebugEvent.dwProcessId)->second.get();
|
||||||
|
|
||||||
//thread housekeeping (main thread is created implicitly)
|
//thread housekeeping (main thread is created implicitly)
|
||||||
mProcess->threads.insert({ mDebugEvent.dwThreadId,
|
mProcess->threads.insert({ mDebugEvent.dwThreadId,
|
||||||
Thread(createProcess.hThread,
|
std::make_unique<Thread>(createProcess.hThread,
|
||||||
mDebugEvent.dwThreadId,
|
mDebugEvent.dwThreadId,
|
||||||
createProcess.lpThreadLocalBase,
|
createProcess.lpThreadLocalBase,
|
||||||
createProcess.lpStartAddress) });
|
createProcess.lpStartAddress) });
|
||||||
mThread = mProcess->thread = &mProcess->threads.find(mDebugEvent.dwThreadId)->second;
|
mThread = mProcess->thread = mProcess->threads.find(mDebugEvent.dwThreadId)->second.get();
|
||||||
mRegisters = &mThread->registers;
|
mRegisters = &mThread->registers;
|
||||||
|
|
||||||
//read thread context from main thread
|
//read thread context from main thread
|
||||||
|
|
|
||||||
|
|
@ -6,13 +6,13 @@ namespace GleeBug
|
||||||
{
|
{
|
||||||
//thread housekeeping
|
//thread housekeeping
|
||||||
mProcess->threads.insert({ mDebugEvent.dwThreadId,
|
mProcess->threads.insert({ mDebugEvent.dwThreadId,
|
||||||
Thread(createThread.hThread,
|
std::make_unique<Thread>(createThread.hThread,
|
||||||
mDebugEvent.dwThreadId,
|
mDebugEvent.dwThreadId,
|
||||||
createThread.lpThreadLocalBase,
|
createThread.lpThreadLocalBase,
|
||||||
createThread.lpStartAddress) });
|
createThread.lpStartAddress) });
|
||||||
|
|
||||||
//set the current thread
|
//set the current thread
|
||||||
mThread = mProcess->thread = &mProcess->threads.find(mDebugEvent.dwThreadId)->second;
|
mThread = mProcess->thread = mProcess->threads.find(mDebugEvent.dwThreadId)->second.get();
|
||||||
mRegisters = &mThread->registers;
|
mRegisters = &mThread->registers;
|
||||||
if (!mThread->RegReadContext())
|
if (!mThread->RegReadContext())
|
||||||
cbInternalError("Thread::RegReadContext() failed!");
|
cbInternalError("Thread::RegReadContext() failed!");
|
||||||
|
|
|
||||||
|
|
@ -38,11 +38,11 @@ namespace GleeBug
|
||||||
auto processFound = mProcesses.find(mDebugEvent.dwProcessId);
|
auto processFound = mProcesses.find(mDebugEvent.dwProcessId);
|
||||||
if (processFound != mProcesses.end())
|
if (processFound != mProcesses.end())
|
||||||
{
|
{
|
||||||
mProcess = &processFound->second;
|
mProcess = processFound->second.get();
|
||||||
auto threadFound = mProcess->threads.find(mDebugEvent.dwThreadId);
|
auto threadFound = mProcess->threads.find(mDebugEvent.dwThreadId);
|
||||||
if (threadFound != mProcess->threads.end())
|
if (threadFound != mProcess->threads.end())
|
||||||
{
|
{
|
||||||
mThread = mProcess->thread = &threadFound->second;
|
mThread = mProcess->thread = threadFound->second.get();
|
||||||
mRegisters = &mThread->registers;
|
mRegisters = &mThread->registers;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,7 @@ namespace GleeBug
|
||||||
bool success = true;
|
bool success = true;
|
||||||
for (auto & thread : threads)
|
for (auto & thread : threads)
|
||||||
{
|
{
|
||||||
if (!thread.second.SetHardwareBreakpoint(address, slot, type, size))
|
if (!thread.second->SetHardwareBreakpoint(address, slot, type, size))
|
||||||
{
|
{
|
||||||
success = false;
|
success = false;
|
||||||
break;
|
break;
|
||||||
|
|
@ -111,7 +111,7 @@ namespace GleeBug
|
||||||
if (!success)
|
if (!success)
|
||||||
{
|
{
|
||||||
for (auto & thread : threads)
|
for (auto & thread : threads)
|
||||||
thread.second.DeleteHardwareBreakpoint(slot);
|
thread.second->DeleteHardwareBreakpoint(slot);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -161,7 +161,7 @@ namespace GleeBug
|
||||||
bool success = true;
|
bool success = true;
|
||||||
for (auto & thread : threads)
|
for (auto & thread : threads)
|
||||||
{
|
{
|
||||||
if (!thread.second.DeleteHardwareBreakpoint(info.internal.hardware.slot))
|
if (!thread.second->DeleteHardwareBreakpoint(info.internal.hardware.slot))
|
||||||
success = false;
|
success = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ namespace GleeBug
|
||||||
bool systemBreakpoint;
|
bool systemBreakpoint;
|
||||||
bool permanentDep;
|
bool permanentDep;
|
||||||
|
|
||||||
ThreadMap threads; //DO NOT COPY THESE OBJECTS!
|
ThreadMap threads;
|
||||||
DllMap dlls;
|
DllMap dlls;
|
||||||
BreakpointMap breakpoints;
|
BreakpointMap breakpoints;
|
||||||
SoftwareBreakpointMap softwareBreakpointReferences;
|
SoftwareBreakpointMap softwareBreakpointReferences;
|
||||||
|
|
@ -42,6 +42,11 @@ namespace GleeBug
|
||||||
*/
|
*/
|
||||||
explicit Process(HANDLE hProcess, uint32 dwProcessId, uint32 dwMainThreadId, const CREATE_PROCESS_DEBUG_INFO & createProcessInfo);
|
explicit Process(HANDLE hProcess, uint32 dwProcessId, uint32 dwMainThreadId, const CREATE_PROCESS_DEBUG_INFO & createProcessInfo);
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Copy constructor.
|
||||||
|
*/
|
||||||
|
Process(const Process &) = delete;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Read memory from the process.
|
\brief Read memory from the process.
|
||||||
\param address The virtual address to read from.
|
\param address The virtual address to read from.
|
||||||
|
|
@ -397,7 +402,7 @@ namespace GleeBug
|
||||||
{
|
{
|
||||||
auto result = true;
|
auto result = true;
|
||||||
for(auto & thread : this->threads)
|
for(auto & thread : this->threads)
|
||||||
if(!thread.second.RegReadContext())
|
if(!thread.second->RegReadContext())
|
||||||
result = false;
|
result = false;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
@ -406,7 +411,7 @@ namespace GleeBug
|
||||||
{
|
{
|
||||||
auto result = true;
|
auto result = true;
|
||||||
for(auto & thread : this->threads)
|
for(auto & thread : this->threads)
|
||||||
if(!thread.second.RegWriteContext())
|
if(!thread.second->RegWriteContext())
|
||||||
result = false;
|
result = false;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,11 @@ namespace GleeBug
|
||||||
*/
|
*/
|
||||||
Registers();
|
Registers();
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Copy constructor.
|
||||||
|
*/
|
||||||
|
Registers(const Registers &) = delete;
|
||||||
|
|
||||||
#include "Debugger.Thread.Registers.Register.h"
|
#include "Debugger.Thread.Registers.Register.h"
|
||||||
|
|
||||||
Register<R::DR0, ptr> Dr0;
|
Register<R::DR0, ptr> Dr0;
|
||||||
|
|
|
||||||
|
|
@ -13,40 +13,18 @@ namespace GleeBug
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
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()
|
bool Thread::RegReadContext()
|
||||||
{
|
{
|
||||||
memset(&this->mOldContext, 0, sizeof(CONTEXT));
|
memset(&this->mOldContext, 0, sizeof(CONTEXT));
|
||||||
this->mOldContext.ContextFlags = CONTEXT_ALL; //TODO: granular control over what's required
|
this->mOldContext.ContextFlags = CONTEXT_ALL; //TODO: granular control over what's required
|
||||||
this->registers.setContextLazy(&this->mOldContext, this->hThread);
|
if(GetThreadContext(this->hThread, &this->mOldContext))
|
||||||
|
{
|
||||||
|
this->registers.SetContext(this->mOldContext);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
__debugbreak();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool Thread::RegWriteContext()
|
bool Thread::RegWriteContext()
|
||||||
{
|
{
|
||||||
|
|
@ -54,7 +32,10 @@ namespace GleeBug
|
||||||
if (memcmp(&this->mOldContext, &this->registers.mContext, sizeof(CONTEXT)) == 0)
|
if (memcmp(&this->mOldContext, &this->registers.mContext, sizeof(CONTEXT)) == 0)
|
||||||
return true;
|
return true;
|
||||||
//update the context
|
//update the context
|
||||||
return !!SetThreadContext(this->hThread, &this->registers.mContext);
|
if(SetThreadContext(this->hThread, &this->registers.mContext))
|
||||||
|
return true;
|
||||||
|
__debugbreak();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Thread::StepInto()
|
void Thread::StepInto()
|
||||||
|
|
@ -85,4 +66,14 @@ namespace GleeBug
|
||||||
isInternalStepping = true;
|
isInternalStepping = true;
|
||||||
cbInternalStep = cbStep;
|
cbInternalStep = cbStep;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Thread::Suspend()
|
||||||
|
{
|
||||||
|
return SuspendThread(hThread) != -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Thread::Resume()
|
||||||
|
{
|
||||||
|
return ResumeThread(hThread) != -1;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -36,14 +36,7 @@ namespace GleeBug
|
||||||
/**
|
/**
|
||||||
\brief Copy constructor.
|
\brief Copy constructor.
|
||||||
*/
|
*/
|
||||||
Thread(const Thread & other);
|
Thread(const Thread & other) = delete;
|
||||||
|
|
||||||
/**
|
|
||||||
\brief Assignment operator.
|
|
||||||
\param other The other object.
|
|
||||||
\return A shallow copy of this object.
|
|
||||||
*/
|
|
||||||
Thread & operator=(const Thread & other);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Read the register context from the thread. This fills the RegistersInfo member.
|
\brief Read the register context from the thread. This fills the RegistersInfo member.
|
||||||
|
|
@ -117,6 +110,18 @@ namespace GleeBug
|
||||||
*/
|
*/
|
||||||
bool DeleteHardwareBreakpoint(HardwareSlot slot);
|
bool DeleteHardwareBreakpoint(HardwareSlot slot);
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Suspends this thread.
|
||||||
|
\return true if it succeeds, false if it fails.
|
||||||
|
*/
|
||||||
|
bool Suspend();
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Resumes this thread.
|
||||||
|
\return true if it succeeds, false if it fails.
|
||||||
|
*/
|
||||||
|
bool Resume();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CONTEXT mOldContext;
|
CONTEXT mOldContext;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,11 @@ namespace GleeBug
|
||||||
*/
|
*/
|
||||||
Debugger();
|
Debugger();
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Copy constructor.
|
||||||
|
*/
|
||||||
|
Debugger(const Debugger &) = delete;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Destructs the Debugger instance.
|
\brief Destructs the Debugger instance.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -240,6 +240,32 @@ public:
|
||||||
mThread->StepInto(STEPCALLBACK(CallBack));
|
mThread->StepInto(STEPCALLBACK(CallBack));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ThreadSuspender
|
||||||
|
{
|
||||||
|
ThreadSuspender(Thread* thread, bool running, bool writeRegs)
|
||||||
|
: thread(running ? thread : nullptr), writeRegs(writeRegs)
|
||||||
|
{
|
||||||
|
if(this->thread)
|
||||||
|
{
|
||||||
|
this->thread->Suspend();
|
||||||
|
this->thread->RegReadContext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~ThreadSuspender()
|
||||||
|
{
|
||||||
|
if(this->thread)
|
||||||
|
{
|
||||||
|
if(this->writeRegs)
|
||||||
|
this->thread->RegWriteContext();
|
||||||
|
this->thread->Resume();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Thread* thread;
|
||||||
|
bool writeRegs;
|
||||||
|
};
|
||||||
|
|
||||||
//Registers
|
//Registers
|
||||||
ULONG_PTR GetContextDataEx(HANDLE hActiveThread, DWORD IndexOfRegister)
|
ULONG_PTR GetContextDataEx(HANDLE hActiveThread, DWORD IndexOfRegister)
|
||||||
{
|
{
|
||||||
|
|
@ -248,8 +274,7 @@ public:
|
||||||
auto thread = threadFromHandle(hActiveThread);
|
auto thread = threadFromHandle(hActiveThread);
|
||||||
if(!thread)
|
if(!thread)
|
||||||
return 0;
|
return 0;
|
||||||
if(mIsRunning)
|
ThreadSuspender suspender(thread, mIsRunning, false);
|
||||||
thread->RegReadContext();
|
|
||||||
return thread->registers.Get(registerFromDword(IndexOfRegister));
|
return thread->registers.Get(registerFromDword(IndexOfRegister));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -258,11 +283,8 @@ public:
|
||||||
auto thread = threadFromHandle(hActiveThread);
|
auto thread = threadFromHandle(hActiveThread);
|
||||||
if (!thread)
|
if (!thread)
|
||||||
return false;
|
return false;
|
||||||
if(mIsRunning)
|
ThreadSuspender suspender(thread, mIsRunning, true);
|
||||||
thread->RegReadContext();
|
|
||||||
thread->registers.Set(registerFromDword(IndexOfRegister), NewRegisterValue);
|
thread->registers.Set(registerFromDword(IndexOfRegister), NewRegisterValue);
|
||||||
if(mIsRunning)
|
|
||||||
thread->RegWriteContext();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -273,8 +295,7 @@ public:
|
||||||
auto thread = threadFromHandle(hActiveThread);
|
auto thread = threadFromHandle(hActiveThread);
|
||||||
if (!thread || !titcontext)
|
if (!thread || !titcontext)
|
||||||
return false;
|
return false;
|
||||||
if(mIsRunning)
|
ThreadSuspender suspender(thread, mIsRunning, false);
|
||||||
thread->RegReadContext();
|
|
||||||
memset(titcontext, 0, sizeof(TITAN_ENGINE_CONTEXT_t));
|
memset(titcontext, 0, sizeof(TITAN_ENGINE_CONTEXT_t));
|
||||||
auto context = thread->registers.GetContext();
|
auto context = thread->registers.GetContext();
|
||||||
titcontext->cax = thread->registers.Gax();
|
titcontext->cax = thread->registers.Gax();
|
||||||
|
|
@ -317,8 +338,7 @@ public:
|
||||||
auto thread = threadFromHandle(hActiveThread);
|
auto thread = threadFromHandle(hActiveThread);
|
||||||
if (!thread || !titcontext)
|
if (!thread || !titcontext)
|
||||||
return false;
|
return false;
|
||||||
if(mIsRunning)
|
ThreadSuspender suspender(thread, mIsRunning, true);
|
||||||
thread->RegReadContext();
|
|
||||||
thread->registers.Gax = titcontext->cax;
|
thread->registers.Gax = titcontext->cax;
|
||||||
thread->registers.Gcx = titcontext->ccx;
|
thread->registers.Gcx = titcontext->ccx;
|
||||||
thread->registers.Gdx = titcontext->cdx;
|
thread->registers.Gdx = titcontext->cdx;
|
||||||
|
|
@ -353,8 +373,6 @@ public:
|
||||||
context.SegCs = titcontext->cs;
|
context.SegCs = titcontext->cs;
|
||||||
context.SegSs = titcontext->ss;
|
context.SegSs = titcontext->ss;
|
||||||
thread->registers.SetContext(context);
|
thread->registers.SetContext(context);
|
||||||
if(mIsRunning)
|
|
||||||
thread->RegWriteContext();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -572,16 +590,25 @@ public:
|
||||||
{
|
{
|
||||||
if (!mProcess)
|
if (!mProcess)
|
||||||
return false;
|
return false;
|
||||||
if(mIsRunning)
|
auto running = mIsRunning;
|
||||||
|
if(running)
|
||||||
|
{
|
||||||
|
for(auto & thread : mProcess->threads)
|
||||||
|
thread.second->Suspend();
|
||||||
mProcess->RegReadContext();
|
mProcess->RegReadContext();
|
||||||
|
}
|
||||||
if(!mProcess->SetHardwareBreakpoint(bpxAddress,
|
if(!mProcess->SetHardwareBreakpoint(bpxAddress,
|
||||||
(HardwareSlot)IndexOfRegister, [bpxCallBack](const BreakpointInfo & info)
|
(HardwareSlot)IndexOfRegister, [bpxCallBack](const BreakpointInfo & info)
|
||||||
{
|
{
|
||||||
(HWBPCALLBACK(bpxCallBack))((const void*)info.address);
|
(HWBPCALLBACK(bpxCallBack))((const void*)info.address);
|
||||||
}, hwtypeFromTitan(bpxType), hwsizeFromTitan(bpxSize)))
|
}, hwtypeFromTitan(bpxType), hwsizeFromTitan(bpxSize)))
|
||||||
return false;
|
return false;
|
||||||
if(mIsRunning)
|
if(running)
|
||||||
|
{
|
||||||
mProcess->RegWriteContext();
|
mProcess->RegWriteContext();
|
||||||
|
for(auto & thread : mProcess->threads)
|
||||||
|
thread.second->Resume();
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -622,9 +649,9 @@ public:
|
||||||
{
|
{
|
||||||
for(auto & it : mProcesses)
|
for(auto & it : mProcesses)
|
||||||
{
|
{
|
||||||
auto breakpoints = it.second.breakpoints; //explicit copy
|
auto breakpoints = it.second->breakpoints; //explicit copy
|
||||||
for(const auto & jt : breakpoints)
|
for(const auto & jt : breakpoints)
|
||||||
it.second.DeleteGenericBreakpoint(jt.second);
|
it.second->DeleteGenericBreakpoint(jt.second);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -756,10 +783,10 @@ private: //functions
|
||||||
auto foundP = mProcesses.find(uint32(tbi.ClientId.UniqueProcess));
|
auto foundP = mProcesses.find(uint32(tbi.ClientId.UniqueProcess));
|
||||||
if(foundP == mProcesses.end())
|
if(foundP == mProcesses.end())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
auto foundT = foundP->second.threads.find(uint32(tbi.ClientId.UniqueThread));
|
auto foundT = foundP->second->threads.find(uint32(tbi.ClientId.UniqueThread));
|
||||||
if(foundT == foundP->second.threads.end())
|
if(foundT == foundP->second->threads.end())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
return &foundT->second;
|
return foundT->second.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
Process* processFromHandle(HANDLE hProcess)
|
Process* processFromHandle(HANDLE hProcess)
|
||||||
|
|
@ -767,7 +794,7 @@ private: //functions
|
||||||
auto foundP = mProcesses.find(GetProcessId(hProcess));
|
auto foundP = mProcesses.find(GetProcessId(hProcess));
|
||||||
if(foundP == mProcesses.end())
|
if(foundP == mProcesses.end())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
return &foundP->second;
|
return foundP->second.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
static HardwareType hwtypeFromTitan(DWORD type)
|
static HardwareType hwtypeFromTitan(DWORD type)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue