mirror of https://github.com/x64dbg/GleeBug
register getter/setter functions should be working + refactoring
This commit is contained in:
parent
2481e33abd
commit
424edbc226
|
|
@ -0,0 +1,2 @@
|
||||||
|
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||||
|
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPrintfBadFormat/@EntryIndexedValue">DO_NOT_SHOW</s:String></wpf:ResourceDictionary>
|
||||||
|
|
@ -6,10 +6,10 @@ namespace GleeBug
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
DllInfo::DllInfo(LPVOID lpBaseOfDll, ULONG_PTR sizeOfImage, LPVOID entryPoint)
|
DllInfo::DllInfo(LPVOID lpBaseOfDll, ptr sizeOfImage, LPVOID entryPoint)
|
||||||
{
|
{
|
||||||
this->lpBaseOfDll = reinterpret_cast<ULONG_PTR>(lpBaseOfDll);
|
this->lpBaseOfDll = ptr(lpBaseOfDll);
|
||||||
this->sizeOfImage = sizeOfImage;
|
this->sizeOfImage = sizeOfImage;
|
||||||
this->entryPoint = reinterpret_cast<ULONG_PTR>(entryPoint);
|
this->entryPoint = ptr(entryPoint);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -11,9 +11,9 @@ namespace GleeBug
|
||||||
class DllInfo
|
class DllInfo
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ULONG_PTR lpBaseOfDll;
|
ptr lpBaseOfDll;
|
||||||
ULONG_PTR sizeOfImage;
|
ptr sizeOfImage;
|
||||||
ULONG_PTR entryPoint;
|
ptr entryPoint;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Default constructor.
|
\brief Default constructor.
|
||||||
|
|
@ -26,7 +26,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, ULONG_PTR sizeOfImage, LPVOID entryPoint);
|
DllInfo(LPVOID lpBaseOfDll, ptr sizeOfImage, LPVOID entryPoint);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,29 +1,10 @@
|
||||||
#ifndef _DEBUGGER_GLOBAL_H
|
#ifndef _DEBUGGER_GLOBAL_H
|
||||||
#define _DEBUGGER_GLOBAL_H
|
#define _DEBUGGER_GLOBAL_H
|
||||||
|
|
||||||
#include <cstdio>
|
#include "GleeBug.h"
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
#include <unordered_map>
|
|
||||||
#include <map>
|
|
||||||
#include <set>
|
|
||||||
#include <functional>
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
#include <psapi.h>
|
|
||||||
|
|
||||||
namespace GleeBug
|
namespace GleeBug
|
||||||
{
|
{
|
||||||
typedef std::pair<ULONG_PTR, ULONG_PTR> Range;
|
|
||||||
|
|
||||||
struct RangeCompare
|
|
||||||
{
|
|
||||||
inline bool operator()(const Range & a, const Range & b) const //a before b?
|
|
||||||
{
|
|
||||||
return a.second < b.first;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//forward declarations
|
//forward declarations
|
||||||
class Debugger;
|
class Debugger;
|
||||||
class ProcessInfo;
|
class ProcessInfo;
|
||||||
|
|
@ -31,18 +12,15 @@ namespace GleeBug
|
||||||
class ThreadInfo;
|
class ThreadInfo;
|
||||||
|
|
||||||
//map typedefs
|
//map typedefs
|
||||||
typedef std::map<DWORD, ProcessInfo> ProcessMap;
|
typedef std::map<uint32, ProcessInfo> ProcessMap;
|
||||||
typedef std::map<Range, DllInfo, RangeCompare> DllMap;
|
typedef std::map<Range, DllInfo, RangeCompare> DllMap;
|
||||||
typedef std::map<DWORD, ThreadInfo> ThreadMap;
|
typedef std::map<uint32, ThreadInfo> ThreadMap;
|
||||||
|
|
||||||
//callback function typedefs
|
//callback function typedefs
|
||||||
typedef std::function<void()> StepCallback;
|
typedef std::function<void()> StepCallback;
|
||||||
|
|
||||||
//vector typedefs
|
//vector typedefs
|
||||||
typedef std::vector<StepCallback> StepCallbackVector;
|
typedef std::vector<StepCallback> StepCallbackVector;
|
||||||
|
|
||||||
//macros
|
|
||||||
#define BIND(thisPtr, funcPtr) std::bind(&funcPtr, thisPtr)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //_DEBUGGER_GLOBAL_H
|
#endif //_DEBUGGER_GLOBAL_H
|
||||||
|
|
@ -24,7 +24,7 @@ namespace GleeBug
|
||||||
void Debugger::unloadDllEvent(const UNLOAD_DLL_DEBUG_INFO & unloadDll)
|
void Debugger::unloadDllEvent(const UNLOAD_DLL_DEBUG_INFO & unloadDll)
|
||||||
{
|
{
|
||||||
//call the debug event callback
|
//call the debug event callback
|
||||||
ULONG_PTR lpBaseOfDll = reinterpret_cast<ULONG_PTR>(unloadDll.lpBaseOfDll);
|
ptr lpBaseOfDll = ptr(unloadDll.lpBaseOfDll);
|
||||||
auto dll = _process->dlls.find(Range(lpBaseOfDll, lpBaseOfDll));
|
auto dll = _process->dlls.find(Range(lpBaseOfDll, lpBaseOfDll));
|
||||||
if (dll != _process->dlls.end())
|
if (dll != _process->dlls.end())
|
||||||
cbUnloadDllEvent(unloadDll, dll->second);
|
cbUnloadDllEvent(unloadDll, dll->second);
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ namespace GleeBug
|
||||||
createProcess.lpStartAddress);
|
createProcess.lpStartAddress);
|
||||||
_process->threads.insert({ thread.dwThreadId, thread });
|
_process->threads.insert({ thread.dwThreadId, thread });
|
||||||
_thread = _process->thread = &_process->threads.find(thread.dwThreadId)->second;
|
_thread = _process->thread = &_process->threads.find(thread.dwThreadId)->second;
|
||||||
|
_registers = &_thread->registers;
|
||||||
|
|
||||||
//read thread context from main thread
|
//read thread context from main thread
|
||||||
if (!_thread->RegReadContext())
|
if (!_thread->RegReadContext())
|
||||||
|
|
@ -44,5 +45,7 @@ namespace GleeBug
|
||||||
|
|
||||||
//set the current process
|
//set the current process
|
||||||
_process = nullptr;
|
_process = nullptr;
|
||||||
|
_thread = nullptr;
|
||||||
|
_registers = nullptr;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -10,6 +10,7 @@ namespace GleeBug
|
||||||
|
|
||||||
//set the current thread
|
//set the current thread
|
||||||
_thread = _process->thread = &_process->threads.find(_debugEvent.dwThreadId)->second;
|
_thread = _process->thread = &_process->threads.find(_debugEvent.dwThreadId)->second;
|
||||||
|
_registers = &_thread->registers;
|
||||||
if (!_thread->RegReadContext())
|
if (!_thread->RegReadContext())
|
||||||
cbInternalError("ThreadInfo::RegReadContext() failed!");
|
cbInternalError("ThreadInfo::RegReadContext() failed!");
|
||||||
|
|
||||||
|
|
@ -27,5 +28,6 @@ namespace GleeBug
|
||||||
|
|
||||||
//set the current thread
|
//set the current thread
|
||||||
_thread = _process->thread = nullptr;
|
_thread = _process->thread = nullptr;
|
||||||
|
_registers = nullptr;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -25,14 +25,22 @@ namespace GleeBug
|
||||||
if (_process->threads.count(_debugEvent.dwThreadId))
|
if (_process->threads.count(_debugEvent.dwThreadId))
|
||||||
{
|
{
|
||||||
_thread = _process->thread = &_process->threads[_debugEvent.dwThreadId];
|
_thread = _process->thread = &_process->threads[_debugEvent.dwThreadId];
|
||||||
|
_registers = &_thread->registers;
|
||||||
if (!_thread->RegReadContext())
|
if (!_thread->RegReadContext())
|
||||||
cbInternalError("ThreadInfo::RegReadContext() failed!");
|
cbInternalError("ThreadInfo::RegReadContext() failed!");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
_thread = _process->thread = nullptr;
|
_thread = _process->thread = nullptr;
|
||||||
|
_registers = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
_process = nullptr;
|
_process = nullptr;
|
||||||
|
_thread = nullptr;
|
||||||
|
_registers = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
//dispatch the debug event
|
//dispatch the debug event
|
||||||
switch (_debugEvent.dwDebugEventCode)
|
switch (_debugEvent.dwDebugEventCode)
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ namespace GleeBug
|
||||||
this->hProcess = INVALID_HANDLE_VALUE;
|
this->hProcess = INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProcessInfo::ProcessInfo(DWORD dwProcessId, HANDLE hProcess, DWORD dwMainThreadId)
|
ProcessInfo::ProcessInfo(uint32 dwProcessId, HANDLE hProcess, uint32 dwMainThreadId)
|
||||||
{
|
{
|
||||||
this->systemBreakpoint = false;
|
this->systemBreakpoint = false;
|
||||||
this->hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
|
this->hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
|
||||||
|
|
@ -17,12 +17,12 @@ namespace GleeBug
|
||||||
this->dwMainThreadId = dwMainThreadId;
|
this->dwMainThreadId = dwMainThreadId;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ProcessInfo::MemRead(ULONG_PTR address, const size_t size, void* buffer)
|
bool ProcessInfo::MemRead(ptr address, const size_t size, void* buffer)
|
||||||
{
|
{
|
||||||
return !!ReadProcessMemory(this->hProcess, reinterpret_cast<const void*>(address), buffer, size, nullptr);
|
return !!ReadProcessMemory(this->hProcess, reinterpret_cast<const void*>(address), buffer, size, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ProcessInfo::MemWrite(ULONG_PTR address, const size_t size, const void* buffer)
|
bool ProcessInfo::MemWrite(ptr address, const size_t size, const void* buffer)
|
||||||
{
|
{
|
||||||
return !!WriteProcessMemory(this->hProcess, reinterpret_cast<void*>(address), buffer, size, nullptr);
|
return !!WriteProcessMemory(this->hProcess, reinterpret_cast<void*>(address), buffer, size, nullptr);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,8 @@ namespace GleeBug
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
HANDLE hProcess;
|
HANDLE hProcess;
|
||||||
DWORD dwProcessId;
|
uint32 dwProcessId;
|
||||||
DWORD dwMainThreadId;
|
uint32 dwMainThreadId;
|
||||||
|
|
||||||
ThreadInfo* thread;
|
ThreadInfo* thread;
|
||||||
bool systemBreakpoint;
|
bool systemBreakpoint;
|
||||||
|
|
@ -33,7 +33,7 @@ namespace GleeBug
|
||||||
\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(DWORD dwProcessId, HANDLE hProcess, DWORD dwMainThreadId);
|
ProcessInfo(uint32 dwProcessId, HANDLE hProcess, uint32 dwMainThreadId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Read memory from the process.
|
\brief Read memory from the process.
|
||||||
|
|
@ -42,7 +42,7 @@ namespace GleeBug
|
||||||
\param [out] buffer Destination buffer. Cannot be null. May be filled partially on failure.
|
\param [out] buffer Destination buffer. Cannot be null. May be filled partially on failure.
|
||||||
\return true if it succeeds, false if it fails.
|
\return true if it succeeds, false if it fails.
|
||||||
*/
|
*/
|
||||||
bool MemRead(ULONG_PTR address, const size_t size, void* buffer);
|
bool MemRead(ptr address, const size_t size, void* buffer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Write memory to the process.
|
\brief Write memory to the process.
|
||||||
|
|
@ -51,7 +51,7 @@ namespace GleeBug
|
||||||
\param [in] buffer Source buffer. Cannot be null.
|
\param [in] buffer Source buffer. Cannot be null.
|
||||||
\return true if it succeeds, false if it fails.
|
\return true if it succeeds, false if it fails.
|
||||||
*/
|
*/
|
||||||
bool MemWrite(ULONG_PTR address, const size_t size, const void* buffer);
|
bool MemWrite(ptr address, const size_t size, const void* buffer);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,503 @@
|
||||||
|
#include "Debugger.Thread.Registers.h"
|
||||||
|
|
||||||
|
#ifdef _WIN64
|
||||||
|
#define contextGax _context.Rax
|
||||||
|
#define contextGbx _context.Rbx
|
||||||
|
#define contextGcx _context.Rcx
|
||||||
|
#define contextGdx _context.Rdx
|
||||||
|
#define contextGdi _context.Rdi
|
||||||
|
#define contextGsi _context.Rsi
|
||||||
|
#define contextGbp _context.Rbp
|
||||||
|
#define contextGsp _context.Rsp
|
||||||
|
#define contextGip _context.Rip
|
||||||
|
#else //x32
|
||||||
|
#define contextGax _context.Eax
|
||||||
|
#define contextGbx _context.Ebx
|
||||||
|
#define contextGcx _context.Ecx
|
||||||
|
#define contextGdx _context.Edx
|
||||||
|
#define contextGdi _context.Edi
|
||||||
|
#define contextGsi _context.Esi
|
||||||
|
#define contextGbp _context.Ebp
|
||||||
|
#define contextGsp _context.Esp
|
||||||
|
#define contextGip _context.Eip
|
||||||
|
#endif //_WIN64
|
||||||
|
|
||||||
|
#ifdef _WIN64
|
||||||
|
#define uint32_lo(x) ptr(x & 0xFFFFFFFF)
|
||||||
|
#else //x32
|
||||||
|
#define uint32_lo(x) ptr(x)
|
||||||
|
#endif //_WIN64
|
||||||
|
#define uint16_lo(x) ptr(x & 0xFFFFFFFF)
|
||||||
|
#define uint8_hi(x) ptr((x >> 8) & 0xFF)
|
||||||
|
#define uint8_lo(x) ptr(x & 0xFF)
|
||||||
|
|
||||||
|
#ifdef _WIN64
|
||||||
|
#define set_uint32_lo(x, y) x = (x & ~0xFFFFFFFF) | uint32_lo(y)
|
||||||
|
#else //x32
|
||||||
|
#define set_uint32_lo(x, y) x = y
|
||||||
|
#endif //_WIN64
|
||||||
|
#define set_uint16_lo(x, y) x = (x & ~0xFFFF) | uint16_lo(y)
|
||||||
|
#define set_uint8_hi(x, y) x = (x & ~0xFF00) | (uint8_lo(y) << 8)
|
||||||
|
#define set_uint8_lo(x, y) x = (x & ~0xFF) | uint8_lo(y)
|
||||||
|
|
||||||
|
namespace GleeBug
|
||||||
|
{
|
||||||
|
ptr Registers::Get(R reg) const
|
||||||
|
{
|
||||||
|
switch (reg)
|
||||||
|
{
|
||||||
|
case R::DR0:
|
||||||
|
return ptr(_context.Dr0);
|
||||||
|
case R::DR1:
|
||||||
|
return ptr(_context.Dr1);
|
||||||
|
case R::DR2:
|
||||||
|
return ptr(_context.Dr2);
|
||||||
|
case R::DR3:
|
||||||
|
return ptr(_context.Dr3);
|
||||||
|
case R::DR6:
|
||||||
|
return ptr(_context.Dr6);
|
||||||
|
case R::DR7:
|
||||||
|
return ptr(_context.Dr7);
|
||||||
|
|
||||||
|
case R::EFlags:
|
||||||
|
return ptr(_context.EFlags);
|
||||||
|
|
||||||
|
case R::EAX:
|
||||||
|
return uint32_lo(contextGax);
|
||||||
|
case R::AX:
|
||||||
|
return uint16_lo(contextGax);
|
||||||
|
case R::AH:
|
||||||
|
return uint8_hi(contextGax);
|
||||||
|
case R::AL:
|
||||||
|
return uint8_lo(contextGax);
|
||||||
|
case R::EBX:
|
||||||
|
return uint32_lo(contextGbx);
|
||||||
|
case R::BX:
|
||||||
|
return uint16_lo(contextGbx);
|
||||||
|
case R::BH:
|
||||||
|
return uint8_hi(contextGbx);
|
||||||
|
case R::BL:
|
||||||
|
return uint8_lo(contextGbx);
|
||||||
|
case R::ECX:
|
||||||
|
return uint32_lo(contextGcx);
|
||||||
|
case R::CX:
|
||||||
|
return uint16_lo(contextGcx);
|
||||||
|
case R::CH:
|
||||||
|
return uint8_hi(contextGcx);
|
||||||
|
case R::CL:
|
||||||
|
return uint8_lo(contextGcx);
|
||||||
|
case R::EDX:
|
||||||
|
return uint32_lo(contextGdx);
|
||||||
|
case R::DX:
|
||||||
|
return uint16_lo(contextGdx);
|
||||||
|
case R::DH:
|
||||||
|
return uint8_hi(contextGdx);
|
||||||
|
case R::DL:
|
||||||
|
return uint8_lo(contextGdx);
|
||||||
|
case R::EDI:
|
||||||
|
return uint32_lo(contextGdi);
|
||||||
|
case R::DI:
|
||||||
|
return uint16_lo(contextGdi);
|
||||||
|
case R::ESI:
|
||||||
|
return uint32_lo(contextGsi);
|
||||||
|
case R::SI:
|
||||||
|
return uint16_lo(contextGsi);
|
||||||
|
case R::EBP:
|
||||||
|
return uint32_lo(contextGbp);
|
||||||
|
case R::BP:
|
||||||
|
return uint16_lo(contextGbp);
|
||||||
|
case R::ESP:
|
||||||
|
return uint32_lo(contextGsp);
|
||||||
|
case R::SP:
|
||||||
|
return uint16_lo(contextGsp);
|
||||||
|
case R::EIP:
|
||||||
|
return uint32_lo(contextGip);
|
||||||
|
|
||||||
|
#ifdef _WIN64
|
||||||
|
case R::RAX:
|
||||||
|
return ptr(_context.Rax);
|
||||||
|
case R::RBX:
|
||||||
|
return ptr(_context.Rbx);
|
||||||
|
case R::RCX:
|
||||||
|
return ptr(_context.Rcx);
|
||||||
|
case R::RDX:
|
||||||
|
return ptr(_context.Rdx);
|
||||||
|
case R::RSI:
|
||||||
|
return ptr(_context.Rsi);
|
||||||
|
case R::SIL:
|
||||||
|
return uint8_lo(_context.Rsi);
|
||||||
|
case R::RDI:
|
||||||
|
return ptr(_context.Rdi);
|
||||||
|
case R::DIL:
|
||||||
|
return uint8_lo(_context.Rdi);
|
||||||
|
case R::RBP:
|
||||||
|
return ptr(_context.Rbp);
|
||||||
|
case R::BPL:
|
||||||
|
return uint8_lo(_context.Rbp);
|
||||||
|
case R::RSP:
|
||||||
|
return ptr(_context.Rsp);
|
||||||
|
case R::SPL:
|
||||||
|
return uint8_lo(_context.Rsp);
|
||||||
|
case R::RIP:
|
||||||
|
return ptr(_context.Rip);
|
||||||
|
case R::R8:
|
||||||
|
return ptr(_context.R8);
|
||||||
|
case R::R8D:
|
||||||
|
return uint32_lo(_context.R8);
|
||||||
|
case R::R8W:
|
||||||
|
return uint16_lo(_context.R8);
|
||||||
|
case R::R8B:
|
||||||
|
return uint8_lo(_context.R8);
|
||||||
|
case R::R9:
|
||||||
|
return ptr(_context.R9);
|
||||||
|
case R::R9D:
|
||||||
|
return uint32_lo(_context.R9);
|
||||||
|
case R::R9W:
|
||||||
|
return uint16_lo(_context.R9);
|
||||||
|
case R::R9B:
|
||||||
|
return uint8_lo(_context.R9);
|
||||||
|
case R::R10:
|
||||||
|
return ptr(_context.R10);
|
||||||
|
case R::R10D:
|
||||||
|
return uint32_lo(_context.R10);
|
||||||
|
case R::R10W:
|
||||||
|
return uint16_lo(_context.R10);
|
||||||
|
case R::R10B:
|
||||||
|
return uint8_lo(_context.R10);
|
||||||
|
case R::R11:
|
||||||
|
return ptr(_context.R11);
|
||||||
|
case R::R11D:
|
||||||
|
return uint32_lo(_context.R11);
|
||||||
|
case R::R11W:
|
||||||
|
return uint16_lo(_context.R11);
|
||||||
|
case R::R11B:
|
||||||
|
return uint8_lo(_context.R11);
|
||||||
|
case R::R12:
|
||||||
|
return ptr(_context.R12);
|
||||||
|
case R::R12D:
|
||||||
|
return uint32_lo(_context.R12);
|
||||||
|
case R::R12W:
|
||||||
|
return uint16_lo(_context.R12);
|
||||||
|
case R::R12B:
|
||||||
|
return uint8_lo(_context.R12);
|
||||||
|
case R::R13:
|
||||||
|
return ptr(_context.R13);
|
||||||
|
case R::R13D:
|
||||||
|
return uint32_lo(_context.R13);
|
||||||
|
case R::R13W:
|
||||||
|
return uint16_lo(_context.R13);
|
||||||
|
case R::R13B:
|
||||||
|
return uint8_lo(_context.R13);
|
||||||
|
case R::R14:
|
||||||
|
return ptr(_context.R14);
|
||||||
|
case R::R14D:
|
||||||
|
return uint32_lo(_context.R14);
|
||||||
|
case R::R14W:
|
||||||
|
return uint16_lo(_context.R14);
|
||||||
|
case R::R14B:
|
||||||
|
return uint8_lo(_context.R14);
|
||||||
|
case R::R15:
|
||||||
|
return ptr(_context.R15);
|
||||||
|
case R::R15D:
|
||||||
|
return uint32_lo(_context.R15);
|
||||||
|
case R::R15W:
|
||||||
|
return uint16_lo(_context.R15);
|
||||||
|
case R::R15B:
|
||||||
|
return uint8_lo(_context.R15);
|
||||||
|
#endif //_WIN64
|
||||||
|
|
||||||
|
case R::GAX:
|
||||||
|
return ptr(contextGax);
|
||||||
|
case R::GBX:
|
||||||
|
return ptr(contextGbx);
|
||||||
|
case R::GCX:
|
||||||
|
return ptr(contextGcx);
|
||||||
|
case R::GDX:
|
||||||
|
return ptr(contextGdx);
|
||||||
|
case R::GDI:
|
||||||
|
return ptr(contextGdi);
|
||||||
|
case R::GSI:
|
||||||
|
return ptr(contextGsi);
|
||||||
|
case R::GBP:
|
||||||
|
return ptr(contextGbp);
|
||||||
|
case R::GSP:
|
||||||
|
return ptr(contextGsp);
|
||||||
|
case R::GIP:
|
||||||
|
return ptr(contextGip);
|
||||||
|
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Registers::Set(R reg, ptr value)
|
||||||
|
{
|
||||||
|
switch (reg)
|
||||||
|
{
|
||||||
|
case R::DR0:
|
||||||
|
_context.Dr0 = value;
|
||||||
|
break;
|
||||||
|
case R::DR1:
|
||||||
|
_context.Dr1 = value;
|
||||||
|
break;
|
||||||
|
case R::DR2:
|
||||||
|
_context.Dr2 = value;
|
||||||
|
break;
|
||||||
|
case R::DR3:
|
||||||
|
_context.Dr3 = value;
|
||||||
|
break;
|
||||||
|
case R::DR6:
|
||||||
|
_context.Dr6 = value;
|
||||||
|
break;
|
||||||
|
case R::DR7:
|
||||||
|
_context.Dr7 = value;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case R::EFlags:
|
||||||
|
_context.EFlags = (DWORD)value;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case R::EAX:
|
||||||
|
set_uint32_lo(contextGax, value);
|
||||||
|
break;
|
||||||
|
case R::AX:
|
||||||
|
set_uint16_lo(contextGax, value);
|
||||||
|
break;
|
||||||
|
case R::AH:
|
||||||
|
set_uint8_hi(contextGax, value);
|
||||||
|
break;
|
||||||
|
case R::AL:
|
||||||
|
set_uint8_lo(contextGax, value);
|
||||||
|
break;
|
||||||
|
case R::EBX:
|
||||||
|
set_uint32_lo(contextGbx, value);
|
||||||
|
break;
|
||||||
|
case R::BX:
|
||||||
|
set_uint16_lo(contextGbx, value);
|
||||||
|
break;
|
||||||
|
case R::BH:
|
||||||
|
set_uint8_hi(contextGbx, value);
|
||||||
|
break;
|
||||||
|
case R::BL:
|
||||||
|
set_uint8_lo(contextGbx, value);
|
||||||
|
break;
|
||||||
|
case R::ECX:
|
||||||
|
set_uint32_lo(contextGcx, value);
|
||||||
|
break;
|
||||||
|
case R::CX:
|
||||||
|
set_uint16_lo(contextGcx, value);
|
||||||
|
break;
|
||||||
|
case R::CH:
|
||||||
|
set_uint8_hi(contextGcx, value);
|
||||||
|
break;
|
||||||
|
case R::CL:
|
||||||
|
set_uint8_lo(contextGcx, value);
|
||||||
|
break;
|
||||||
|
case R::EDX:
|
||||||
|
set_uint32_lo(contextGdx, value);
|
||||||
|
break;
|
||||||
|
case R::DX:
|
||||||
|
set_uint16_lo(contextGdx, value);
|
||||||
|
break;
|
||||||
|
case R::DH:
|
||||||
|
set_uint8_hi(contextGdx, value);
|
||||||
|
break;
|
||||||
|
case R::DL:
|
||||||
|
set_uint8_lo(contextGdx, value);
|
||||||
|
break;
|
||||||
|
case R::EDI:
|
||||||
|
set_uint32_lo(contextGdi, value);
|
||||||
|
break;
|
||||||
|
case R::DI:
|
||||||
|
set_uint16_lo(contextGdi, value);
|
||||||
|
break;
|
||||||
|
case R::ESI:
|
||||||
|
set_uint32_lo(contextGsi, value);
|
||||||
|
break;
|
||||||
|
case R::SI:
|
||||||
|
set_uint16_lo(contextGsi, value);
|
||||||
|
break;
|
||||||
|
case R::EBP:
|
||||||
|
set_uint32_lo(contextGbp, value);
|
||||||
|
break;
|
||||||
|
case R::BP:
|
||||||
|
set_uint16_lo(contextGbp, value);
|
||||||
|
break;
|
||||||
|
case R::ESP:
|
||||||
|
set_uint32_lo(contextGsp, value);
|
||||||
|
break;
|
||||||
|
case R::SP:
|
||||||
|
set_uint16_lo(contextGsp, value);
|
||||||
|
break;
|
||||||
|
case R::EIP:
|
||||||
|
set_uint32_lo(contextGip, value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
#ifdef _WIN64
|
||||||
|
case R::RAX:
|
||||||
|
_context.Rax = value;
|
||||||
|
break;
|
||||||
|
case R::RBX:
|
||||||
|
_context.Rbx = value;
|
||||||
|
break;
|
||||||
|
case R::RCX:
|
||||||
|
_context.Rcx = value;
|
||||||
|
break;
|
||||||
|
case R::RDX:
|
||||||
|
_context.Rdx = value;
|
||||||
|
break;
|
||||||
|
case R::RSI:
|
||||||
|
_context.Rsi = value;
|
||||||
|
break;
|
||||||
|
case R::SIL:
|
||||||
|
set_uint8_lo(_context.Rsi, value);
|
||||||
|
break;
|
||||||
|
case R::RDI:
|
||||||
|
_context.Rdi = value;
|
||||||
|
break;
|
||||||
|
case R::DIL:
|
||||||
|
set_uint8_lo(_context.Rdi, value);
|
||||||
|
break;
|
||||||
|
case R::RBP:
|
||||||
|
_context.Rbp = value;
|
||||||
|
break;
|
||||||
|
case R::BPL:
|
||||||
|
set_uint8_lo(_context.Rbp, value);
|
||||||
|
break;
|
||||||
|
case R::RSP:
|
||||||
|
_context.Rsp = value;
|
||||||
|
break;
|
||||||
|
case R::SPL:
|
||||||
|
set_uint8_lo(_context.Rsp, value);
|
||||||
|
break;
|
||||||
|
case R::RIP:
|
||||||
|
_context.Rip = value;
|
||||||
|
break;
|
||||||
|
case R::R8:
|
||||||
|
_context.R8 = value;
|
||||||
|
break;
|
||||||
|
case R::R8D:
|
||||||
|
set_uint32_lo(_context.R8, value);
|
||||||
|
break;
|
||||||
|
case R::R8W:
|
||||||
|
set_uint16_lo(_context.R8, value);
|
||||||
|
break;
|
||||||
|
case R::R8B:
|
||||||
|
set_uint8_lo(_context.R8, value);
|
||||||
|
break;
|
||||||
|
case R::R9:
|
||||||
|
_context.R9 = value;
|
||||||
|
break;
|
||||||
|
case R::R9D:
|
||||||
|
set_uint32_lo(_context.R9, value);
|
||||||
|
break;
|
||||||
|
case R::R9W:
|
||||||
|
set_uint16_lo(_context.R9, value);
|
||||||
|
break;
|
||||||
|
case R::R9B:
|
||||||
|
set_uint8_lo(_context.R9, value);
|
||||||
|
break;
|
||||||
|
case R::R10:
|
||||||
|
_context.R10 = value;
|
||||||
|
break;
|
||||||
|
case R::R10D:
|
||||||
|
set_uint32_lo(_context.R10, value);
|
||||||
|
break;
|
||||||
|
case R::R10W:
|
||||||
|
set_uint16_lo(_context.R10, value);
|
||||||
|
break;
|
||||||
|
case R::R10B:
|
||||||
|
set_uint8_lo(_context.R10, value);
|
||||||
|
break;
|
||||||
|
case R::R11:
|
||||||
|
_context.R11 = value;
|
||||||
|
break;
|
||||||
|
case R::R11D:
|
||||||
|
set_uint32_lo(_context.R11, value);
|
||||||
|
break;
|
||||||
|
case R::R11W:
|
||||||
|
set_uint16_lo(_context.R11, value);
|
||||||
|
break;
|
||||||
|
case R::R11B:
|
||||||
|
set_uint8_lo(_context.R11, value);
|
||||||
|
break;
|
||||||
|
case R::R12:
|
||||||
|
_context.R12 = value;
|
||||||
|
break;
|
||||||
|
case R::R12D:
|
||||||
|
set_uint32_lo(_context.R12, value);
|
||||||
|
break;
|
||||||
|
case R::R12W:
|
||||||
|
set_uint16_lo(_context.R12, value);
|
||||||
|
break;
|
||||||
|
case R::R12B:
|
||||||
|
set_uint8_lo(_context.R12, value);
|
||||||
|
break;
|
||||||
|
case R::R13:
|
||||||
|
_context.R13 = value;
|
||||||
|
break;
|
||||||
|
case R::R13D:
|
||||||
|
set_uint32_lo(_context.R13, value);
|
||||||
|
break;
|
||||||
|
case R::R13W:
|
||||||
|
set_uint16_lo(_context.R13, value);
|
||||||
|
break;
|
||||||
|
case R::R13B:
|
||||||
|
set_uint8_lo(_context.R13, value);
|
||||||
|
break;
|
||||||
|
case R::R14:
|
||||||
|
_context.R14 = value;
|
||||||
|
break;
|
||||||
|
case R::R14D:
|
||||||
|
set_uint32_lo(_context.R14, value);
|
||||||
|
break;
|
||||||
|
case R::R14W:
|
||||||
|
set_uint16_lo(_context.R14, value);
|
||||||
|
break;
|
||||||
|
case R::R14B:
|
||||||
|
set_uint8_lo(_context.R14, value);
|
||||||
|
break;
|
||||||
|
case R::R15:
|
||||||
|
_context.R15 = value;
|
||||||
|
break;
|
||||||
|
case R::R15D:
|
||||||
|
set_uint32_lo(_context.R15, value);
|
||||||
|
break;
|
||||||
|
case R::R15W:
|
||||||
|
set_uint16_lo(_context.R15, value);
|
||||||
|
break;
|
||||||
|
case R::R15B:
|
||||||
|
set_uint8_lo(_context.R15, value);
|
||||||
|
break;
|
||||||
|
#endif //_WIN64
|
||||||
|
|
||||||
|
case R::GAX:
|
||||||
|
contextGax = value;
|
||||||
|
break;
|
||||||
|
case R::GBX:
|
||||||
|
contextGbx = value;
|
||||||
|
break;
|
||||||
|
case R::GCX:
|
||||||
|
contextGcx = value;
|
||||||
|
break;
|
||||||
|
case R::GDX:
|
||||||
|
contextGdx = value;
|
||||||
|
break;
|
||||||
|
case R::GDI:
|
||||||
|
contextGdi = value;
|
||||||
|
break;
|
||||||
|
case R::GSI:
|
||||||
|
contextGsi = value;
|
||||||
|
break;
|
||||||
|
case R::GBP:
|
||||||
|
contextGbp = value;
|
||||||
|
break;
|
||||||
|
case R::GSP:
|
||||||
|
contextGsp = value;
|
||||||
|
break;
|
||||||
|
case R::GIP:
|
||||||
|
contextGip = value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,112 @@
|
||||||
|
#ifndef _DEBUGGER_THREAD_REGISTERS_REGISTER_H
|
||||||
|
#define _DEBUGGER_THREAD_REGISTERS_REGISTER_H
|
||||||
|
|
||||||
|
#include "Debugger.Thread.Registers.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Class that represents a register.
|
||||||
|
\tparam RegisterIndex The enum index of the register.
|
||||||
|
\tparam Type Type of the register value.
|
||||||
|
\tparam ThisPtr Pointer to the Registers class.
|
||||||
|
*/
|
||||||
|
template<R RegisterIndex, typename Type>
|
||||||
|
class Register
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit Register(Registers* registers) : _registers(registers) {}
|
||||||
|
|
||||||
|
Type Get() const
|
||||||
|
{
|
||||||
|
return Type(_registers->Get(RegisterIndex));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Set(Type value)
|
||||||
|
{
|
||||||
|
_registers->Set(RegisterIndex, ptr(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
Type operator()() const
|
||||||
|
{
|
||||||
|
return Get();
|
||||||
|
}
|
||||||
|
|
||||||
|
Register<RegisterIndex, Type> & operator=(const Type & other)
|
||||||
|
{
|
||||||
|
Set(other);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Register<RegisterIndex, Type> & operator+=(const Type & other)
|
||||||
|
{
|
||||||
|
Set(Get() + other);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Register<RegisterIndex, Type> & operator-=(const Type & other)
|
||||||
|
{
|
||||||
|
Set(Get() - other);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Register<RegisterIndex, Type> & operator*=(const Type & other)
|
||||||
|
{
|
||||||
|
Set(Get() * other);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Register<RegisterIndex, Type> & operator/=(const Type & other)
|
||||||
|
{
|
||||||
|
Set(Get() / other);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Register<RegisterIndex, Type> & operator%=(const Type & other)
|
||||||
|
{
|
||||||
|
Set(Get() % other);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Register<RegisterIndex, Type> & operator^=(const Type & other)
|
||||||
|
{
|
||||||
|
Set(Get() ^ other);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Register<RegisterIndex, Type> & operator&=(const Type & other)
|
||||||
|
{
|
||||||
|
Set(Get() & other);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Register<RegisterIndex, Type> & operator|=(const Type & other)
|
||||||
|
{
|
||||||
|
Set(Get() | other);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Register<RegisterIndex, Type> & operator++()
|
||||||
|
{
|
||||||
|
Set(Get() + 1);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Register<RegisterIndex, Type> & operator++(int)
|
||||||
|
{
|
||||||
|
return operator++();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const Type & other)
|
||||||
|
{
|
||||||
|
return Get() == other;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const Type & other)
|
||||||
|
{
|
||||||
|
return !operator==(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Registers* _registers;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //_DEBUGGER_THREAD_REGISTERS_REGISTER_H
|
||||||
|
|
@ -2,106 +2,138 @@
|
||||||
|
|
||||||
namespace GleeBug
|
namespace GleeBug
|
||||||
{
|
{
|
||||||
RegistersInfo::RegistersInfo()
|
Registers::Registers() :
|
||||||
|
Dr0(this),
|
||||||
|
Dr1(this),
|
||||||
|
Dr2(this),
|
||||||
|
Dr3(this),
|
||||||
|
Dr6(this),
|
||||||
|
Dr7(this),
|
||||||
|
|
||||||
|
Eflags(this),
|
||||||
|
|
||||||
|
Eax(this),
|
||||||
|
Ax(this),
|
||||||
|
Ah(this),
|
||||||
|
Al(this),
|
||||||
|
Ebx(this),
|
||||||
|
Bx(this),
|
||||||
|
Bh(this),
|
||||||
|
Bl(this),
|
||||||
|
Ecx(this),
|
||||||
|
Cx(this),
|
||||||
|
Ch(this),
|
||||||
|
Cl(this),
|
||||||
|
Edx(this),
|
||||||
|
Dx(this),
|
||||||
|
Dh(this),
|
||||||
|
Dl(this),
|
||||||
|
Edi(this),
|
||||||
|
Di(this),
|
||||||
|
Esi(this),
|
||||||
|
Si(this),
|
||||||
|
Ebp(this),
|
||||||
|
Bp(this),
|
||||||
|
Esp(this),
|
||||||
|
Sp(this),
|
||||||
|
Eip(this),
|
||||||
|
|
||||||
|
#ifdef _WIN64
|
||||||
|
Rax(this),
|
||||||
|
Rbx(this),
|
||||||
|
Rcx(this),
|
||||||
|
Rdx(this),
|
||||||
|
Rsi(this),
|
||||||
|
Sil(this),
|
||||||
|
Rdi(this),
|
||||||
|
Dil(this),
|
||||||
|
Rbp(this),
|
||||||
|
Bpl(this),
|
||||||
|
Rsp(this),
|
||||||
|
Spl(this),
|
||||||
|
Rip(this),
|
||||||
|
R8(this),
|
||||||
|
R8d(this),
|
||||||
|
R8w(this),
|
||||||
|
R8b(this),
|
||||||
|
R9(this),
|
||||||
|
R9d(this),
|
||||||
|
R9w(this),
|
||||||
|
R9b(this),
|
||||||
|
R10(this),
|
||||||
|
R10d(this),
|
||||||
|
R10w(this),
|
||||||
|
R10b(this),
|
||||||
|
R11(this),
|
||||||
|
R11d(this),
|
||||||
|
R11w(this),
|
||||||
|
R11b(this),
|
||||||
|
R12(this),
|
||||||
|
R12d(this),
|
||||||
|
R12w(this),
|
||||||
|
R12b(this),
|
||||||
|
R13(this),
|
||||||
|
R13d(this),
|
||||||
|
R13w(this),
|
||||||
|
R13b(this),
|
||||||
|
R14(this),
|
||||||
|
R14d(this),
|
||||||
|
R14w(this),
|
||||||
|
R14b(this),
|
||||||
|
R15(this),
|
||||||
|
R15d(this),
|
||||||
|
R15w(this),
|
||||||
|
R15b(this),
|
||||||
|
#endif //_WIN64
|
||||||
|
|
||||||
|
Gax(this),
|
||||||
|
Gbx(this),
|
||||||
|
Gcx(this),
|
||||||
|
Gdx(this),
|
||||||
|
Gdi(this),
|
||||||
|
Gsi(this),
|
||||||
|
Gbp(this),
|
||||||
|
Gsp(this),
|
||||||
|
Gip(this)
|
||||||
{
|
{
|
||||||
memset(&this->_context, 0, sizeof(CONTEXT));
|
memset(&this->_context, 0, sizeof(CONTEXT));
|
||||||
}
|
}
|
||||||
|
|
||||||
const CONTEXT* RegistersInfo::GetContext()
|
const CONTEXT* Registers::GetContext() const
|
||||||
{
|
{
|
||||||
#ifdef _WIN64
|
|
||||||
_context.Rax = this->Rax;
|
|
||||||
_context.Rbx = this->Rbx;
|
|
||||||
_context.Rcx = this->Rcx;
|
|
||||||
_context.Rdx = this->Rdx;
|
|
||||||
_context.Rsi = this->Rsi;
|
|
||||||
_context.Rdi = this->Rdi;
|
|
||||||
_context.Rbp = this->Rbp;
|
|
||||||
_context.Rsp = this->Rsp;
|
|
||||||
_context.Rip = this->Rip;
|
|
||||||
_context.R8 = this->R8;
|
|
||||||
_context.R9 = this->R9;
|
|
||||||
_context.R10 = this->R10;
|
|
||||||
_context.R11 = this->R11;
|
|
||||||
_context.R12 = this->R12;
|
|
||||||
_context.R13 = this->R13;
|
|
||||||
_context.R14 = this->R14;
|
|
||||||
_context.R15 = this->R15;
|
|
||||||
_context.EFlags = this->EFlags;
|
|
||||||
#else //x86
|
|
||||||
_context.Eax = this->Eax;
|
|
||||||
_context.Ebx = this->Ebx;
|
|
||||||
_context.Ecx = this->Ecx;
|
|
||||||
_context.Edx = this->Edx;
|
|
||||||
_context.Esi = this->Esi;
|
|
||||||
_context.Edi = this->Edi;
|
|
||||||
_context.Ebp = this->Ebp;
|
|
||||||
_context.Esp = this->Esp;
|
|
||||||
_context.Eip = this->Eip;
|
|
||||||
_context.EFlags = this->EFlags;
|
|
||||||
#endif //_WIN64
|
|
||||||
return &_context;
|
return &_context;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegistersInfo::SetContext(const CONTEXT & context)
|
void Registers::SetContext(const CONTEXT & context)
|
||||||
{
|
{
|
||||||
#ifdef _WIN64
|
|
||||||
this->Rax = context.Rax;
|
|
||||||
this->Rbx = context.Rbx;
|
|
||||||
this->Rcx = context.Rcx;
|
|
||||||
this->Rdx = context.Rdx;
|
|
||||||
this->Rsi = context.Rsi;
|
|
||||||
this->Rdi = context.Rdi;
|
|
||||||
this->Rbp = context.Rbp;
|
|
||||||
this->Rsp = context.Rsp;
|
|
||||||
this->Rip = context.Rip;
|
|
||||||
this->R8 = context.R8;
|
|
||||||
this->R9 = context.R9;
|
|
||||||
this->R10 = context.R10;
|
|
||||||
this->R11 = context.R11;
|
|
||||||
this->R12 = context.R12;
|
|
||||||
this->R13 = context.R13;
|
|
||||||
this->R14 = context.R14;
|
|
||||||
this->R15 = context.R15;
|
|
||||||
this->EFlags = context.EFlags;
|
|
||||||
#else //x86
|
|
||||||
this->Eax = context.Eax;
|
|
||||||
this->Ebx = context.Ebx;
|
|
||||||
this->Ecx = context.Ecx;
|
|
||||||
this->Edx = context.Edx;
|
|
||||||
this->Esi = context.Esi;
|
|
||||||
this->Edi = context.Edi;
|
|
||||||
this->Ebp = context.Ebp;
|
|
||||||
this->Esp = context.Esp;
|
|
||||||
this->Eip = context.Eip;
|
|
||||||
this->EFlags = context.EFlags;
|
|
||||||
#endif //_WIN64
|
|
||||||
this->_context = context;
|
this->_context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegistersInfo::SetTrapFlag(bool set)
|
void Registers::SetTrapFlag(bool set)
|
||||||
{
|
{
|
||||||
if (set)
|
/*if (set)
|
||||||
this->EFlags |= TRAP_FLAG;
|
this->EFlags |= TRAP_FLAG;
|
||||||
else
|
else
|
||||||
this->EFlags &= ~TRAP_FLAG;
|
this->EFlags &= ~TRAP_FLAG;*/
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RegistersInfo::GetTrapFlag()
|
bool Registers::GetTrapFlag() const
|
||||||
{
|
{
|
||||||
return (this->EFlags & TRAP_FLAG) == TRAP_FLAG;
|
return true;
|
||||||
|
//return (this->EFlags & TRAP_FLAG) == TRAP_FLAG;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegistersInfo::SetResumeFlag(bool set)
|
void Registers::SetResumeFlag(bool set)
|
||||||
{
|
{
|
||||||
if (set)
|
/*if (set)
|
||||||
this->EFlags |= RESUME_FLAG;
|
this->EFlags |= RESUME_FLAG;
|
||||||
else
|
else
|
||||||
this->EFlags &= ~RESUME_FLAG;
|
this->EFlags &= ~RESUME_FLAG;*/
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RegistersInfo::GetResumeFlag()
|
bool Registers::GetResumeFlag() const
|
||||||
{
|
{
|
||||||
return (this->EFlags & RESUME_FLAG) == RESUME_FLAG;
|
return true;
|
||||||
|
//return (this->EFlags & RESUME_FLAG) == RESUME_FLAG;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -5,55 +5,227 @@
|
||||||
|
|
||||||
namespace GleeBug
|
namespace GleeBug
|
||||||
{
|
{
|
||||||
CONTEXT;
|
|
||||||
/**
|
/**
|
||||||
\brief Thread register context.
|
\brief Thread register context.
|
||||||
*/
|
*/
|
||||||
class RegistersInfo
|
class Registers
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
enum class R
|
||||||
|
{
|
||||||
|
DR0,
|
||||||
|
DR1,
|
||||||
|
DR2,
|
||||||
|
DR3,
|
||||||
|
DR6,
|
||||||
|
DR7,
|
||||||
|
|
||||||
|
EFlags,
|
||||||
|
|
||||||
|
EAX,
|
||||||
|
AX,
|
||||||
|
AH,
|
||||||
|
AL,
|
||||||
|
EBX,
|
||||||
|
BX,
|
||||||
|
BH,
|
||||||
|
BL,
|
||||||
|
ECX,
|
||||||
|
CX,
|
||||||
|
CH,
|
||||||
|
CL,
|
||||||
|
EDX,
|
||||||
|
DX,
|
||||||
|
DH,
|
||||||
|
DL,
|
||||||
|
EDI,
|
||||||
|
DI,
|
||||||
|
ESI,
|
||||||
|
SI,
|
||||||
|
EBP,
|
||||||
|
BP,
|
||||||
|
ESP,
|
||||||
|
SP,
|
||||||
|
EIP,
|
||||||
|
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
DWORD64 Rax;
|
RAX,
|
||||||
DWORD64 Rbx;
|
RBX,
|
||||||
DWORD64 Rcx;
|
RCX,
|
||||||
DWORD64 Rdx;
|
RDX,
|
||||||
DWORD64 Rsi;
|
RSI,
|
||||||
DWORD64 Rdi;
|
SIL,
|
||||||
DWORD64 Rbp;
|
RDI,
|
||||||
DWORD64 Rsp;
|
DIL,
|
||||||
DWORD64 Rip;
|
RBP,
|
||||||
DWORD64 R8;
|
BPL,
|
||||||
DWORD64 R9;
|
RSP,
|
||||||
DWORD64 R10;
|
SPL,
|
||||||
DWORD64 R11;
|
RIP,
|
||||||
DWORD64 R12;
|
R8,
|
||||||
DWORD64 R13;
|
R8D,
|
||||||
DWORD64 R14;
|
R8W,
|
||||||
DWORD64 R15;
|
R8B,
|
||||||
DWORD EFlags;
|
R9,
|
||||||
#else //x86
|
R9D,
|
||||||
DWORD Eax;
|
R9W,
|
||||||
DWORD Ebx;
|
R9B,
|
||||||
DWORD Ecx;
|
R10,
|
||||||
DWORD Edx;
|
R10D,
|
||||||
DWORD Esi;
|
R10W,
|
||||||
DWORD Edi;
|
R10B,
|
||||||
DWORD Ebp;
|
R11,
|
||||||
DWORD Esp;
|
R11D,
|
||||||
DWORD Eip;
|
R11W,
|
||||||
DWORD EFlags;
|
R11B,
|
||||||
|
R12,
|
||||||
|
R12D,
|
||||||
|
R12W,
|
||||||
|
R12B,
|
||||||
|
R13,
|
||||||
|
R13D,
|
||||||
|
R13W,
|
||||||
|
R13B,
|
||||||
|
R14,
|
||||||
|
R14D,
|
||||||
|
R14W,
|
||||||
|
R14B,
|
||||||
|
R15,
|
||||||
|
R15D,
|
||||||
|
R15W,
|
||||||
|
R15B,
|
||||||
#endif //_WIN64
|
#endif //_WIN64
|
||||||
|
|
||||||
|
GAX,
|
||||||
|
GBX,
|
||||||
|
GCX,
|
||||||
|
GDX,
|
||||||
|
GDI,
|
||||||
|
GSI,
|
||||||
|
GBP,
|
||||||
|
GSP,
|
||||||
|
GIP,
|
||||||
|
}; //RegisterEnum
|
||||||
|
|
||||||
|
#include "Debugger.Thread.Registers.Register.h"
|
||||||
|
|
||||||
|
Register<R::DR0, ptr> Dr0;
|
||||||
|
Register<R::DR1, ptr> Dr1;
|
||||||
|
Register<R::DR2, ptr> Dr2;
|
||||||
|
Register<R::DR3, ptr> Dr3;
|
||||||
|
Register<R::DR6, ptr> Dr6;
|
||||||
|
Register<R::DR7, ptr> Dr7;
|
||||||
|
|
||||||
|
Register<R::EFlags, uint32> Eflags;
|
||||||
|
|
||||||
|
Register<R::EAX, uint32> Eax;
|
||||||
|
Register<R::AX, uint16> Ax;
|
||||||
|
Register<R::AH, uint8> Ah;
|
||||||
|
Register<R::AL, uint8> Al;
|
||||||
|
Register<R::EBX, uint32> Ebx;
|
||||||
|
Register<R::BX, uint16> Bx;
|
||||||
|
Register<R::BH, uint8> Bh;
|
||||||
|
Register<R::BL, uint8> Bl;
|
||||||
|
Register<R::ECX, uint32> Ecx;
|
||||||
|
Register<R::CX, uint16> Cx;
|
||||||
|
Register<R::CH, uint8> Ch;
|
||||||
|
Register<R::CL, uint8> Cl;
|
||||||
|
Register<R::EDX, uint32> Edx;
|
||||||
|
Register<R::DX, uint16> Dx;
|
||||||
|
Register<R::DH, uint8> Dh;
|
||||||
|
Register<R::DL, uint8> Dl;
|
||||||
|
Register<R::EDI, uint32> Edi;
|
||||||
|
Register<R::DI, uint16> Di;
|
||||||
|
Register<R::ESI, uint32> Esi;
|
||||||
|
Register<R::SI, uint16> Si;
|
||||||
|
Register<R::EBP, uint32> Ebp;
|
||||||
|
Register<R::BP, uint16> Bp;
|
||||||
|
Register<R::ESP, uint32> Esp;
|
||||||
|
Register<R::SP, uint16> Sp;
|
||||||
|
Register<R::EIP, uint32> Eip;
|
||||||
|
|
||||||
|
#ifdef _WIN64
|
||||||
|
Register<R::RAX, uint64> Rax;
|
||||||
|
Register<R::RBX, uint64> Rbx;
|
||||||
|
Register<R::RCX, uint64> Rcx;
|
||||||
|
Register<R::RDX, uint64> Rdx;
|
||||||
|
Register<R::RSI, uint64> Rsi;
|
||||||
|
Register<R::SIL, uint8> Sil;
|
||||||
|
Register<R::RDI, uint64> Rdi;
|
||||||
|
Register<R::DIL, uint8> Dil;
|
||||||
|
Register<R::RBP, uint64> Rbp;
|
||||||
|
Register<R::BPL, uint8> Bpl;
|
||||||
|
Register<R::RSP, uint64> Rsp;
|
||||||
|
Register<R::SPL, uint8> Spl;
|
||||||
|
Register<R::RIP, uint64> Rip;
|
||||||
|
Register<R::R8, uint64> R8;
|
||||||
|
Register<R::R8D, uint32> R8d;
|
||||||
|
Register<R::R8W, uint16> R8w;
|
||||||
|
Register<R::R8B, uint8> R8b;
|
||||||
|
Register<R::R9, uint64> R9;
|
||||||
|
Register<R::R9D, uint32> R9d;
|
||||||
|
Register<R::R9W, uint16> R9w;
|
||||||
|
Register<R::R9B, uint8> R9b;
|
||||||
|
Register<R::R10, uint64> R10;
|
||||||
|
Register<R::R10D, uint32> R10d;
|
||||||
|
Register<R::R10W, uint16> R10w;
|
||||||
|
Register<R::R10B, uint8> R10b;
|
||||||
|
Register<R::R11, uint64> R11;
|
||||||
|
Register<R::R11D, uint32> R11d;
|
||||||
|
Register<R::R11W, uint16> R11w;
|
||||||
|
Register<R::R11B, uint8> R11b;
|
||||||
|
Register<R::R12, uint64> R12;
|
||||||
|
Register<R::R12D, uint32> R12d;
|
||||||
|
Register<R::R12W, uint16> R12w;
|
||||||
|
Register<R::R12B, uint8> R12b;
|
||||||
|
Register<R::R13, uint64> R13;
|
||||||
|
Register<R::R13D, uint32> R13d;
|
||||||
|
Register<R::R13W, uint16> R13w;
|
||||||
|
Register<R::R13B, uint8> R13b;
|
||||||
|
Register<R::R14, uint64> R14;
|
||||||
|
Register<R::R14D, uint32> R14d;
|
||||||
|
Register<R::R14W, uint16> R14w;
|
||||||
|
Register<R::R14B, uint8> R14b;
|
||||||
|
Register<R::R15, uint64> R15;
|
||||||
|
Register<R::R15D, uint32> R15d;
|
||||||
|
Register<R::R15W, uint16> R15w;
|
||||||
|
Register<R::R15B, uint8> R15b;
|
||||||
|
#endif //_WIN64
|
||||||
|
|
||||||
|
Register<R::GAX, ptr> Gax;
|
||||||
|
Register<R::GBX, ptr> Gbx;
|
||||||
|
Register<R::GCX, ptr> Gcx;
|
||||||
|
Register<R::GDX, ptr> Gdx;
|
||||||
|
Register<R::GDI, ptr> Gdi;
|
||||||
|
Register<R::GSI, ptr> Gsi;
|
||||||
|
Register<R::GBP, ptr> Gbp;
|
||||||
|
Register<R::GSP, ptr> Gsp;
|
||||||
|
Register<R::GIP, ptr> Gip;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Default constructor.
|
\brief Default constructor.
|
||||||
*/
|
*/
|
||||||
RegistersInfo();
|
Registers();
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Gets the given register.
|
||||||
|
\param reg The register to get.
|
||||||
|
\return The register value.
|
||||||
|
*/
|
||||||
|
ptr Get(R reg) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Sets a given register.
|
||||||
|
\param reg The register to set.
|
||||||
|
\param value The new register value.
|
||||||
|
*/
|
||||||
|
void Set(R reg, ptr value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Gets a pointer to the context object.
|
\brief Gets a pointer to the context object.
|
||||||
\return This function will never return a nullptr.
|
\return This function will never return a nullptr.
|
||||||
*/
|
*/
|
||||||
const CONTEXT* GetContext();
|
const CONTEXT* GetContext() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Sets the CONTEXT.
|
\brief Sets the CONTEXT.
|
||||||
|
|
@ -71,7 +243,7 @@ namespace GleeBug
|
||||||
\brief Gets trap flag.
|
\brief Gets trap flag.
|
||||||
\return true if the flag is set, false otherwise.
|
\return true if the flag is set, false otherwise.
|
||||||
*/
|
*/
|
||||||
bool GetTrapFlag();
|
bool GetTrapFlag() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Sets resume flag.
|
\brief Sets resume flag.
|
||||||
|
|
@ -83,7 +255,7 @@ namespace GleeBug
|
||||||
\brief Gets resume flag.
|
\brief Gets resume flag.
|
||||||
\return true if the flag is set, false otherwise.
|
\return true if the flag is set, false otherwise.
|
||||||
*/
|
*/
|
||||||
bool GetResumeFlag();
|
bool GetResumeFlag() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CONTEXT _context;
|
CONTEXT _context;
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,12 @@ namespace GleeBug
|
||||||
this->hThread = INVALID_HANDLE_VALUE;
|
this->hThread = INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ThreadInfo::ThreadInfo(DWORD dwThreadId, HANDLE hThread, LPVOID lpThreadLocalBase, LPVOID lpStartAddress)
|
ThreadInfo::ThreadInfo(uint32 dwThreadId, HANDLE hThread, LPVOID lpThreadLocalBase, LPVOID lpStartAddress)
|
||||||
{
|
{
|
||||||
this->dwThreadId = dwThreadId;
|
this->dwThreadId = dwThreadId;
|
||||||
this->hThread = hThread;
|
this->hThread = hThread;
|
||||||
this->lpThreadLocalBase = reinterpret_cast<ULONG_PTR>(lpThreadLocalBase);
|
this->lpThreadLocalBase = ptr(lpThreadLocalBase);
|
||||||
this->lpStartAddress = reinterpret_cast<ULONG_PTR>(lpStartAddress);
|
this->lpStartAddress = ptr(lpStartAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ThreadInfo::RegReadContext()
|
bool ThreadInfo::RegReadContext()
|
||||||
|
|
|
||||||
|
|
@ -12,12 +12,12 @@ namespace GleeBug
|
||||||
class ThreadInfo
|
class ThreadInfo
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DWORD dwThreadId;
|
uint32 dwThreadId;
|
||||||
HANDLE hThread;
|
HANDLE hThread;
|
||||||
ULONG_PTR lpThreadLocalBase;
|
ptr lpThreadLocalBase;
|
||||||
ULONG_PTR lpStartAddress;
|
ptr lpStartAddress;
|
||||||
|
|
||||||
RegistersInfo registers;
|
Registers registers;
|
||||||
StepCallbackVector stepCallbacks;
|
StepCallbackVector stepCallbacks;
|
||||||
bool isSingleStepping;
|
bool isSingleStepping;
|
||||||
|
|
||||||
|
|
@ -32,7 +32,7 @@ namespace GleeBug
|
||||||
\param lpThreadLocalBase The thread local base.
|
\param lpThreadLocalBase The thread local base.
|
||||||
\param lpStartAddress The start address.
|
\param lpStartAddress The start address.
|
||||||
*/
|
*/
|
||||||
ThreadInfo(DWORD dwThreadId, HANDLE hThread, LPVOID lpThreadLocalBase, LPVOID lpStartAddress);
|
ThreadInfo(uint32 dwThreadId, HANDLE hThread, LPVOID lpThreadLocalBase, LPVOID lpStartAddress);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\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.
|
||||||
|
|
|
||||||
|
|
@ -201,7 +201,7 @@ namespace GleeBug
|
||||||
|
|
||||||
protected: //variables
|
protected: //variables
|
||||||
PROCESS_INFORMATION _mainProcess;
|
PROCESS_INFORMATION _mainProcess;
|
||||||
DWORD _continueStatus;
|
uint32 _continueStatus;
|
||||||
bool _breakDebugger;
|
bool _breakDebugger;
|
||||||
DEBUG_EVENT _debugEvent;
|
DEBUG_EVENT _debugEvent;
|
||||||
ProcessMap _processes;
|
ProcessMap _processes;
|
||||||
|
|
@ -216,6 +216,11 @@ namespace GleeBug
|
||||||
\brief The current thread (can be null in some cases). Should be a copy of _process->thread.
|
\brief The current thread (can be null in some cases). Should be a copy of _process->thread.
|
||||||
*/
|
*/
|
||||||
ThreadInfo* _thread;
|
ThreadInfo* _thread;
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief The current thread registers (can be null in some cases). Should be a copy of _thread->registers.
|
||||||
|
*/
|
||||||
|
Registers* _registers;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
#ifndef _GLEEBUG_H
|
||||||
|
#define _GLEEBUG_H
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <map>
|
||||||
|
#include <set>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <psapi.h>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
//macros
|
||||||
|
#define BIND(thisPtr, funcPtr) std::bind(&funcPtr, thisPtr)
|
||||||
|
|
||||||
|
namespace GleeBug
|
||||||
|
{
|
||||||
|
typedef int8_t int8;
|
||||||
|
typedef uint8_t uint8;
|
||||||
|
typedef int16_t int16;
|
||||||
|
typedef uint16_t uint16;
|
||||||
|
typedef int32_t int32;
|
||||||
|
typedef uint32_t uint32;
|
||||||
|
typedef int64_t int64;
|
||||||
|
typedef uint64_t uint64;
|
||||||
|
#ifdef _WIN64
|
||||||
|
typedef uint64 ptr;
|
||||||
|
#else //x32
|
||||||
|
typedef uint32 ptr;
|
||||||
|
#endif //_WIN64
|
||||||
|
|
||||||
|
typedef std::pair<ptr, ptr> Range;
|
||||||
|
|
||||||
|
struct RangeCompare
|
||||||
|
{
|
||||||
|
inline bool operator()(const Range & a, const Range & b) const //a before b?
|
||||||
|
{
|
||||||
|
return a.second < b.first;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //_GLEEBUG_H
|
||||||
|
|
@ -158,6 +158,7 @@
|
||||||
<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" />
|
<ClCompile Include="Debugger.Thread.Registers.cpp" />
|
||||||
|
<ClCompile Include="Debugger.Thread.Registers.GetSet.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="Debugger.Dll.h" />
|
<ClInclude Include="Debugger.Dll.h" />
|
||||||
|
|
@ -166,6 +167,8 @@
|
||||||
<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" />
|
<ClInclude Include="Debugger.Thread.Registers.h" />
|
||||||
|
<ClInclude Include="Debugger.Thread.Registers.Register.h" />
|
||||||
|
<ClInclude Include="GleeBug.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,9 @@
|
||||||
<ClCompile Include="Debugger.Thread.Registers.cpp">
|
<ClCompile Include="Debugger.Thread.Registers.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="Debugger.Thread.Registers.GetSet.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="Debugger.h">
|
<ClInclude Include="Debugger.h">
|
||||||
|
|
@ -67,5 +70,11 @@
|
||||||
<ClInclude Include="Debugger.Thread.Registers.h">
|
<ClInclude Include="Debugger.Thread.Registers.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="Debugger.Thread.Registers.Register.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="GleeBug.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
@ -72,17 +72,39 @@ protected:
|
||||||
void boobs()
|
void boobs()
|
||||||
{
|
{
|
||||||
printf("(.)Y(.) 0x%p\n",
|
printf("(.)Y(.) 0x%p\n",
|
||||||
#ifdef _WIN64
|
_registers->Gip.Get());
|
||||||
_thread->registers.Rip);
|
}
|
||||||
#else //x32
|
|
||||||
_thread->registers.Eip);
|
void gax()
|
||||||
#endif //_WIN64
|
{
|
||||||
|
printf("GAX: 0x%p = 0x%p = 0x%p\n",
|
||||||
|
_registers->Get(Registers::R::GAX),
|
||||||
|
_registers->Gax.Get(),
|
||||||
|
_registers->Gax());
|
||||||
}
|
}
|
||||||
|
|
||||||
void cbSystemBreakpoint() override
|
void cbSystemBreakpoint() override
|
||||||
{
|
{
|
||||||
|
printf("%p\n", _registers->Gcx());
|
||||||
|
gax();
|
||||||
|
_registers->Gax.Set(123);
|
||||||
|
gax();
|
||||||
|
_registers->Gax = 0x1234;
|
||||||
|
if (_registers->Gax == _registers->Gcx())
|
||||||
|
{
|
||||||
|
puts("test== okay!");
|
||||||
|
}
|
||||||
|
if (_registers->Gax != 1)
|
||||||
|
puts("test!= okay!");
|
||||||
|
gax();
|
||||||
|
_registers->Gax++;
|
||||||
|
gax();
|
||||||
|
++_registers->Gax;
|
||||||
|
gax();
|
||||||
|
|
||||||
|
|
||||||
printf("System breakpoint reached, CIP: 0x%p\n",
|
printf("System breakpoint reached, CIP: 0x%p\n",
|
||||||
_thread->registers.Rip);
|
_registers->Gip.Get());
|
||||||
_thread->StepInto(BIND(this, MyDebugger::boobs));
|
_thread->StepInto(BIND(this, MyDebugger::boobs));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,36 @@
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include "MyDebugger.h"
|
#include "MyDebugger.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
static ptr GetRegister(RegisterEnum reg)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SetRegister(RegisterEnum reg, ptr value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template <RegisterEnum RegisterIndex, typename Type>
|
||||||
|
class Register
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Type Get()
|
||||||
|
{
|
||||||
|
return reinterpret_cast<Type>(GetRegister(RegisterIndex));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Set(Type value)
|
||||||
|
{
|
||||||
|
SetRegister(RegisterIndex, ptr(value));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void test()
|
||||||
|
{
|
||||||
|
|
||||||
|
}*/
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue