register getter/setter functions should be working + refactoring

This commit is contained in:
Mr. eXoDia 2015-07-15 05:54:06 +02:00
parent 2481e33abd
commit 424edbc226
22 changed files with 1095 additions and 168 deletions

2
GleeBug.sln.DotSettings Normal file
View File

@ -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>

View File

@ -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->entryPoint = reinterpret_cast<ULONG_PTR>(entryPoint);
this->entryPoint = ptr(entryPoint);
}
};

View File

@ -11,9 +11,9 @@ namespace GleeBug
class DllInfo
{
public:
ULONG_PTR lpBaseOfDll;
ULONG_PTR sizeOfImage;
ULONG_PTR entryPoint;
ptr lpBaseOfDll;
ptr sizeOfImage;
ptr entryPoint;
/**
\brief Default constructor.
@ -26,7 +26,7 @@ namespace GleeBug
\param sizeOfImage Size of the image.
\param entryPoint The entry point.
*/
DllInfo(LPVOID lpBaseOfDll, ULONG_PTR sizeOfImage, LPVOID entryPoint);
DllInfo(LPVOID lpBaseOfDll, ptr sizeOfImage, LPVOID entryPoint);
};
};

View File

@ -1,29 +1,10 @@
#ifndef _DEBUGGER_GLOBAL_H
#define _DEBUGGER_GLOBAL_H
#include <cstdio>
#include <string>
#include <vector>
#include <unordered_map>
#include <map>
#include <set>
#include <functional>
#include <windows.h>
#include <psapi.h>
#include "GleeBug.h"
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
class Debugger;
class ProcessInfo;
@ -31,18 +12,15 @@ namespace GleeBug
class ThreadInfo;
//map typedefs
typedef std::map<DWORD, ProcessInfo> ProcessMap;
typedef std::map<uint32, ProcessInfo> ProcessMap;
typedef std::map<Range, DllInfo, RangeCompare> DllMap;
typedef std::map<DWORD, ThreadInfo> ThreadMap;
typedef std::map<uint32, ThreadInfo> ThreadMap;
//callback function typedefs
typedef std::function<void()> StepCallback;
//vector typedefs
typedef std::vector<StepCallback> StepCallbackVector;
//macros
#define BIND(thisPtr, funcPtr) std::bind(&funcPtr, thisPtr)
};
#endif //_DEBUGGER_GLOBAL_H

View File

@ -24,7 +24,7 @@ namespace GleeBug
void Debugger::unloadDllEvent(const UNLOAD_DLL_DEBUG_INFO & unloadDll)
{
//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));
if (dll != _process->dlls.end())
cbUnloadDllEvent(unloadDll, dll->second);

View File

@ -18,6 +18,7 @@ namespace GleeBug
createProcess.lpStartAddress);
_process->threads.insert({ thread.dwThreadId, thread });
_thread = _process->thread = &_process->threads.find(thread.dwThreadId)->second;
_registers = &_thread->registers;
//read thread context from main thread
if (!_thread->RegReadContext())
@ -44,5 +45,7 @@ namespace GleeBug
//set the current process
_process = nullptr;
_thread = nullptr;
_registers = nullptr;
}
};

View File

@ -10,6 +10,7 @@ namespace GleeBug
//set the current thread
_thread = _process->thread = &_process->threads.find(_debugEvent.dwThreadId)->second;
_registers = &_thread->registers;
if (!_thread->RegReadContext())
cbInternalError("ThreadInfo::RegReadContext() failed!");
@ -27,5 +28,6 @@ namespace GleeBug
//set the current thread
_thread = _process->thread = nullptr;
_registers = nullptr;
}
};

View File

@ -25,14 +25,22 @@ namespace GleeBug
if (_process->threads.count(_debugEvent.dwThreadId))
{
_thread = _process->thread = &_process->threads[_debugEvent.dwThreadId];
_registers = &_thread->registers;
if (!_thread->RegReadContext())
cbInternalError("ThreadInfo::RegReadContext() failed!");
}
else
{
_thread = _process->thread = nullptr;
_registers = nullptr;
}
}
else
{
_process = nullptr;
_thread = nullptr;
_registers = nullptr;
}
//dispatch the debug event
switch (_debugEvent.dwDebugEventCode)

View File

@ -9,7 +9,7 @@ namespace GleeBug
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->hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
@ -17,12 +17,12 @@ namespace GleeBug
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);
}
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);
}

View File

