mirror of https://github.com/x64dbg/GleeBug
some very amazing coding was done here (documentation + RegistersInfo with cache)
This commit is contained in:
parent
aa38b3e721
commit
c1bb981c16
|
|
@ -14,7 +14,17 @@ namespace GleeBug
|
||||||
DWORD sizeOfImage;
|
DWORD sizeOfImage;
|
||||||
ULONG_PTR entryPoint;
|
ULONG_PTR entryPoint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Default constructor.
|
||||||
|
*/
|
||||||
DllInfo();
|
DllInfo();
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Constructor.
|
||||||
|
\param lpBaseOfDll The base of DLL.
|
||||||
|
\param sizeOfImage Size of the image.
|
||||||
|
\param entryPoint The entry point.
|
||||||
|
*/
|
||||||
DllInfo(LPVOID lpBaseOfDll, DWORD sizeOfImage, LPVOID entryPoint);
|
DllInfo(LPVOID lpBaseOfDll, DWORD sizeOfImage, LPVOID entryPoint);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ namespace GleeBug
|
||||||
|
|
||||||
//set the current thread
|
//set the current thread
|
||||||
_curProcess->curThread = &_curProcess->threads[thread.dwThreadId];
|
_curProcess->curThread = &_curProcess->threads[thread.dwThreadId];
|
||||||
|
_curProcess->curThread->RegReadContext();
|
||||||
|
|
||||||
//call the debug event callback
|
//call the debug event callback
|
||||||
cbCreateThreadEvent(createThread, *_curProcess->curThread);
|
cbCreateThreadEvent(createThread, *_curProcess->curThread);
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,10 @@ namespace GleeBug
|
||||||
{
|
{
|
||||||
_curProcess = &_processes[_debugEvent.dwProcessId];
|
_curProcess = &_processes[_debugEvent.dwProcessId];
|
||||||
if (_curProcess->threads.count(_debugEvent.dwThreadId))
|
if (_curProcess->threads.count(_debugEvent.dwThreadId))
|
||||||
|
{
|
||||||
_curProcess->curThread = &_curProcess->threads[_debugEvent.dwThreadId];
|
_curProcess->curThread = &_curProcess->threads[_debugEvent.dwThreadId];
|
||||||
|
_curProcess->curThread->RegReadContext();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
_curProcess->curThread = nullptr;
|
_curProcess->curThread = nullptr;
|
||||||
}
|
}
|
||||||
|
|
@ -62,6 +65,10 @@ namespace GleeBug
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//write the register context
|
||||||
|
if (_curProcess->curThread)
|
||||||
|
_curProcess->curThread->RegWriteContext();
|
||||||
|
|
||||||
//continue the debug event
|
//continue the debug event
|
||||||
if (!ContinueDebugEvent(_debugEvent.dwProcessId, _debugEvent.dwThreadId, _continueStatus))
|
if (!ContinueDebugEvent(_debugEvent.dwProcessId, _debugEvent.dwThreadId, _continueStatus))
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -22,10 +22,39 @@ namespace GleeBug
|
||||||
ThreadMap threads;
|
ThreadMap threads;
|
||||||
DllMap dlls;
|
DllMap dlls;
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Default constructor.
|
||||||
|
*/
|
||||||
ProcessInfo();
|
ProcessInfo();
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Constructor.
|
||||||
|
\param dwProcessId Identifier for the process.
|
||||||
|
\param dwMainThreadId Identifier for the main thread.
|
||||||
|
*/
|
||||||
ProcessInfo(DWORD dwProcessId, DWORD dwMainThreadId);
|
ProcessInfo(DWORD dwProcessId, DWORD dwMainThreadId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Destructor.
|
||||||
|
*/
|
||||||
~ProcessInfo();
|
~ProcessInfo();
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Read memory from the process.
|
||||||
|
\param address The virtual address to read from.
|
||||||
|
\param size The size to read.
|
||||||
|
\param [out] buffer Destination buffer. Cannot be null. May be filled partially on failure.
|
||||||
|
\return true if it succeeds, false if it fails.
|
||||||
|
*/
|
||||||
bool MemRead(ULONG_PTR address, const size_t size, void* buffer);
|
bool MemRead(ULONG_PTR address, const size_t size, void* buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Write memory to the process.
|
||||||
|
\param address The virtual address to write to.
|
||||||
|
\param size The size to write.
|
||||||
|
\param [in] buffer Source buffer. Cannot be null.
|
||||||
|
\return true if it succeeds, false if it fails.
|
||||||
|
*/
|
||||||
bool MemWrite(ULONG_PTR address, const size_t size, const void* buffer);
|
bool MemWrite(ULONG_PTR address, const size_t size, const void* buffer);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
#include "Debugger.Thread.Registers.h"
|
||||||
|
|
||||||
|
namespace GleeBug
|
||||||
|
{
|
||||||
|
RegistersInfo::RegistersInfo()
|
||||||
|
{
|
||||||
|
memset(&this->_context, 0, sizeof(CONTEXT));
|
||||||
|
}
|
||||||
|
|
||||||
|
const CONTEXT* RegistersInfo::GetContext()
|
||||||
|
{
|
||||||
|
return &_context;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RegistersInfo::SetContext(const CONTEXT & context)
|
||||||
|
{
|
||||||
|
this->_context = context;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,66 @@
|
||||||
|
#ifndef _DEBUGGER_THREAD_REGISTERS_H
|
||||||
|
#define _DEBUGGER_THREAD_REGISTERS_H
|
||||||
|
|
||||||
|
#include "Debugger.Global.h"
|
||||||
|
|
||||||
|
namespace GleeBug
|
||||||
|
{
|
||||||
|
CONTEXT;
|
||||||
|
/**
|
||||||
|
\brief Thread register context. #lovethetrash
|
||||||
|
*/
|
||||||
|
struct RegistersInfo
|
||||||
|
{
|
||||||
|
#ifdef _WIN64
|
||||||
|
ULONG_PTR & Rax = _context.Rax;
|
||||||
|
ULONG_PTR & Rbx = _context.Rbx;
|
||||||
|
ULONG_PTR & Rcx = _context.Rcx;
|
||||||
|
ULONG_PTR & Rdx = _context.Rdx;
|
||||||
|
ULONG_PTR & Rsi = _context.Rsi;
|
||||||
|
ULONG_PTR & Rdi = _context.Rdi;
|
||||||
|
ULONG_PTR & Rbp = _context.Rbp;
|
||||||
|
ULONG_PTR & Rsp = _context.Rsp;
|
||||||
|
ULONG_PTR & Rip = _context.Rip;
|
||||||
|
ULONG_PTR & R8 = _context.R8;
|
||||||
|
ULONG_PTR & R9 = _context.R9;
|
||||||
|
ULONG_PTR & R10 = _context.R10;
|
||||||
|
ULONG_PTR & R11 = _context.R11;
|
||||||
|
ULONG_PTR & R12 = _context.R12;
|
||||||
|
ULONG_PTR & R13 = _context.R13;
|
||||||
|
ULONG_PTR & R14 = _context.R14;
|
||||||
|
ULONG_PTR & R15 = _context.R15;
|
||||||
|
#else //x86
|
||||||
|
ULONG_PTR & Eax = _context.Eax;
|
||||||
|
ULONG_PTR & Ebx = _context.Ebx;
|
||||||
|
ULONG_PTR & Ecx = _context.Ecx;
|
||||||
|
ULONG_PTR & Edx = _context.Edx;
|
||||||
|
ULONG_PTR & Esi = _context.Esi;
|
||||||
|
ULONG_PTR & Edi = _context.Edi;
|
||||||
|
ULONG_PTR & Ebp = _context.Ebp;
|
||||||
|
ULONG_PTR & Esp = _context.Esp;
|
||||||
|
ULONG_PTR & Eip = _context.Eip;
|
||||||
|
#endif //_WIN64
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Default constructor.
|
||||||
|
*/
|
||||||
|
RegistersInfo();
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Gets a pointer to the context object.
|
||||||
|
\return This function will never return a nullptr.
|
||||||
|
*/
|
||||||
|
const CONTEXT* GetContext();
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Sets the CONTEXT.
|
||||||
|
\param context The context to set.
|
||||||
|
*/
|
||||||
|
void SetContext(const CONTEXT & context);
|
||||||
|
|
||||||
|
private:
|
||||||
|
CONTEXT _context;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //_DEBUGGER_THREAD_REGISTERS_H
|
||||||
|
|
@ -18,6 +18,33 @@ namespace GleeBug
|
||||||
ThreadInfo::~ThreadInfo()
|
ThreadInfo::~ThreadInfo()
|
||||||
{
|
{
|
||||||
if (this->hThread != INVALID_HANDLE_VALUE)
|
if (this->hThread != INVALID_HANDLE_VALUE)
|
||||||
CloseHandle(hThread);
|
CloseHandle(this->hThread);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ThreadInfo::RegReadContext()
|
||||||
|
{
|
||||||
|
SuspendThread(this->hThread);
|
||||||
|
memset(&this->_oldContext, 0, sizeof(CONTEXT));
|
||||||
|
this->_oldContext.ContextFlags = CONTEXT_ALL;
|
||||||
|
bool bReturn = false;
|
||||||
|
if (GetThreadContext(this->hThread, &this->_oldContext))
|
||||||
|
{
|
||||||
|
this->registers.SetContext(this->_oldContext);
|
||||||
|
bReturn = true;
|
||||||
|
}
|
||||||
|
ResumeThread(this->hThread);
|
||||||
|
return bReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ThreadInfo::RegWriteContext()
|
||||||
|
{
|
||||||
|
//check if something actually changed
|
||||||
|
if (memcmp(&this->_oldContext, this->registers.GetContext(), sizeof(CONTEXT)) == 0)
|
||||||
|
return true;
|
||||||
|
//update the context
|
||||||
|
SuspendThread(this->hThread);
|
||||||
|
bool bReturn = !!SetThreadContext(this->hThread, this->registers.GetContext());
|
||||||
|
ResumeThread(this->hThread);
|
||||||
|
return bReturn;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
#ifndef _DEBUGGER_THREADS_H
|
#ifndef _DEBUGGER_THREAD_H
|
||||||
#define _DEBUGGER_THREADS_H
|
#define _DEBUGGER_THREAD_H
|
||||||
|
|
||||||
#include "Debugger.Global.h"
|
#include "Debugger.Global.h"
|
||||||
|
#include "Debugger.Thread.Registers.h"
|
||||||
|
|
||||||
namespace GleeBug
|
namespace GleeBug
|
||||||
{
|
{
|
||||||
|
|
@ -14,10 +15,40 @@ namespace GleeBug
|
||||||
HANDLE hThread;
|
HANDLE hThread;
|
||||||
ULONG_PTR lpThreadLocalBase;
|
ULONG_PTR lpThreadLocalBase;
|
||||||
ULONG_PTR lpStartAddress;
|
ULONG_PTR lpStartAddress;
|
||||||
|
RegistersInfo registers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Default constructor.
|
||||||
|
*/
|
||||||
ThreadInfo();
|
ThreadInfo();
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Constructor.
|
||||||
|
\param dwThreadId Identifier for the thread.
|
||||||
|
\param lpThreadLocalBase The thread local base.
|
||||||
|
\param lpStartAddress The start address.
|
||||||
|
*/
|
||||||
ThreadInfo(DWORD dwThreadId, LPVOID lpThreadLocalBase, LPVOID lpStartAddress);
|
ThreadInfo(DWORD dwThreadId, LPVOID lpThreadLocalBase, LPVOID lpStartAddress);
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Destructor.
|
||||||
|
*/
|
||||||
~ThreadInfo();
|
~ThreadInfo();
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Read the register context from the thread. This fills the RegistersInfo member.
|
||||||
|
\return true if it succeeds, false if it fails.
|
||||||
|
*/
|
||||||
|
bool RegReadContext();
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Write the register context to the thread. This does nothing if the RegistersInfo member did not change.
|
||||||
|
\return true if it succeeds, false if it fails.
|
||||||
|
*/
|
||||||
|
bool RegWriteContext();
|
||||||
|
|
||||||
|
private:
|
||||||
|
CONTEXT _oldContext;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::map<DWORD, ThreadInfo> ThreadMap;
|
typedef std::map<DWORD, ThreadInfo> ThreadMap;
|
||||||
|
|
|
||||||
|
|
@ -113,6 +113,12 @@ namespace GleeBug
|
||||||
*/
|
*/
|
||||||
virtual void cbSystemBreakpoint() {};
|
virtual void cbSystemBreakpoint() {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Internal error callback. Provide an implementation to use this callback.
|
||||||
|
\param error The error message.
|
||||||
|
*/
|
||||||
|
virtual void cbInternalError(const std::string & error) {};
|
||||||
|
|
||||||
protected: //core debug event handlers
|
protected: //core debug event handlers
|
||||||
/**
|
/**
|
||||||
\brief Process creation debug event. Do not override this unless you know what you are doing!
|
\brief Process creation debug event. Do not override this unless you know what you are doing!
|
||||||
|
|
|
||||||
|
|
@ -157,6 +157,7 @@
|
||||||
<ClCompile Include="Debugger.Loop.Thread.cpp" />
|
<ClCompile Include="Debugger.Loop.Thread.cpp" />
|
||||||
<ClCompile Include="Debugger.Process.cpp" />
|
<ClCompile Include="Debugger.Process.cpp" />
|
||||||
<ClCompile Include="Debugger.Thread.cpp" />
|
<ClCompile Include="Debugger.Thread.cpp" />
|
||||||
|
<ClCompile Include="Debugger.Thread.Registers.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="Debugger.Dll.h" />
|
<ClInclude Include="Debugger.Dll.h" />
|
||||||
|
|
@ -164,6 +165,7 @@
|
||||||
<ClInclude Include="Debugger.h" />
|
<ClInclude Include="Debugger.h" />
|
||||||
<ClInclude Include="Debugger.Thread.h" />
|
<ClInclude Include="Debugger.Thread.h" />
|
||||||
<ClInclude Include="Debugger.Global.h" />
|
<ClInclude Include="Debugger.Global.h" />
|
||||||
|
<ClInclude Include="Debugger.Thread.Registers.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,9 @@
|
||||||
<ClCompile Include="Debugger.Loop.Rip.cpp">
|
<ClCompile Include="Debugger.Loop.Rip.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="Debugger.Thread.Registers.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="Debugger.h">
|
<ClInclude Include="Debugger.h">
|
||||||
|
|
@ -65,5 +68,8 @@
|
||||||
<ClInclude Include="Debugger.Global.h">
|
<ClInclude Include="Debugger.Global.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="Debugger.Thread.Registers.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
@ -55,7 +55,7 @@ protected:
|
||||||
|
|
||||||
virtual void cbSystemBreakpoint()
|
virtual void cbSystemBreakpoint()
|
||||||
{
|
{
|
||||||
printf("System breakpoint reached!");
|
printf("System breakpoint reached!\n");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue