diff --git a/GleeBug.sln.DotSettings b/GleeBug.sln.DotSettings new file mode 100644 index 0000000..7794a18 --- /dev/null +++ b/GleeBug.sln.DotSettings @@ -0,0 +1,2 @@ + + DO_NOT_SHOW \ No newline at end of file diff --git a/GleeBug/Debugger.Dll.cpp b/GleeBug/Debugger.Dll.cpp index 8ab8850..7d46a0b 100644 --- a/GleeBug/Debugger.Dll.cpp +++ b/GleeBug/Debugger.Dll.cpp @@ -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(lpBaseOfDll); + this->lpBaseOfDll = ptr(lpBaseOfDll); this->sizeOfImage = sizeOfImage; - this->entryPoint = reinterpret_cast(entryPoint); + this->entryPoint = ptr(entryPoint); } }; \ No newline at end of file diff --git a/GleeBug/Debugger.Dll.h b/GleeBug/Debugger.Dll.h index db9ba42..b9104fc 100644 --- a/GleeBug/Debugger.Dll.h +++ b/GleeBug/Debugger.Dll.h @@ -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); }; }; diff --git a/GleeBug/Debugger.Global.h b/GleeBug/Debugger.Global.h index 9950a0c..3690ee2 100644 --- a/GleeBug/Debugger.Global.h +++ b/GleeBug/Debugger.Global.h @@ -1,29 +1,10 @@ #ifndef _DEBUGGER_GLOBAL_H #define _DEBUGGER_GLOBAL_H -#include -#include -#include -#include -#include -#include -#include - -#include -#include +#include "GleeBug.h" namespace GleeBug { - typedef std::pair 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 ProcessMap; + typedef std::map ProcessMap; typedef std::map DllMap; - typedef std::map ThreadMap; + typedef std::map ThreadMap; //callback function typedefs typedef std::function StepCallback; //vector typedefs typedef std::vector StepCallbackVector; - - //macros -#define BIND(thisPtr, funcPtr) std::bind(&funcPtr, thisPtr) }; #endif //_DEBUGGER_GLOBAL_H \ No newline at end of file diff --git a/GleeBug/Debugger.Loop.Dll.cpp b/GleeBug/Debugger.Loop.Dll.cpp index 6ba6116..412f0e8 100644 --- a/GleeBug/Debugger.Loop.Dll.cpp +++ b/GleeBug/Debugger.Loop.Dll.cpp @@ -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(unloadDll.lpBaseOfDll); + ptr lpBaseOfDll = ptr(unloadDll.lpBaseOfDll); auto dll = _process->dlls.find(Range(lpBaseOfDll, lpBaseOfDll)); if (dll != _process->dlls.end()) cbUnloadDllEvent(unloadDll, dll->second); diff --git a/GleeBug/Debugger.Loop.Process.cpp b/GleeBug/Debugger.Loop.Process.cpp index 73dbf7f..b511642 100644 --- a/GleeBug/Debugger.Loop.Process.cpp +++ b/GleeBug/Debugger.Loop.Process.cpp @@ -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; } }; \ No newline at end of file diff --git a/GleeBug/Debugger.Loop.Thread.cpp b/GleeBug/Debugger.Loop.Thread.cpp index bb3a479..9f99bfa 100644 --- a/GleeBug/Debugger.Loop.Thread.cpp +++ b/GleeBug/Debugger.Loop.Thread.cpp @@ -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; } }; \ No newline at end of file diff --git a/GleeBug/Debugger.Loop.cpp b/GleeBug/Debugger.Loop.cpp index 9c5e9db..c52ac91 100644 --- a/GleeBug/Debugger.Loop.cpp +++ b/GleeBug/Debugger.Loop.cpp @@ -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) diff --git a/GleeBug/Debugger.Process.cpp b/GleeBug/Debugger.Process.cpp index 0e9472d..68d02ac 100644 --- a/GleeBug/Debugger.Process.cpp +++ b/GleeBug/Debugger.Process.cpp @@ -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(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(address), buffer, size, nullptr); } diff --git a/GleeBug/Debugger.Process.h b/GleeBug/Debugger.Process.h index ba182cc..1ffea3f 100644 --- a/GleeBug/Debugger.Process.h +++ b/GleeBug/Debugger.Process.h @@ -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); }; }; diff --git a/GleeBug/Debugger.Thread.Registers.GetSet.cpp b/GleeBug/Debugger.Thread.Registers.GetSet.cpp new file mode 100644 index 0000000..d3892de --- /dev/null +++ b/GleeBug/Debugger.Thread.Registers.GetSet.cpp @@ -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; + } + } +} \ No newline at end of file diff --git a/GleeBug/Debugger.Thread.Registers.Register.h b/GleeBug/Debugger.Thread.Registers.Register.h new file mode 100644 index 0000000..7e06178 --- /dev/null +++ b/GleeBug/Debugger.Thread.Registers.Register.h @@ -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 +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 & operator=(const Type & other) + { + Set(other); + return *this; + } + + Register & operator+=(const Type & other) + { + Set(Get() + other); + return *this; + } + + Register & operator-=(const Type & other) + { + Set(Get() - other); + return *this; + } + + Register & operator*=(const Type & other) + { + Set(Get() * other); + return *this; + } + + Register & operator/=(const Type & other) + { + Set(Get() / other); + return *this; + } + + Register & operator%=(const Type & other) + { + Set(Get() % other); + return *this; + } + + Register & operator^=(const Type & other) + { + Set(Get() ^ other); + return *this; + } + + Register & operator&=(const Type & other) + { + Set(Get() & other); + return *this; + } + + Register & operator|=(const Type & other) + { + Set(Get() | other); + return *this; + } + + Register & operator++() + { + Set(Get() + 1); + return *this; + } + + Register & 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 \ No newline at end of file diff --git a/GleeBug/Debugger.Thread.Registers.cpp b/GleeBug/Debugger.Thread.Registers.cpp index f508eba..da8b240 100644 --- a/GleeBug/Debugger.Thread.Registers.cpp +++ b/GleeBug/Debugger.Thread.Registers.cpp @@ -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; + else + 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; + else + 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; } }; \ No newline at end of file diff --git a/GleeBug/Debugger.Thread.Registers.h b/GleeBug/Debugger.Thread.Registers.h index a17d3a1..b3372a4 100644 --- a/GleeBug/Debugger.Thread.Registers.h +++ b/GleeBug/Debugger.Thread.Registers.h @@ -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 Dr0; + Register Dr1; + Register Dr2; + Register Dr3; + Register Dr6; + Register Dr7; + + Register Eflags; + + Register Eax; + Register Ax; + Register Ah; + Register Al; + Register Ebx; + Register Bx; + Register Bh; + Register Bl; + Register Ecx; + Register Cx; + Register Ch; + Register Cl; + Register Edx; + Register Dx; + Register Dh; + Register Dl; + Register Edi; + Register Di; + Register Esi; + Register Si; + Register Ebp; + Register Bp; + Register Esp; + Register Sp; + Register Eip; + +#ifdef _WIN64 + Register Rax; + Register Rbx; + Register Rcx; + Register Rdx; + Register Rsi; + Register Sil; + Register Rdi; + Register Dil; + Register Rbp; + Register Bpl; + Register Rsp; + Register Spl; + Register Rip; + Register R8; + Register R8d; + Register R8w; + Register R8b; + Register R9; + Register R9d; + Register R9w; + Register R9b; + Register R10; + Register R10d; + Register R10w; + Register R10b; + Register R11; + Register R11d; + Register R11w; + Register R11b; + Register R12; + Register R12d; + Register R12w; + Register R12b; + Register R13; + Register R13d; + Register R13w; + Register R13b; + Register R14; + Register R14d; + Register R14w; + Register R14b; + Register R15; + Register R15d; + Register R15w; + Register R15b; +#endif //_WIN64 + + Register Gax; + Register Gbx; + Register Gcx; + Register Gdx; + Register Gdi; + Register Gsi; + Register Gbp; + Register Gsp; + Register 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; diff --git a/GleeBug/Debugger.Thread.cpp b/GleeBug/Debugger.Thread.cpp index f85d32a..59552bb 100644 --- a/GleeBug/Debugger.Thread.cpp +++ b/GleeBug/Debugger.Thread.cpp @@ -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(lpThreadLocalBase); - this->lpStartAddress = reinterpret_cast(lpStartAddress); + this->lpThreadLocalBase = ptr(lpThreadLocalBase); + this->lpStartAddress = ptr(lpStartAddress); } bool ThreadInfo::RegReadContext() diff --git a/GleeBug/Debugger.Thread.h b/GleeBug/Debugger.Thread.h index 5b9553c..8463418 100644 --- a/GleeBug/Debugger.Thread.h +++ b/GleeBug/Debugger.Thread.h @@ -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. diff --git a/GleeBug/Debugger.h b/GleeBug/Debugger.h index ec1308f..23bbc71 100644 --- a/GleeBug/Debugger.h +++ b/GleeBug/Debugger.h @@ -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; }; }; diff --git a/GleeBug/GleeBug.h b/GleeBug/GleeBug.h new file mode 100644 index 0000000..b4cf238 --- /dev/null +++ b/GleeBug/GleeBug.h @@ -0,0 +1,46 @@ +#ifndef _GLEEBUG_H +#define _GLEEBUG_H + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +//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 Range; + + struct RangeCompare + { + inline bool operator()(const Range & a, const Range & b) const //a before b? + { + return a.second < b.first; + } + }; +} + +#endif //_GLEEBUG_H \ No newline at end of file diff --git a/GleeBug/GleeBug.vcxproj b/GleeBug/GleeBug.vcxproj index 25d38a7..ceaa87c 100644 --- a/GleeBug/GleeBug.vcxproj +++ b/GleeBug/GleeBug.vcxproj @@ -158,6 +158,7 @@ + @@ -166,6 +167,8 @@ + + diff --git a/GleeBug/GleeBug.vcxproj.filters b/GleeBug/GleeBug.vcxproj.filters index be04ec1..651ccea 100644 --- a/GleeBug/GleeBug.vcxproj.filters +++ b/GleeBug/GleeBug.vcxproj.filters @@ -47,6 +47,9 @@ Source Files + + Source Files + @@ -67,5 +70,11 @@ Header Files + + Header Files + + + Header Files + \ No newline at end of file diff --git a/MyDebugger/MyDebugger.h b/MyDebugger/MyDebugger.h index a1de2c4..3401878 100644 --- a/MyDebugger/MyDebugger.h +++ b/MyDebugger/MyDebugger.h @@ -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)); } diff --git a/MyDebugger/main.cpp b/MyDebugger/main.cpp index 93abbae..e74ddcc 100644 --- a/MyDebugger/main.cpp +++ b/MyDebugger/main.cpp @@ -1,6 +1,36 @@ #include #include "MyDebugger.h" +/* +static ptr GetRegister(RegisterEnum reg) +{ + return 0; +} + +static void SetRegister(RegisterEnum reg, ptr value) +{ +} + +template +class Register +{ +public: + Type Get() + { + return reinterpret_cast(GetRegister(RegisterIndex)); + } + + void Set(Type value) + { + SetRegister(RegisterIndex, ptr(value)); + } +}; + +static void test() +{ + +}*/ + int main() { #ifdef _WIN64