@ -14,8 +14,8 @@ namespace GleeBug
{
public:
HANDLE hProcess;
DWORD dwProcessId;
DWORD dwMainThreadId;
uint32 dwProcessId;
uint32 dwMainThreadId;
ThreadInfo* thread;
bool systemBreakpoint;
@ -33,7 +33,7 @@ namespace GleeBug
\param dwProcessId Identifier for the process.
\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.
@ -42,7 +42,7 @@ namespace GleeBug
\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(ptr address, const size_t size, void* buffer);
/**
\brief Write memory to the process.
@ -51,7 +51,7 @@ namespace GleeBug
\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(ptr address, const size_t size, const void* buffer);
};
};

View File

@ -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;
}
}
}

View File

@ -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

View File

@ -2,106 +2,138 @@
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));
}
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;
}
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;
}
void RegistersInfo::SetTrapFlag(bool set)
void Registers::SetTrapFlag(bool set)
{
if (set)
/*if (set)
this->EFlags |= TRAP_FLAG;
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;
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;
}
};

View File

@ -5,55 +5,227 @@
namespace GleeBug
{
CONTEXT;
/**
\brief Thread register context.
*/
class RegistersInfo
class Registers
{
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
DWORD64 Rax;
DWORD64 Rbx;
DWORD64 Rcx;
DWORD64 Rdx;
DWORD64 Rsi;
DWORD64 Rdi;
DWORD64 Rbp;
DWORD64 Rsp;
DWORD64 Rip;
DWORD64 R8;
DWORD64 R9;
DWORD64 R10;
DWORD64 R11;
DWORD64 R12;
DWORD64 R13;
DWORD64 R14;
DWORD64 R15;
DWORD EFlags;
#else //x86
DWORD Eax;
DWORD Ebx;
DWORD Ecx;
DWORD Edx;
DWORD Esi;
DWORD Edi;
DWORD Ebp;
DWORD Esp;
DWORD Eip;
DWORD EFlags;
RAX,
RBX,
RCX,
RDX,
RSI,
SIL,
RDI,
DIL,
RBP,
BPL,
RSP,
SPL,
RIP,
R8,
R8D,
R8W,
R8B,
R9,
R9D,
R9W,
R9B,
R10,
R10D,
R10W,
R10B,
R11,
R11D,
R11W,
R11B,
R12,
R12D,
R12W,
R12B,
R13,
R13D,
R13W,
R13B,
R14,
R14D,
R14W,
R14B,
R15,
R15D,
R15W,
R15B,
#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.
*/
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.
\return This function will never return a nullptr.
*/
const CONTEXT* GetContext();
const CONTEXT* GetContext() const;
/**
\brief Sets the CONTEXT.
@ -71,7 +243,7 @@ namespace GleeBug
\brief Gets trap flag.
\return true if the flag is set, false otherwise.
*/
bool GetTrapFlag();
bool GetTrapFlag() const;
/**
\brief Sets resume flag.
@ -83,7 +255,7 @@ namespace GleeBug
\brief Gets resume flag.
\return true if the flag is set, false otherwise.
*/
bool GetResumeFlag();
bool GetResumeFlag() const;
private:
CONTEXT _context;

View File

@ -7,12 +7,12 @@ namespace GleeBug
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->hThread = hThread;
this->lpThreadLocalBase = reinterpret_cast<ULONG_PTR>(lpThreadLocalBase);
this->lpStartAddress = reinterpret_cast<ULONG_PTR>(lpStartAddress);
this->lpThreadLocalBase = ptr(lpThreadLocalBase);
this->lpStartAddress = ptr(lpStartAddress);
}
bool ThreadInfo::RegReadContext()

View File

@ -12,12 +12,12 @@ namespace GleeBug
class ThreadInfo
{
public:
DWORD dwThreadId;
uint32 dwThreadId;
HANDLE hThread;
ULONG_PTR lpThreadLocalBase;
ULONG_PTR lpStartAddress;
ptr lpThreadLocalBase;
ptr lpStartAddress;
RegistersInfo registers;
Registers registers;
StepCallbackVector stepCallbacks;
bool isSingleStepping;
@ -32,7 +32,7 @@ namespace GleeBug
\param lpThreadLocalBase The thread local base.
\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.

View File

@ -201,7 +201,7 @@ namespace GleeBug
protected: //variables
PROCESS_INFORMATION _mainProcess;
DWORD _continueStatus;
uint32 _continueStatus;
bool _breakDebugger;
DEBUG_EVENT _debugEvent;
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.
*/
ThreadInfo* _thread;
/**
\brief The current thread registers (can be null in some cases). Should be a copy of _thread->registers.
*/
Registers* _registers;
};
};

46
GleeBug/GleeBug.h Normal file
View File

@ -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

View File

@ -158,6 +158,7 @@
<ClCompile Include="Debugger.Process.cpp" />
<ClCompile Include="Debugger.Thread.cpp" />
<ClCompile Include="Debugger.Thread.Registers.cpp" />
<ClCompile Include="Debugger.Thread.Registers.GetSet.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="Debugger.Dll.h" />
@ -166,6 +167,8 @@
<ClInclude Include="Debugger.Thread.h" />
<ClInclude Include="Debugger.Global.h" />
<ClInclude Include="Debugger.Thread.Registers.h" />
<ClInclude Include="Debugger.Thread.Registers.Register.h" />
<ClInclude Include="GleeBug.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">

View File

@ -47,6 +47,9 @@
<ClCompile Include="Debugger.Thread.Registers.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Debugger.Thread.Registers.GetSet.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Debugger.h">
@ -67,5 +70,11 @@
<ClInclude Include="Debugger.Thread.Registers.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Debugger.Thread.Registers.Register.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="GleeBug.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -72,17 +72,39 @@ protected:
void boobs()
{
printf("(.)Y(.) 0x%p\n",
#ifdef _WIN64
_thread->registers.Rip);
#else //x32
_thread->registers.Eip);
#endif //_WIN64
_registers->Gip.Get());
}
void gax()
{
printf("GAX: 0x%p = 0x%p = 0x%p\n",
_registers->Get(Registers::R::GAX),
_registers->Gax.Get(),
_registers->Gax());
}
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",
_thread->registers.Rip);
_registers->Gip.Get());
_thread->StepInto(BIND(this, MyDebugger::boobs));
}

View File

@ -1,6 +1,36 @@
#include <cstdio>
#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()
{
#ifdef _WIN64