mirror of https://github.com/x64dbg/GleeBug
renaming fest continued (and probably finished)
This commit is contained in:
parent
3c1f141949
commit
362cba7830
|
|
@ -5,7 +5,7 @@ namespace GleeBug
|
|||
void Debugger::debugStringEvent(const OUTPUT_DEBUG_STRING_INFO & debugString)
|
||||
{
|
||||
//prevent anti-debug trick (debug string events are actually exceptions)
|
||||
_continueStatus = DBG_EXCEPTION_NOT_HANDLED;
|
||||
mContinueStatus = DBG_EXCEPTION_NOT_HANDLED;
|
||||
|
||||
//call the debug event callback
|
||||
cbDebugStringEvent(debugString);
|
||||
|
|
|
|||
|
|
@ -7,12 +7,12 @@ namespace GleeBug
|
|||
//DLL housekeeping
|
||||
MODULEINFO modinfo;
|
||||
memset(&modinfo, 0, sizeof(MODULEINFO));
|
||||
GetModuleInformation(_process->hProcess,
|
||||
GetModuleInformation(mProcess->hProcess,
|
||||
HMODULE(loadDll.lpBaseOfDll),
|
||||
&modinfo,
|
||||
sizeof(MODULEINFO));
|
||||
DllInfo dll(loadDll.lpBaseOfDll, modinfo.SizeOfImage, modinfo.EntryPoint);
|
||||
_process->dlls.insert({ Range(dll.lpBaseOfDll, dll.lpBaseOfDll + dll.sizeOfImage - 1), dll });
|
||||
mProcess->dlls.insert({ Range(dll.lpBaseOfDll, dll.lpBaseOfDll + dll.sizeOfImage - 1), dll });
|
||||
|
||||
//call the debug event callback
|
||||
cbLoadDllEvent(loadDll, dll);
|
||||
|
|
@ -25,14 +25,14 @@ namespace GleeBug
|
|||
{
|
||||
//call the debug event callback
|
||||
ptr lpBaseOfDll = ptr(unloadDll.lpBaseOfDll);
|
||||
auto dll = _process->dlls.find(Range(lpBaseOfDll, lpBaseOfDll));
|
||||
if (dll != _process->dlls.end())
|
||||
auto dll = mProcess->dlls.find(Range(lpBaseOfDll, lpBaseOfDll));
|
||||
if (dll != mProcess->dlls.end())
|
||||
cbUnloadDllEvent(unloadDll, dll->second);
|
||||
else
|
||||
cbUnloadDllEvent(unloadDll, DllInfo(unloadDll.lpBaseOfDll, 0, nullptr));
|
||||
|
||||
//DLL housekeeping
|
||||
if (dll != _process->dlls.end())
|
||||
_process->dlls.erase(dll);
|
||||
if (dll != mProcess->dlls.end())
|
||||
mProcess->dlls.erase(dll);
|
||||
}
|
||||
};
|
||||
|
|
@ -4,11 +4,11 @@ namespace GleeBug
|
|||
{
|
||||
void Debugger::exceptionBreakpoint(const EXCEPTION_RECORD & exceptionRecord, const bool firstChance)
|
||||
{
|
||||
if (!_process->systemBreakpoint) //handle system breakpoint
|
||||
if (!mProcess->systemBreakpoint) //handle system breakpoint
|
||||
{
|
||||
//set internal state
|
||||
_process->systemBreakpoint = true;
|
||||
_continueStatus = DBG_CONTINUE;
|
||||
mProcess->systemBreakpoint = true;
|
||||
mContinueStatus = DBG_CONTINUE;
|
||||
|
||||
//call the callback
|
||||
cbSystemBreakpoint();
|
||||
|
|
@ -16,63 +16,63 @@ namespace GleeBug
|
|||
else
|
||||
{
|
||||
//check if the breakpoint exists
|
||||
auto foundInfo = _process->breakpoints.find({ BreakpointType::Software, ptr(exceptionRecord.ExceptionAddress) });
|
||||
if (foundInfo == _process->breakpoints.end())
|
||||
auto foundInfo = mProcess->breakpoints.find({ BreakpointType::Software, ptr(exceptionRecord.ExceptionAddress) });
|
||||
if (foundInfo == mProcess->breakpoints.end())
|
||||
return;
|
||||
const auto info = foundInfo->second;
|
||||
|
||||
//set continue status
|
||||
_continueStatus = DBG_CONTINUE;
|
||||
mContinueStatus = DBG_CONTINUE;
|
||||
|
||||
//set back the instruction pointer
|
||||
_registers->Gip = info.address;
|
||||
mRegisters->Gip = info.address;
|
||||
|
||||
//restore the original breakpoint byte and do an internal step
|
||||
_process->MemWrite(info.address, info.internal.software.oldbytes, info.internal.software.size);
|
||||
_thread->StepInternal(std::bind([this, info]()
|
||||
mProcess->MemWrite(info.address, info.internal.software.oldbytes, info.internal.software.size);
|
||||
mThread->StepInternal(std::bind([this, info]()
|
||||
{
|
||||
//only restore the bytes if the breakpoint still exists
|
||||
if (_process->breakpoints.find({ BreakpointType::Software, info.address }) != _process->breakpoints.end())
|
||||
_process->MemWrite(info.address, info.internal.software.newbytes, info.internal.software.size);
|
||||
if (mProcess->breakpoints.find({ BreakpointType::Software, info.address }) != mProcess->breakpoints.end())
|
||||
mProcess->MemWrite(info.address, info.internal.software.newbytes, info.internal.software.size);
|
||||
}));
|
||||
|
||||
//call the generic callback
|
||||
cbBreakpoint(info);
|
||||
|
||||
//call the user callback
|
||||
auto foundCallback = _process->breakpointCallbacks.find({ BreakpointType::Software, info.address });
|
||||
if (foundCallback != _process->breakpointCallbacks.end())
|
||||
auto foundCallback = mProcess->breakpointCallbacks.find({ BreakpointType::Software, info.address });
|
||||
if (foundCallback != mProcess->breakpointCallbacks.end())
|
||||
foundCallback->second(info);
|
||||
|
||||
//delete the breakpoint if it is singleshoot
|
||||
if (info.singleshoot)
|
||||
_process->DeleteGenericBreakpoint(info);
|
||||
mProcess->DeleteGenericBreakpoint(info);
|
||||
}
|
||||
}
|
||||
|
||||
void Debugger::exceptionSingleStep(const EXCEPTION_RECORD & exceptionRecord, const bool firstChance)
|
||||
{
|
||||
if (_thread->isInternalStepping) //handle internal steps
|
||||
if (mThread->isInternalStepping) //handle internal steps
|
||||
{
|
||||
//set internal status
|
||||
_thread->isInternalStepping = false;
|
||||
_continueStatus = DBG_CONTINUE;
|
||||
mThread->isInternalStepping = false;
|
||||
mContinueStatus = DBG_CONTINUE;
|
||||
|
||||
//call the internal step callback
|
||||
_thread->cbInternalStep();
|
||||
mThread->cbInternalStep();
|
||||
}
|
||||
if (_thread->isSingleStepping) //handle single step
|
||||
if (mThread->isSingleStepping) //handle single step
|
||||
{
|
||||
//set internal status
|
||||
_thread->isSingleStepping = false;
|
||||
_continueStatus = DBG_CONTINUE;
|
||||
mThread->isSingleStepping = false;
|
||||
mContinueStatus = DBG_CONTINUE;
|
||||
|
||||
//call the generic callback
|
||||
cbStep();
|
||||
|
||||
//call the user callbacks
|
||||
auto cbStepCopy = _thread->stepCallbacks;
|
||||
_thread->stepCallbacks.clear();
|
||||
auto cbStepCopy = mThread->stepCallbacks;
|
||||
mThread->stepCallbacks.clear();
|
||||
for (auto cbStep : cbStepCopy)
|
||||
cbStep();
|
||||
}
|
||||
|
|
@ -85,69 +85,69 @@ namespace GleeBug
|
|||
void Debugger::exceptionHardwareBreakpoint(ptr exceptionAddress)
|
||||
{
|
||||
//determine the hardware breakpoint triggered
|
||||
ptr dr6 = _registers->Dr6();
|
||||
ptr dr6 = mRegisters->Dr6();
|
||||
HardwareSlot breakpointSlot;
|
||||
ptr breakpointAddress;
|
||||
if (exceptionAddress == _registers->Dr0() || dr6 & 0x1)
|
||||
if (exceptionAddress == mRegisters->Dr0() || dr6 & 0x1)
|
||||
{
|
||||
breakpointAddress = _registers->Dr0();
|
||||
breakpointAddress = mRegisters->Dr0();
|
||||
breakpointSlot = HardwareSlot::Dr0;
|
||||
}
|
||||
else if (exceptionAddress == _registers->Dr1() || dr6 & 0x2)
|
||||
else if (exceptionAddress == mRegisters->Dr1() || dr6 & 0x2)
|
||||
{
|
||||
breakpointAddress = _registers->Dr1();
|
||||
breakpointAddress = mRegisters->Dr1();
|
||||
breakpointSlot = HardwareSlot::Dr1;
|
||||
}
|
||||
else if (exceptionAddress == _registers->Dr2() || dr6 & 0x4)
|
||||
else if (exceptionAddress == mRegisters->Dr2() || dr6 & 0x4)
|
||||
{
|
||||
breakpointAddress = _registers->Dr2();
|
||||
breakpointAddress = mRegisters->Dr2();
|
||||
breakpointSlot = HardwareSlot::Dr2;
|
||||
}
|
||||
else if (exceptionAddress == _registers->Dr3() || dr6 & 0x8)
|
||||
else if (exceptionAddress == mRegisters->Dr3() || dr6 & 0x8)
|
||||
{
|
||||
breakpointAddress = _registers->Dr3();
|
||||
breakpointAddress = mRegisters->Dr3();
|
||||
breakpointSlot = HardwareSlot::Dr3;
|
||||
}
|
||||
else
|
||||
return; //not a hardware breakpoint
|
||||
|
||||
//find the breakpoint in the internal structures
|
||||
auto foundInfo = _process->breakpoints.find({ BreakpointType::Hardware, breakpointAddress });
|
||||
if (foundInfo == _process->breakpoints.end())
|
||||
auto foundInfo = mProcess->breakpoints.find({ BreakpointType::Hardware, breakpointAddress });
|
||||
if (foundInfo == mProcess->breakpoints.end())
|
||||
return; //not a valid hardware breakpoint
|
||||
const auto info = foundInfo->second;
|
||||
if (info.internal.hardware.slot != breakpointSlot)
|
||||
return; //not a valid hardware breakpoint
|
||||
|
||||
//set continue status
|
||||
_continueStatus = DBG_CONTINUE;
|
||||
mContinueStatus = DBG_CONTINUE;
|
||||
|
||||
//delete the hardware breakpoint from the thread (not the breakpoint buffer) and do an internal step (TODO: maybe delete from all threads?)
|
||||
_thread->DeleteHardwareBreakpoint(breakpointSlot);
|
||||
_thread->StepInternal(std::bind([this, info]()
|
||||
mThread->DeleteHardwareBreakpoint(breakpointSlot);
|
||||
mThread->StepInternal(std::bind([this, info]()
|
||||
{
|
||||
//only restore if the breakpoint still exists
|
||||
if (_process->breakpoints.find({ BreakpointType::Hardware, info.address }) != _process->breakpoints.end())
|
||||
_thread->SetHardwareBreakpoint(info.address, info.internal.hardware.slot, info.internal.hardware.type, info.internal.hardware.size);
|
||||
if (mProcess->breakpoints.find({ BreakpointType::Hardware, info.address }) != mProcess->breakpoints.end())
|
||||
mThread->SetHardwareBreakpoint(info.address, info.internal.hardware.slot, info.internal.hardware.type, info.internal.hardware.size);
|
||||
}));
|
||||
|
||||
//call the generic callback
|
||||
cbBreakpoint(info);
|
||||
|
||||
//call the user callback
|
||||
auto foundCallback = _process->breakpointCallbacks.find({ BreakpointType::Hardware, info.address });
|
||||
if (foundCallback != _process->breakpointCallbacks.end())
|
||||
auto foundCallback = mProcess->breakpointCallbacks.find({ BreakpointType::Hardware, info.address });
|
||||
if (foundCallback != mProcess->breakpointCallbacks.end())
|
||||
foundCallback->second(info);
|
||||
|
||||
//delete the breakpoint if it is singleshoot
|
||||
if (info.singleshoot)
|
||||
_process->DeleteGenericBreakpoint(info);
|
||||
mProcess->DeleteGenericBreakpoint(info);
|
||||
}
|
||||
|
||||
void Debugger::exceptionEvent(const EXCEPTION_DEBUG_INFO & exceptionInfo)
|
||||
{
|
||||
//let the debuggee handle exceptions per default
|
||||
_continueStatus = DBG_EXCEPTION_NOT_HANDLED;
|
||||
mContinueStatus = DBG_EXCEPTION_NOT_HANDLED;
|
||||
|
||||
const EXCEPTION_RECORD & exceptionRecord = exceptionInfo.ExceptionRecord;
|
||||
bool firstChance = exceptionInfo.dwFirstChance == 1;
|
||||
|
|
@ -167,7 +167,7 @@ namespace GleeBug
|
|||
}
|
||||
|
||||
//call the unhandled exception callback
|
||||
if (_continueStatus == DBG_EXCEPTION_NOT_HANDLED)
|
||||
if (mContinueStatus == DBG_EXCEPTION_NOT_HANDLED)
|
||||
cbUnhandledException(exceptionRecord, firstChance);
|
||||
}
|
||||
};
|
||||
|
|
@ -5,27 +5,27 @@ namespace GleeBug
|
|||
void Debugger::createProcessEvent(const CREATE_PROCESS_DEBUG_INFO & createProcess)
|
||||
{
|
||||
//process housekeeping
|
||||
_processes.insert({ _debugEvent.dwProcessId,
|
||||
mProcesses.insert({ mDebugEvent.dwProcessId,
|
||||
ProcessInfo(createProcess.hProcess,
|
||||
_debugEvent.dwProcessId,
|
||||
_debugEvent.dwThreadId) });
|
||||
_process = &_processes.find(_debugEvent.dwProcessId)->second;
|
||||
mDebugEvent.dwProcessId,
|
||||
mDebugEvent.dwThreadId) });
|
||||
mProcess = &mProcesses.find(mDebugEvent.dwProcessId)->second;
|
||||
|
||||
//thread housekeeping (main thread is created implicitly)
|
||||
_process->threads.insert({ _debugEvent.dwThreadId,
|
||||
mProcess->threads.insert({ mDebugEvent.dwThreadId,
|
||||
ThreadInfo(createProcess.hThread,
|
||||
_debugEvent.dwThreadId,
|
||||
mDebugEvent.dwThreadId,
|
||||
createProcess.lpThreadLocalBase,
|
||||
createProcess.lpStartAddress) });
|
||||
_thread = _process->thread = &_process->threads.find(_debugEvent.dwThreadId)->second;
|
||||
_registers = &_thread->registers;
|
||||
mThread = mProcess->thread = &mProcess->threads.find(mDebugEvent.dwThreadId)->second;
|
||||
mRegisters = &mThread->registers;
|
||||
|
||||
//read thread context from main thread
|
||||
if (!_thread->RegReadContext())
|
||||
if (!mThread->RegReadContext())
|
||||
cbInternalError("ThreadInfo::RegReadContext() failed!");
|
||||
|
||||
//call the debug event callback
|
||||
cbCreateProcessEvent(createProcess, *_process);
|
||||
cbCreateProcessEvent(createProcess, *mProcess);
|
||||
|
||||
//close the file handle
|
||||
CloseHandle(createProcess.hFile);
|
||||
|
|
@ -34,18 +34,18 @@ namespace GleeBug
|
|||
void Debugger::exitProcessEvent(const EXIT_PROCESS_DEBUG_INFO & exitProcess)
|
||||
{
|
||||
//check if the terminated process is the main debuggee
|
||||
if (_debugEvent.dwProcessId == _mainProcess.dwProcessId)
|
||||
_breakDebugger = true;
|
||||
if (mDebugEvent.dwProcessId == mMainProcess.dwProcessId)
|
||||
mBreakDebugger = true;
|
||||
|
||||
//call the debug event callback
|
||||
cbExitProcessEvent(exitProcess, *_process);
|
||||
cbExitProcessEvent(exitProcess, *mProcess);
|
||||
|
||||
//process housekeeping
|
||||
_processes.erase(_debugEvent.dwProcessId);
|
||||
mProcesses.erase(mDebugEvent.dwProcessId);
|
||||
|
||||
//set the current process
|
||||
_process = nullptr;
|
||||
_thread = nullptr;
|
||||
_registers = nullptr;
|
||||
mProcess = nullptr;
|
||||
mThread = nullptr;
|
||||
mRegisters = nullptr;
|
||||
}
|
||||
};
|
||||
|
|
@ -5,7 +5,7 @@ namespace GleeBug
|
|||
void Debugger::ripEvent(const RIP_INFO & rip)
|
||||
{
|
||||
//prevent anti-debug trick (RIP events are actually exceptions)
|
||||
_continueStatus = DBG_EXCEPTION_NOT_HANDLED;
|
||||
mContinueStatus = DBG_EXCEPTION_NOT_HANDLED;
|
||||
|
||||
//call the debug event callback
|
||||
cbRipEvent(rip);
|
||||
|
|
|
|||
|
|
@ -5,32 +5,32 @@ namespace GleeBug
|
|||
void Debugger::createThreadEvent(const CREATE_THREAD_DEBUG_INFO & createThread)
|
||||
{
|
||||
//thread housekeeping
|
||||
_process->threads.insert({ _debugEvent.dwThreadId,
|
||||
mProcess->threads.insert({ mDebugEvent.dwThreadId,
|
||||
ThreadInfo(createThread.hThread,
|
||||
_debugEvent.dwThreadId,
|
||||
mDebugEvent.dwThreadId,
|
||||
createThread.lpThreadLocalBase,
|
||||
createThread.lpStartAddress) });
|
||||
|
||||
//set the current thread
|
||||
_thread = _process->thread = &_process->threads.find(_debugEvent.dwThreadId)->second;
|
||||
_registers = &_thread->registers;
|
||||
if (!_thread->RegReadContext())
|
||||
mThread = mProcess->thread = &mProcess->threads.find(mDebugEvent.dwThreadId)->second;
|
||||
mRegisters = &mThread->registers;
|
||||
if (!mThread->RegReadContext())
|
||||
cbInternalError("ThreadInfo::RegReadContext() failed!");
|
||||
|
||||
//call the debug event callback
|
||||
cbCreateThreadEvent(createThread, *_thread);
|
||||
cbCreateThreadEvent(createThread, *mThread);
|
||||
}
|
||||
|
||||
void Debugger::exitThreadEvent(const EXIT_THREAD_DEBUG_INFO & exitThread)
|
||||
{
|
||||
//call the debug event callback
|
||||
cbExitThreadEvent(exitThread, *_thread);
|
||||
cbExitThreadEvent(exitThread, *mThread);
|
||||
|
||||
//thread housekeeping
|
||||
_process->threads.erase(_debugEvent.dwThreadId);
|
||||
mProcess->threads.erase(mDebugEvent.dwThreadId);
|
||||
|
||||
//set the current thread
|
||||
_thread = _process->thread = nullptr;
|
||||
_registers = nullptr;
|
||||
mThread = mProcess->thread = nullptr;
|
||||
mRegisters = nullptr;
|
||||
}
|
||||
};
|
||||
|
|
@ -5,7 +5,7 @@ namespace GleeBug
|
|||
void Debugger::unknownEvent(DWORD debugEventCode)
|
||||
{
|
||||
//prevent possible anti-debug trick
|
||||
_continueStatus = DBG_EXCEPTION_NOT_HANDLED;
|
||||
mContinueStatus = DBG_EXCEPTION_NOT_HANDLED;
|
||||
|
||||
//call the debug event callback
|
||||
cbUnknownEvent(debugEventCode);
|
||||
|
|
|
|||
|
|
@ -5,106 +5,106 @@ namespace GleeBug
|
|||
void Debugger::Start()
|
||||
{
|
||||
//initialize loop variables
|
||||
_breakDebugger = false;
|
||||
_isDebugging = true;
|
||||
mBreakDebugger = false;
|
||||
mIsDebugging = true;
|
||||
|
||||
while (!_breakDebugger)
|
||||
while (!mBreakDebugger)
|
||||
{
|
||||
//wait for a debug event
|
||||
_isRunning = true;
|
||||
if (!WaitForDebugEvent(&_debugEvent, INFINITE))
|
||||
mIsRunning = true;
|
||||
if (!WaitForDebugEvent(&mDebugEvent, INFINITE))
|
||||
break;
|
||||
_isRunning = false;
|
||||
mIsRunning = false;
|
||||
|
||||
//set default continue status
|
||||
_continueStatus = DBG_EXCEPTION_NOT_HANDLED;
|
||||
mContinueStatus = DBG_EXCEPTION_NOT_HANDLED;
|
||||
|
||||
//set the current process and thread
|
||||
auto processFound = _processes.find(_debugEvent.dwProcessId);
|
||||
if (processFound != _processes.end())
|
||||
auto processFound = mProcesses.find(mDebugEvent.dwProcessId);
|
||||
if (processFound != mProcesses.end())
|
||||
{
|
||||
_process = &processFound->second;
|
||||
auto threadFound = _process->threads.find(_debugEvent.dwThreadId);
|
||||
if (threadFound != _process->threads.end())
|
||||
mProcess = &processFound->second;
|
||||
auto threadFound = mProcess->threads.find(mDebugEvent.dwThreadId);
|
||||
if (threadFound != mProcess->threads.end())
|
||||
{
|
||||
_thread = _process->thread = &threadFound->second;
|
||||
_registers = &_thread->registers;
|
||||
if (!_thread->RegReadContext())
|
||||
mThread = mProcess->thread = &threadFound->second;
|
||||
mRegisters = &mThread->registers;
|
||||
if (!mThread->RegReadContext())
|
||||
cbInternalError("ThreadInfo::RegReadContext() failed!");
|
||||
}
|
||||
else
|
||||
{
|
||||
_thread = _process->thread = nullptr;
|
||||
_registers = nullptr;
|
||||
mThread = mProcess->thread = nullptr;
|
||||
mRegisters = nullptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_registers = nullptr;
|
||||
_thread = nullptr;
|
||||
if (_process)
|
||||
mRegisters = nullptr;
|
||||
mThread = nullptr;
|
||||
if (mProcess)
|
||||
{
|
||||
_process->thread = nullptr;
|
||||
_process = nullptr;
|
||||
mProcess->thread = nullptr;
|
||||
mProcess = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
//call the pre debug event callback
|
||||
cbPostDebugEvent(_debugEvent);
|
||||
cbPostDebugEvent(mDebugEvent);
|
||||
|
||||
//dispatch the debug event
|
||||
switch (_debugEvent.dwDebugEventCode)
|
||||
switch (mDebugEvent.dwDebugEventCode)
|
||||
{
|
||||
case CREATE_PROCESS_DEBUG_EVENT:
|
||||
createProcessEvent(_debugEvent.u.CreateProcessInfo);
|
||||
createProcessEvent(mDebugEvent.u.CreateProcessInfo);
|
||||
break;
|
||||
case EXIT_PROCESS_DEBUG_EVENT:
|
||||
exitProcessEvent(_debugEvent.u.ExitProcess);
|
||||
exitProcessEvent(mDebugEvent.u.ExitProcess);
|
||||
break;
|
||||
case CREATE_THREAD_DEBUG_EVENT:
|
||||
createThreadEvent(_debugEvent.u.CreateThread);
|
||||
createThreadEvent(mDebugEvent.u.CreateThread);
|
||||
break;
|
||||
case EXIT_THREAD_DEBUG_EVENT:
|
||||
exitThreadEvent(_debugEvent.u.ExitThread);
|
||||
exitThreadEvent(mDebugEvent.u.ExitThread);
|
||||
break;
|
||||
case LOAD_DLL_DEBUG_EVENT:
|
||||
loadDllEvent(_debugEvent.u.LoadDll);
|
||||
loadDllEvent(mDebugEvent.u.LoadDll);
|
||||
break;
|
||||
case UNLOAD_DLL_DEBUG_EVENT:
|
||||
unloadDllEvent(_debugEvent.u.UnloadDll);
|
||||
unloadDllEvent(mDebugEvent.u.UnloadDll);
|
||||
break;
|
||||
case EXCEPTION_DEBUG_EVENT:
|
||||
exceptionEvent(_debugEvent.u.Exception);
|
||||
exceptionEvent(mDebugEvent.u.Exception);
|
||||
break;
|
||||
case OUTPUT_DEBUG_STRING_EVENT:
|
||||
debugStringEvent(_debugEvent.u.DebugString);
|
||||
debugStringEvent(mDebugEvent.u.DebugString);
|
||||
break;
|
||||
case RIP_EVENT:
|
||||
ripEvent(_debugEvent.u.RipInfo);
|
||||
ripEvent(mDebugEvent.u.RipInfo);
|
||||
break;
|
||||
default:
|
||||
unknownEvent(_debugEvent.dwDebugEventCode);
|
||||
unknownEvent(mDebugEvent.dwDebugEventCode);
|
||||
break;
|
||||
}
|
||||
|
||||
//call the post debug event callback
|
||||
cbPostDebugEvent(_debugEvent);
|
||||
cbPostDebugEvent(mDebugEvent);
|
||||
|
||||
//write the register context
|
||||
if (_thread)
|
||||
if (mThread)
|
||||
{
|
||||
if (!_thread->RegWriteContext())
|
||||
if (!mThread->RegWriteContext())
|
||||
cbInternalError("ThreadInfo::RegWriteContext() failed!");
|
||||
}
|
||||
|
||||
//continue the debug event
|
||||
if (!ContinueDebugEvent(_debugEvent.dwProcessId, _debugEvent.dwThreadId, _continueStatus))
|
||||
if (!ContinueDebugEvent(mDebugEvent.dwProcessId, mDebugEvent.dwThreadId, mContinueStatus))
|
||||
break;
|
||||
}
|
||||
|
||||
//cleanup
|
||||
_processes.clear();
|
||||
_process = nullptr;
|
||||
_isDebugging = false;
|
||||
mProcesses.clear();
|
||||
mProcess = nullptr;
|
||||
mIsDebugging = false;
|
||||
}
|
||||
};
|
||||
|
|
@ -25,7 +25,10 @@ public:
|
|||
\brief Constructor.
|
||||
\param registers Pointer to the registers object.
|
||||
*/
|
||||
explicit Flag(Registers* registers) : _registers(registers) {}
|
||||
explicit Flag(Registers* registers)
|
||||
: mRegisters(registers)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Gets the flag.
|
||||
|
|
@ -33,7 +36,7 @@ public:
|
|||
*/
|
||||
bool Get() const
|
||||
{
|
||||
return _registers->GetFlag(FlagIndex);
|
||||
return mRegisters->GetFlag(FlagIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -42,7 +45,7 @@ public:
|
|||
*/
|
||||
void Set(bool value = true)
|
||||
{
|
||||
_registers->SetFlag(FlagIndex, value);
|
||||
mRegisters->SetFlag(FlagIndex, value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -108,7 +111,7 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
Registers* _registers;
|
||||
Registers* mRegisters;
|
||||
};
|
||||
|
||||
#endif //DEBUGGER_THREAD_REGISTERS_FLAG_H
|
||||
|
|
@ -1,25 +1,25 @@
|
|||
#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
|
||||
#define contextGax mContext.Rax
|
||||
#define contextGbx mContext.Rbx
|
||||
#define contextGcx mContext.Rcx
|
||||
#define contextGdx mContext.Rdx
|
||||
#define contextGdi mContext.Rdi
|
||||
#define contextGsi mContext.Rsi
|
||||
#define contextGbp mContext.Rbp
|
||||
#define contextGsp mContext.Rsp
|
||||
#define contextGip mContext.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
|
||||
#define contextGax mContext.Eax
|
||||
#define contextGbx mContext.Ebx
|
||||
#define contextGcx mContext.Ecx
|
||||
#define contextGdx mContext.Edx
|
||||
#define contextGdi mContext.Edi
|
||||
#define contextGsi mContext.Esi
|
||||
#define contextGbp mContext.Ebp
|
||||
#define contextGsp mContext.Esp
|
||||
#define contextGip mContext.Eip
|
||||
#endif //_WIN64
|
||||
|
||||
#ifdef _WIN64
|
||||
|
|
@ -50,20 +50,20 @@ namespace GleeBug
|
|||
switch (reg)
|
||||
{
|
||||
case R::DR0:
|
||||
return ptr(_context.Dr0);
|
||||
return ptr(mContext.Dr0);
|
||||
case R::DR1:
|
||||
return ptr(_context.Dr1);
|
||||
return ptr(mContext.Dr1);
|
||||
case R::DR2:
|
||||
return ptr(_context.Dr2);
|
||||
return ptr(mContext.Dr2);
|
||||
case R::DR3:
|
||||
return ptr(_context.Dr3);
|
||||
return ptr(mContext.Dr3);
|
||||
case R::DR6:
|
||||
return ptr(_context.Dr6);
|
||||
return ptr(mContext.Dr6);
|
||||
case R::DR7:
|
||||
return ptr(_context.Dr7);
|
||||
return ptr(mContext.Dr7);
|
||||
|
||||
case R::EFlags:
|
||||
return ptr(_context.EFlags);
|
||||
return ptr(mContext.EFlags);
|
||||
|
||||
case R::EAX:
|
||||
return uint32_lo(contextGax);
|
||||
|
|
@ -238,26 +238,26 @@ namespace GleeBug
|
|||
switch (reg)
|
||||
{
|
||||
case R::DR0:
|
||||
_context.Dr0 = value;
|
||||
mContext.Dr0 = value;
|
||||
break;
|
||||
case R::DR1:
|
||||
_context.Dr1 = value;
|
||||
mContext.Dr1 = value;
|
||||
break;
|
||||
case R::DR2:
|
||||
_context.Dr2 = value;
|
||||
mContext.Dr2 = value;
|
||||
break;
|
||||
case R::DR3:
|
||||
_context.Dr3 = value;
|
||||
mContext.Dr3 = value;
|
||||
break;
|
||||
case R::DR6:
|
||||
_context.Dr6 = value;
|
||||
mContext.Dr6 = value;
|
||||
break;
|
||||
case R::DR7:
|
||||
_context.Dr7 = value;
|
||||
mContext.Dr7 = value;
|
||||
break;
|
||||
|
||||
case R::EFlags:
|
||||
_context.EFlags = uint32(value);
|
||||
mContext.EFlags = uint32(value);
|
||||
break;
|
||||
|
||||
case R::EAX:
|
||||
|
|
@ -506,14 +506,14 @@ namespace GleeBug
|
|||
|
||||
bool Registers::GetFlag(F flag) const
|
||||
{
|
||||
return (_context.EFlags & ptr(flag)) == ptr(flag);
|
||||
return (mContext.EFlags & ptr(flag)) == ptr(flag);
|
||||
}
|
||||
|
||||
void Registers::SetFlag(F flag, bool set)
|
||||
{
|
||||
if (set)
|
||||
_context.EFlags |= ptr(flag);
|
||||
mContext.EFlags |= ptr(flag);
|
||||
else
|
||||
_context.EFlags &= ~ptr(flag);
|
||||
mContext.EFlags &= ~ptr(flag);
|
||||
}
|
||||
}
|
||||
|
|
@ -116,7 +116,10 @@ public:
|
|||
\brief Constructor.
|
||||
\param registers Pointer to the registers.
|
||||
*/
|
||||
explicit Register(Registers* registers) : _registers(registers) {}
|
||||
explicit Register(Registers* registers)
|
||||
: mRegisters(registers)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Gets the register value.
|
||||
|
|
@ -124,7 +127,7 @@ public:
|
|||
*/
|
||||
Type Get() const
|
||||
{
|
||||
return Type(_registers->Get(RegisterIndex));
|
||||
return Type(mRegisters->Get(RegisterIndex));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -133,7 +136,7 @@ public:
|
|||
*/
|
||||
void Set(Type value)
|
||||
{
|
||||
_registers->Set(RegisterIndex, ptr(value));
|
||||
mRegisters->Set(RegisterIndex, ptr(value));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -285,7 +288,7 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
Registers* _registers;
|
||||
Registers* mRegisters;
|
||||
};
|
||||
|
||||
#endif //DEBUGGER_THREAD_REGISTERS_REGISTER_H
|
||||
|
|
@ -99,16 +99,16 @@ namespace GleeBug
|
|||
TrapFlag(this),
|
||||
ResumeFlag(this)
|
||||
{
|
||||
memset(&this->_context, 0, sizeof(CONTEXT));
|
||||
memset(&this->mContext, 0, sizeof(CONTEXT));
|
||||
}
|
||||
|
||||
const CONTEXT* Registers::GetContext() const
|
||||
{
|
||||
return &_context;
|
||||
return &mContext;
|
||||
}
|
||||
|
||||
void Registers::SetContext(const CONTEXT & context)
|
||||
{
|
||||
this->_context = context;
|
||||
this->mContext = context;
|
||||
}
|
||||
};
|
||||
|
|
@ -156,7 +156,7 @@ namespace GleeBug
|
|||
void SetContext(const CONTEXT & context);
|
||||
|
||||
private:
|
||||
CONTEXT _context;
|
||||
CONTEXT mContext;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -43,12 +43,12 @@ namespace GleeBug
|
|||
bool ThreadInfo::RegReadContext()
|
||||
{
|
||||
SuspendThread(this->hThread);
|
||||
memset(&this->_oldContext, 0, sizeof(CONTEXT));
|
||||
this->_oldContext.ContextFlags = CONTEXT_ALL;
|
||||
memset(&this->mOldContext, 0, sizeof(CONTEXT));
|
||||
this->mOldContext.ContextFlags = CONTEXT_ALL;
|
||||
bool bReturn = false;
|
||||
if (GetThreadContext(this->hThread, &this->_oldContext))
|
||||
if (GetThreadContext(this->hThread, &this->mOldContext))
|
||||
{
|
||||
this->registers.SetContext(this->_oldContext);
|
||||
this->registers.SetContext(this->mOldContext);
|
||||
bReturn = true;
|
||||
}
|
||||
ResumeThread(this->hThread);
|
||||
|
|
@ -58,7 +58,7 @@ namespace GleeBug
|
|||
bool ThreadInfo::RegWriteContext() const
|
||||
{
|
||||
//check if something actually changed
|
||||
if (memcmp(&this->_oldContext, this->registers.GetContext(), sizeof(CONTEXT)) == 0)
|
||||
if (memcmp(&this->mOldContext, this->registers.GetContext(), sizeof(CONTEXT)) == 0)
|
||||
return true;
|
||||
//update the context
|
||||
SuspendThread(this->hThread);
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ namespace GleeBug
|
|||
bool DeleteHardwareBreakpoint(HardwareSlot slot);
|
||||
|
||||
private:
|
||||
CONTEXT _oldContext;
|
||||
CONTEXT mOldContext;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ namespace GleeBug
|
|||
{
|
||||
Debugger::Debugger()
|
||||
{
|
||||
_processes.clear();
|
||||
mProcesses.clear();
|
||||
}
|
||||
|
||||
Debugger::~Debugger()
|
||||
|
|
@ -43,7 +43,7 @@ namespace GleeBug
|
|||
nullptr,
|
||||
szCurrentDirectory,
|
||||
&si,
|
||||
&_mainProcess);
|
||||
&mMainProcess);
|
||||
|
||||
delete[] szCreateWithCmdLine;
|
||||
|
||||
|
|
@ -52,11 +52,11 @@ namespace GleeBug
|
|||
|
||||
bool Debugger::Stop() const
|
||||
{
|
||||
return !!TerminateProcess(_mainProcess.hProcess, 0);
|
||||
return !!TerminateProcess(mMainProcess.hProcess, 0);
|
||||
}
|
||||
|
||||
bool Debugger::Detach() const
|
||||
{
|
||||
return !!DebugActiveProcessStop(_mainProcess.dwProcessId);
|
||||
return !!DebugActiveProcessStop(mMainProcess.dwProcessId);
|
||||
}
|
||||
};
|
||||
|
|
@ -243,28 +243,28 @@ namespace GleeBug
|
|||
virtual void exceptionHardwareBreakpoint(ptr exceptionAddress);
|
||||
|
||||
protected: //variables
|
||||
PROCESS_INFORMATION _mainProcess;
|
||||
uint32 _continueStatus = DBG_EXCEPTION_NOT_HANDLED;
|
||||
bool _breakDebugger = false;
|
||||
DEBUG_EVENT _debugEvent;
|
||||
ProcessMap _processes;
|
||||
bool _isRunning = false;
|
||||
bool _isDebugging = false;
|
||||
PROCESS_INFORMATION mMainProcess;
|
||||
uint32 mContinueStatus = DBG_EXCEPTION_NOT_HANDLED;
|
||||
bool mBreakDebugger = false;
|
||||
DEBUG_EVENT mDebugEvent;
|
||||
ProcessMap mProcesses;
|
||||
bool mIsRunning = false;
|
||||
bool mIsDebugging = false;
|
||||
|
||||
/**
|
||||
\brief The current process (can be null in some cases).
|
||||
*/
|
||||
ProcessInfo* _process = nullptr;
|
||||
ProcessInfo* mProcess = nullptr;
|
||||
|
||||
/**
|
||||
\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 mProcess->thread.
|
||||
*/
|
||||
ThreadInfo* _thread = nullptr;
|
||||
ThreadInfo* mThread = nullptr;
|
||||
|
||||
/**
|
||||
\brief The current thread registers (can be null in some cases). Should be a copy of _thread->registers.
|
||||
\brief The current thread registers (can be null in some cases). Should be a copy of mThread->registers.
|
||||
*/
|
||||
Registers* _registers = nullptr;
|
||||
Registers* mRegisters = nullptr;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ namespace GleeBug
|
|||
{
|
||||
BufferFile::BufferFile(void* data, uint32 size)
|
||||
: File(nullptr),
|
||||
_data(data),
|
||||
_size(size)
|
||||
mData(data),
|
||||
mSize(size)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -21,7 +21,7 @@ namespace GleeBug
|
|||
|
||||
bool BufferFile::IsOpen() const
|
||||
{
|
||||
return !!_data;
|
||||
return !!mData;
|
||||
}
|
||||
|
||||
void BufferFile::Close()
|
||||
|
|
@ -30,21 +30,21 @@ namespace GleeBug
|
|||
|
||||
uint32 BufferFile::GetSize() const
|
||||
{
|
||||
return _size;
|
||||
return mSize;
|
||||
}
|
||||
|
||||
bool BufferFile::Read(uint32 offset, void* data, uint32 size, uint32* bytesRead) const
|
||||
{
|
||||
if (offset >= _size)
|
||||
if (offset >= mSize)
|
||||
return false;
|
||||
auto readSize = size;
|
||||
auto result = true;
|
||||
if (offset + size > _size)
|
||||
if (offset + size > mSize)
|
||||
{
|
||||
readSize = _size - offset;
|
||||
readSize = mSize - offset;
|
||||
result = false;
|
||||
}
|
||||
memcpy(data, (uint8*)_data + offset, readSize);
|
||||
memcpy(data, (uint8*)mData + offset, readSize);
|
||||
if (bytesRead)
|
||||
*bytesRead = readSize;
|
||||
return result;
|
||||
|
|
@ -52,16 +52,16 @@ namespace GleeBug
|
|||
|
||||
bool BufferFile::Write(uint32 offset, const void* data, uint32 size, uint32* bytesWritten)
|
||||
{
|
||||
if (offset >= _size)
|
||||
if (offset >= mSize)
|
||||
return false;
|
||||
auto writeSize = size;
|
||||
auto result = true;
|
||||
if (offset + size > _size)
|
||||
if (offset + size > mSize)
|
||||
{
|
||||
writeSize = _size - offset;
|
||||
writeSize = mSize - offset;
|
||||
result = false;
|
||||
}
|
||||
memcpy((uint8*)_data + offset, data, writeSize);
|
||||
memcpy((uint8*)mData + offset, data, writeSize);
|
||||
if (bytesWritten)
|
||||
*bytesWritten = writeSize;
|
||||
return result;
|
||||
|
|
|
|||
|
|
@ -59,8 +59,8 @@ namespace GleeBug
|
|||
virtual bool Write(uint32 offset, const void* data, uint32 size, uint32* bytesWritten = nullptr) override;
|
||||
|
||||
private:
|
||||
void* _data;
|
||||
uint32 _size;
|
||||
void* mData;
|
||||
uint32 mSize;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@
|
|||
namespace GleeBug
|
||||
{
|
||||
File::File(const wchar_t* szFileName, File::Mode mode)
|
||||
: _fileName(szFileName ? szFileName : L""),
|
||||
_mode(mode),
|
||||
_hFile(INVALID_HANDLE_VALUE)
|
||||
: mFileName(szFileName ? szFileName : L""),
|
||||
mMode(mode),
|
||||
mhFile(INVALID_HANDLE_VALUE)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -26,33 +26,33 @@ namespace GleeBug
|
|||
|
||||
bool File::IsOpen() const
|
||||
{
|
||||
return _hFile != INVALID_HANDLE_VALUE;
|
||||
return mhFile != INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
void File::Close()
|
||||
{
|
||||
if (IsOpen())
|
||||
{
|
||||
CloseHandle(_hFile);
|
||||
_hFile = INVALID_HANDLE_VALUE;
|
||||
CloseHandle(mhFile);
|
||||
mhFile = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 File::GetSize() const
|
||||
{
|
||||
return IsOpen() ? GetFileSize(_hFile, nullptr) : 0;
|
||||
return IsOpen() ? GetFileSize(mhFile, nullptr) : 0;
|
||||
}
|
||||
|
||||
bool File::Read(uint32 offset, void* data, uint32 size, uint32* bytesRead) const
|
||||
{
|
||||
if (!IsOpen() || SetFilePointer(_hFile, offset, nullptr, FILE_BEGIN) == INVALID_SET_FILE_POINTER)
|
||||
if (!IsOpen() || SetFilePointer(mhFile, offset, nullptr, FILE_BEGIN) == INVALID_SET_FILE_POINTER)
|
||||
{
|
||||
if (bytesRead)
|
||||
*bytesRead = 0;
|
||||
return false;
|
||||
}
|
||||
DWORD NumberOfBytesRead = 0;
|
||||
auto result = !!ReadFile(_hFile, data, size, &NumberOfBytesRead, nullptr);
|
||||
auto result = !!ReadFile(mhFile, data, size, &NumberOfBytesRead, nullptr);
|
||||
if (bytesRead)
|
||||
*bytesRead = uint32(NumberOfBytesRead);
|
||||
return result;
|
||||
|
|
@ -60,14 +60,14 @@ namespace GleeBug
|
|||
|
||||
bool File::Write(uint32 offset, const void* data, uint32 size, uint32* bytesWritten)
|
||||
{
|
||||
if (!IsOpen() || SetFilePointer(_hFile, offset, nullptr, FILE_BEGIN) == INVALID_SET_FILE_POINTER)
|
||||
if (!IsOpen() || SetFilePointer(mhFile, offset, nullptr, FILE_BEGIN) == INVALID_SET_FILE_POINTER)
|
||||
{
|
||||
if (bytesWritten)
|
||||
*bytesWritten = 0;
|
||||
return false;
|
||||
}
|
||||
DWORD NumberOfBytesWritten = 0;
|
||||
auto result = !!WriteFile(_hFile, data, size, &NumberOfBytesWritten, nullptr);
|
||||
auto result = !!WriteFile(mhFile, data, size, &NumberOfBytesWritten, nullptr);
|
||||
if (bytesWritten)
|
||||
*bytesWritten = uint32(NumberOfBytesWritten);
|
||||
return result;
|
||||
|
|
@ -77,7 +77,7 @@ namespace GleeBug
|
|||
{
|
||||
//get the access and sharemode flags
|
||||
DWORD access, sharemode;
|
||||
switch (_mode)
|
||||
switch (mMode)
|
||||
{
|
||||
case ReadOnly:
|
||||
access = GENERIC_READ;
|
||||
|
|
@ -95,7 +95,7 @@ namespace GleeBug
|
|||
Close();
|
||||
|
||||
//use WinAPI to get the file handle
|
||||
_hFile = CreateFileW(_fileName.c_str(), access, sharemode, nullptr, creation, 0, nullptr);
|
||||
mhFile = CreateFileW(mFileName.c_str(), access, sharemode, nullptr, creation, 0, nullptr);
|
||||
return IsOpen();
|
||||
}
|
||||
};
|
||||
|
|
@ -83,9 +83,9 @@ namespace GleeBug
|
|||
private:
|
||||
bool internalOpen(DWORD creation);
|
||||
|
||||
std::wstring _fileName;
|
||||
Mode _mode;
|
||||
HANDLE _hFile;
|
||||
std::wstring mFileName;
|
||||
Mode mMode;
|
||||
HANDLE mhFile;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
namespace GleeBug
|
||||
{
|
||||
Pe::Pe(File & file)
|
||||
: _file(file)
|
||||
: mFile(file)
|
||||
{
|
||||
Clear();
|
||||
setupErrorMap();
|
||||
|
|
@ -11,14 +11,14 @@ namespace GleeBug
|
|||
|
||||
void Pe::Clear()
|
||||
{
|
||||
_fileSize = 0;
|
||||
_data.clear();
|
||||
_offset = 0;
|
||||
_dosHeader = Region<IMAGE_DOS_HEADER>();
|
||||
_afterDosData = Region<uint8>();
|
||||
_ntHeaders32 = Region<IMAGE_NT_HEADERS32>();
|
||||
_ntHeaders64 = Region<IMAGE_NT_HEADERS64>();
|
||||
_sectionHeaders = Region<IMAGE_SECTION_HEADER>();
|
||||
mFileSize = 0;
|
||||
mData.clear();
|
||||
mOffset = 0;
|
||||
mDosHeader = Region<IMAGE_DOS_HEADER>();
|
||||
mAfterDosData = Region<uint8>();
|
||||
mNtHeaders32 = Region<IMAGE_NT_HEADERS32>();
|
||||
mNtHeaders64 = Region<IMAGE_NT_HEADERS64>();
|
||||
mSectionHeaders = Region<IMAGE_SECTION_HEADER>();
|
||||
}
|
||||
|
||||
Pe::Error Pe::ParseHeaders()
|
||||
|
|
@ -27,29 +27,29 @@ namespace GleeBug
|
|||
Clear();
|
||||
|
||||
//read the DOS header
|
||||
_dosHeader = readRegion<IMAGE_DOS_HEADER>();
|
||||
if (!_dosHeader)
|
||||
mDosHeader = readRegion<IMAGE_DOS_HEADER>();
|
||||
if (!mDosHeader)
|
||||
return ErrorDosHeaderRead;
|
||||
|
||||
//verify the DOS header
|
||||
if (_dosHeader->e_magic != IMAGE_DOS_SIGNATURE)
|
||||
if (mDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
|
||||
return ErrorDosHeaderMagic;
|
||||
|
||||
//get the NT headers offset
|
||||
auto newOffset = _dosHeader->e_lfanew;
|
||||
auto newOffset = mDosHeader->e_lfanew;
|
||||
|
||||
//verify the new offset
|
||||
if (newOffset < 0 || uint32(newOffset) >= _file.GetSize())
|
||||
if (newOffset < 0 || uint32(newOffset) >= mFile.GetSize())
|
||||
return ErrorDosHeaderNtHeaderOffset;
|
||||
|
||||
//TODO: special case where DOS and PE header overlap (tinygui.exe)
|
||||
if (uint32(newOffset) < _offset)
|
||||
if (uint32(newOffset) < mOffset)
|
||||
return ErrorDosHeaderNtHeaderOffsetOverlap;
|
||||
|
||||
//read & verify the data between the DOS header and the NT headers
|
||||
auto afterDosCount = newOffset - _offset;
|
||||
_afterDosData = readRegion<uint8>(afterDosCount);
|
||||
if (!_afterDosData)
|
||||
auto afterDosCount = newOffset - mOffset;
|
||||
mAfterDosData = readRegion<uint8>(afterDosCount);
|
||||
if (!mAfterDosData)
|
||||
return ErrorAfterDosHeaderData;
|
||||
|
||||
//read & verify the signature
|
||||
|
|
@ -79,8 +79,8 @@ namespace GleeBug
|
|||
return ErrorNtOptionalHeaderMagic;
|
||||
|
||||
//construct & verify the NT headers region
|
||||
_ntHeaders32 = Region<IMAGE_NT_HEADERS32>(&_data, signature.Offset());
|
||||
if (!_ntHeaders32)
|
||||
mNtHeaders32 = Region<IMAGE_NT_HEADERS32>(&mData, signature.Offset());
|
||||
if (!mNtHeaders32)
|
||||
return ErrorNtHeadersRegionSize;
|
||||
}
|
||||
break;
|
||||
|
|
@ -96,8 +96,8 @@ namespace GleeBug
|
|||
return ErrorNtOptionalHeaderMagic;
|
||||
|
||||
//construct & verify the NT headers region
|
||||
_ntHeaders64 = Region<IMAGE_NT_HEADERS64>(&_data, signature.Offset());
|
||||
if (!_ntHeaders64)
|
||||
mNtHeaders64 = Region<IMAGE_NT_HEADERS64>(&mData, signature.Offset());
|
||||
if (!mNtHeaders64)
|
||||
return ErrorNtHeadersRegionSize;
|
||||
}
|
||||
break;
|
||||
|
|
@ -109,8 +109,8 @@ namespace GleeBug
|
|||
if (!ioh)
|
||||
return ErrorNtFileHeaderUnsupportedMachineOptionalHeaderRead;
|
||||
|
||||
_ntHeaders32 = Region<IMAGE_NT_HEADERS32>(&_data, signature.Offset());
|
||||
if (!_ntHeaders32)
|
||||
mNtHeaders32 = Region<IMAGE_NT_HEADERS32>(&mData, signature.Offset());
|
||||
if (!mNtHeaders32)
|
||||
return ErrorNtFileHeaderUnsupportedMachineNtHeadersRegionSize;
|
||||
|
||||
return ErrorNtFileHeaderUnsupportedMachine;
|
||||
|
|
@ -124,55 +124,55 @@ namespace GleeBug
|
|||
|
||||
//read data after the optional header (TODO: check if this is even possible)
|
||||
uint32 afterOptionalCount = sizeOfIoh > realSizeOfIoh ? sizeOfIoh - realSizeOfIoh : 0;
|
||||
_afterOptionalData = readRegion<uint8>(afterOptionalCount);
|
||||
mAfterOptionalData = readRegion<uint8>(afterOptionalCount);
|
||||
|
||||
//read the section headers
|
||||
auto sectionCount = ifh->NumberOfSections;
|
||||
_sectionHeaders = readRegion<IMAGE_SECTION_HEADER>(sectionCount);
|
||||
mSectionHeaders = readRegion<IMAGE_SECTION_HEADER>(sectionCount);
|
||||
|
||||
return ErrorOk;
|
||||
}
|
||||
|
||||
bool Pe::IsValidPe() const
|
||||
{
|
||||
return _sectionHeaders.Valid();
|
||||
return mSectionHeaders.Valid();
|
||||
}
|
||||
|
||||
bool Pe::IsPe64() const
|
||||
{
|
||||
return IsValidPe() ? _ntHeaders64.Valid() : false;
|
||||
return IsValidPe() ? mNtHeaders64.Valid() : false;
|
||||
}
|
||||
|
||||
uint32 Pe::readData(uint32 size)
|
||||
{
|
||||
std::vector<uint8> temp(size);
|
||||
|
||||
if (!_file.Read(_offset, temp.data(), size))
|
||||
if (!mFile.Read(mOffset, temp.data(), size))
|
||||
return INVALID_VALUE;
|
||||
|
||||
auto result = _offset;
|
||||
_offset += size;
|
||||
_data.insert(_data.end(), temp.begin(), temp.end());
|
||||
auto result = mOffset;
|
||||
mOffset += size;
|
||||
mData.insert(mData.end(), temp.begin(), temp.end());
|
||||
return result;
|
||||
}
|
||||
|
||||
void Pe::setupErrorMap()
|
||||
{
|
||||
_errorMap.insert({ ErrorOk, "ErrorOk" });
|
||||
_errorMap.insert({ ErrorDosHeaderRead, "ErrorDosHeaderRead" });
|
||||
_errorMap.insert({ ErrorDosHeaderMagic, "ErrorDosHeaderMagic" });
|
||||
_errorMap.insert({ ErrorDosHeaderNtHeaderOffset, "ErrorDosHeaderNtHeaderOffset" });
|
||||
_errorMap.insert({ ErrorDosHeaderNtHeaderOffsetOverlap, "ErrorDosHeaderNtHeaderOffsetOverlap" });
|
||||
_errorMap.insert({ ErrorAfterDosHeaderData, "ErrorAfterDosHeaderData" });
|
||||
_errorMap.insert({ ErrorNtSignatureRead, "ErrorNtSignatureRead" });
|
||||
_errorMap.insert({ ErrorNtSignatureMagic, "ErrorNtSignatureMagic" });
|
||||
_errorMap.insert({ ErrorNtFileHeaderRead, "ErrorNtFileHeaderRead" });
|
||||
_errorMap.insert({ ErrorNtFileHeaderSizeOfOptionalHeaderOverlap, "ErrorNtFileHeaderSizeOfOptionalHeaderOverlap" });
|
||||
_errorMap.insert({ ErrorNtFileHeaderUnsupportedMachine, "ErrorNtFileHeaderUnsupportedMachine" });
|
||||
_errorMap.insert({ ErrorNtFileHeaderUnsupportedMachineOptionalHeaderRead, "ErrorNtFileHeaderUnsupportedMachineOptionalHeaderRead" });
|
||||
_errorMap.insert({ ErrorNtFileHeaderUnsupportedMachineNtHeadersRegionSize, "ErrorNtFileHeaderUnsupportedMachineNtHeadersRegionSize" });
|
||||
_errorMap.insert({ ErrorNtOptionalHeaderRead, "ErrorNtOptionalHeaderRead" });
|
||||
_errorMap.insert({ ErrorNtOptionalHeaderMagic, "ErrorNtOptionalHeaderMagic" });
|
||||
_errorMap.insert({ ErrorNtHeadersRegionSize, "ErrorNtHeadersRegionSize" });
|
||||
mErrorMap.insert({ ErrorOk, "ErrorOk" });
|
||||
mErrorMap.insert({ ErrorDosHeaderRead, "ErrorDosHeaderRead" });
|
||||
mErrorMap.insert({ ErrorDosHeaderMagic, "ErrorDosHeaderMagic" });
|
||||
mErrorMap.insert({ ErrorDosHeaderNtHeaderOffset, "ErrorDosHeaderNtHeaderOffset" });
|
||||
mErrorMap.insert({ ErrorDosHeaderNtHeaderOffsetOverlap, "ErrorDosHeaderNtHeaderOffsetOverlap" });
|
||||
mErrorMap.insert({ ErrorAfterDosHeaderData, "ErrorAfterDosHeaderData" });
|
||||
mErrorMap.insert({ ErrorNtSignatureRead, "ErrorNtSignatureRead" });
|
||||
mErrorMap.insert({ ErrorNtSignatureMagic, "ErrorNtSignatureMagic" });
|
||||
mErrorMap.insert({ ErrorNtFileHeaderRead, "ErrorNtFileHeaderRead" });
|
||||
mErrorMap.insert({ ErrorNtFileHeaderSizeOfOptionalHeaderOverlap, "ErrorNtFileHeaderSizeOfOptionalHeaderOverlap" });
|
||||
mErrorMap.insert({ ErrorNtFileHeaderUnsupportedMachine, "ErrorNtFileHeaderUnsupportedMachine" });
|
||||
mErrorMap.insert({ ErrorNtFileHeaderUnsupportedMachineOptionalHeaderRead, "ErrorNtFileHeaderUnsupportedMachineOptionalHeaderRead" });
|
||||
mErrorMap.insert({ ErrorNtFileHeaderUnsupportedMachineNtHeadersRegionSize, "ErrorNtFileHeaderUnsupportedMachineNtHeadersRegionSize" });
|
||||
mErrorMap.insert({ ErrorNtOptionalHeaderRead, "ErrorNtOptionalHeaderRead" });
|
||||
mErrorMap.insert({ ErrorNtOptionalHeaderMagic, "ErrorNtOptionalHeaderMagic" });
|
||||
mErrorMap.insert({ ErrorNtHeadersRegionSize, "ErrorNtHeadersRegionSize" });
|
||||
}
|
||||
};
|
||||
|
|
@ -36,12 +36,12 @@ namespace GleeBug
|
|||
bool IsValidPe() const;
|
||||
bool IsPe64() const;
|
||||
|
||||
const Region<IMAGE_DOS_HEADER> & GetDosHeader() const { return _dosHeader; }
|
||||
const Region<uint8> & GetAfterDosData() const { return _afterDosData; }
|
||||
const Region<IMAGE_NT_HEADERS32> & GetNtHeaders32() const { return _ntHeaders32; }
|
||||
const Region<IMAGE_NT_HEADERS64> & GetNtHeaders64() const { return _ntHeaders64; }
|
||||
const Region<uint8> & GetAfterOptionalData() const { return _afterOptionalData; }
|
||||
const Region<IMAGE_SECTION_HEADER> & GetSectionHeaders() const { return _sectionHeaders; }
|
||||
const Region<IMAGE_DOS_HEADER> & GetDosHeader() const { return mDosHeader; }
|
||||
const Region<uint8> & GetAfterDosData() const { return mAfterDosData; }
|
||||
const Region<IMAGE_NT_HEADERS32> & GetNtHeaders32() const { return mNtHeaders32; }
|
||||
const Region<IMAGE_NT_HEADERS64> & GetNtHeaders64() const { return mNtHeaders64; }
|
||||
const Region<uint8> & GetAfterOptionalData() const { return mAfterOptionalData; }
|
||||
const Region<IMAGE_SECTION_HEADER> & GetSectionHeaders() const { return mSectionHeaders; }
|
||||
|
||||
private:
|
||||
uint32 readData(uint32 size);
|
||||
|
|
@ -50,21 +50,21 @@ namespace GleeBug
|
|||
template<typename T>
|
||||
inline Region<T> readRegion(uint32 count = 1)
|
||||
{
|
||||
return Region<T>(&_data, readData(sizeof(T) * count), count);
|
||||
return Region<T>(&mData, readData(sizeof(T) * count), count);
|
||||
}
|
||||
|
||||
std::unordered_map<Error, const char*> _errorMap;
|
||||
File & _file;
|
||||
uint32 _fileSize;
|
||||
std::vector<uint8> _data;
|
||||
uint32 _offset;
|
||||
std::unordered_map<Error, const char*> mErrorMap;
|
||||
File & mFile;
|
||||
uint32 mFileSize;
|
||||
std::vector<uint8> mData;
|
||||
uint32 mOffset;
|
||||
|
||||
Region<IMAGE_DOS_HEADER> _dosHeader;
|
||||
Region<uint8> _afterDosData;
|
||||
Region<IMAGE_NT_HEADERS32> _ntHeaders32;
|
||||
Region<IMAGE_NT_HEADERS64> _ntHeaders64;
|
||||
Region<uint8> _afterOptionalData;
|
||||
Region<IMAGE_SECTION_HEADER> _sectionHeaders;
|
||||
Region<IMAGE_DOS_HEADER> mDosHeader;
|
||||
Region<uint8> mAfterDosData;
|
||||
Region<IMAGE_NT_HEADERS32> mNtHeaders32;
|
||||
Region<IMAGE_NT_HEADERS64> mNtHeaders64;
|
||||
Region<uint8> mAfterOptionalData;
|
||||
Region<IMAGE_SECTION_HEADER> mSectionHeaders;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -28,9 +28,9 @@ namespace GleeBug
|
|||
\param count (Optional) Number of Ts in the region. Use INVALID_VALUE to create an invalid region.
|
||||
*/
|
||||
explicit Region(std::vector<uint8>* data, uint32 offset, uint32 count = 1)
|
||||
: _data(data),
|
||||
_offset(offset),
|
||||
_count(count)
|
||||
: mData(data),
|
||||
mOffset(offset),
|
||||
mCount(count)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -42,7 +42,7 @@ namespace GleeBug
|
|||
{
|
||||
if (!Valid())
|
||||
return nullptr;
|
||||
return (T*)(_data->data() + _offset);
|
||||
return (T*)(mData->data() + mOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -50,7 +50,7 @@ namespace GleeBug
|
|||
*/
|
||||
uint32 Offset() const
|
||||
{
|
||||
return _offset;
|
||||
return mOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -58,7 +58,7 @@ namespace GleeBug
|
|||
*/
|
||||
uint32 Count() const
|
||||
{
|
||||
return _count;
|
||||
return mCount;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -66,7 +66,7 @@ namespace GleeBug
|
|||
*/
|
||||
uint32 Size() const
|
||||
{
|
||||
return Valid() ? _count * sizeof(T) : INVALID_VALUE;
|
||||
return Valid() ? mCount * sizeof(T) : INVALID_VALUE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -74,10 +74,10 @@ namespace GleeBug
|
|||
*/
|
||||
bool Valid() const
|
||||
{
|
||||
return _offset != INVALID_VALUE &&
|
||||
_count != INVALID_VALUE &&
|
||||
_data && _data->data() &&
|
||||
_offset + _count * sizeof(T) <= _data->size();
|
||||
return mOffset != INVALID_VALUE &&
|
||||
mCount != INVALID_VALUE &&
|
||||
mData && mData->data() &&
|
||||
mOffset + mCount * sizeof(T) <= mData->size();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -110,9 +110,9 @@ namespace GleeBug
|
|||
}
|
||||
|
||||
private:
|
||||
std::vector<uint8>* _data;
|
||||
uint32 _offset;
|
||||
uint32 _count;
|
||||
std::vector<uint8>* mData;
|
||||
uint32 mOffset;
|
||||
uint32 mCount;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -11,49 +11,49 @@ protected:
|
|||
void cbEntryBreakpoint(const BreakpointInfo & info)
|
||||
{
|
||||
printf("Reached entry breakpoint! GIP: 0x%p\n",
|
||||
_registers->Gip());
|
||||
if (_process->DeleteBreakpoint(info.address))
|
||||
mRegisters->Gip());
|
||||
if (mProcess->DeleteBreakpoint(info.address))
|
||||
printf("Entry breakpoint deleted!\n");
|
||||
else
|
||||
printf("Failed to delete entry breakpoint...\n");
|
||||
_thread->StepInto(std::bind([this]()
|
||||
mThread->StepInto(std::bind([this]()
|
||||
{
|
||||
printf("Step after entry breakpoint! GIP: 0x%p\n",
|
||||
_registers->Gip());
|
||||
mRegisters->Gip());
|
||||
}));
|
||||
}
|
||||
|
||||
void cbEntryHardwareBreakpoint(const BreakpointInfo & info)
|
||||
{
|
||||
printf("Reached entry hardware breakpoint! GIP: 0x%p\n",
|
||||
_registers->Gip());
|
||||
if (_process->DeleteHardwareBreakpoint(info.address))
|
||||
mRegisters->Gip());
|
||||
if (mProcess->DeleteHardwareBreakpoint(info.address))
|
||||
printf("Entry hardware breakpoint deleted!\n");
|
||||
else
|
||||
printf("Failed to delete entry hardware breakpoint...\n");
|
||||
_thread->StepInto(std::bind([this]()
|
||||
mThread->StepInto(std::bind([this]()
|
||||
{
|
||||
printf("Step after entry hardware breakpoint! GIP: 0x%p\n",
|
||||
_registers->Gip());
|
||||
mRegisters->Gip());
|
||||
}));
|
||||
}
|
||||
|
||||
void cbStepSystem()
|
||||
{
|
||||
printf("Reached step after system breakpoint, GIP: 0x%p!\n",
|
||||
_registers->Gip());
|
||||
mRegisters->Gip());
|
||||
}
|
||||
|
||||
void cbCreateProcessEvent(const CREATE_PROCESS_DEBUG_INFO & createProcess, const ProcessInfo & process) override
|
||||
{
|
||||
ptr entry = ptr(createProcess.lpStartAddress);
|
||||
printf("Process %d created with entry 0x%p\n",
|
||||
_debugEvent.dwProcessId,
|
||||
mDebugEvent.dwProcessId,
|
||||
entry);
|
||||
/*HardwareSlot slot;
|
||||
if (_process->GetFreeHardwareBreakpointSlot(slot))
|
||||
if (mProcess->GetFreeHardwareBreakpointSlot(slot))
|
||||
{
|
||||
if (_process->SetHardwareBreakpoint(entry, slot, this, &MyDebugger::cbEntryHardwareBreakpoint, HardwareType::Execute, HardwareSize::SizeByte))
|
||||
if (mProcess->SetHardwareBreakpoint(entry, slot, this, &MyDebugger::cbEntryHardwareBreakpoint, HardwareType::Execute, HardwareSize::SizeByte))
|
||||
printf("Hardware breakpoint set at 0x%p!\n", entry);
|
||||
else
|
||||
printf("Failed to set hardware breakpoint at 0x%p\n", entry);
|
||||
|
|
@ -61,18 +61,18 @@ protected:
|
|||
else
|
||||
printf("No free hardware breakpoint slot...\n");*/
|
||||
|
||||
if(_process->SetBreakpoint(entry, this, &MyDebugger::cbEntryBreakpoint))
|
||||
if(mProcess->SetBreakpoint(entry, this, &MyDebugger::cbEntryBreakpoint))
|
||||
printf("Breakpoint set at 0x%p!\n", entry);
|
||||
else
|
||||
printf("Failed to set breakpoint at 0x%p...\b", entry);
|
||||
uint8 test[5];
|
||||
ptr start = entry - 2;
|
||||
printf("unsafe: ");
|
||||
_process->MemRead(start, test, sizeof(test));
|
||||
mProcess->MemRead(start, test, sizeof(test));
|
||||
for (int i = 0; i < sizeof(test); i++)
|
||||
printf("%02X ", test[i]);
|
||||
puts("");
|
||||
_process->MemReadSafe(start, test, sizeof(test));
|
||||
mProcess->MemReadSafe(start, test, sizeof(test));
|
||||
printf(" safe: ");
|
||||
for (int i = 0; i < sizeof(test); i++)
|
||||
printf("%02X ", test[i]);
|
||||
|
|
@ -82,21 +82,21 @@ protected:
|
|||
void cbExitProcessEvent(const EXIT_PROCESS_DEBUG_INFO & exitProcess, const ProcessInfo & process) override
|
||||
{
|
||||
printf("Process %u terminated with exit code 0x%08X\n",
|
||||
_debugEvent.dwProcessId,
|
||||
mDebugEvent.dwProcessId,
|
||||
exitProcess.dwExitCode);
|
||||
}
|
||||
|
||||
void cbCreateThreadEvent(const CREATE_THREAD_DEBUG_INFO & createThread, const ThreadInfo & thread) override
|
||||
{
|
||||
printf("Thread %u created with entry 0x%p\n",
|
||||
_debugEvent.dwThreadId,
|
||||
mDebugEvent.dwThreadId,
|
||||
createThread.lpStartAddress);
|
||||
}
|
||||
|
||||
void cbExitThreadEvent(const EXIT_THREAD_DEBUG_INFO & exitThread, const ThreadInfo & thread) override
|
||||
{
|
||||
printf("Thread %u terminated with exit code 0x%08X\n",
|
||||
_debugEvent.dwThreadId,
|
||||
mDebugEvent.dwThreadId,
|
||||
exitThread.dwExitCode);
|
||||
}
|
||||
|
||||
|
|
@ -138,8 +138,8 @@ protected:
|
|||
void cbSystemBreakpoint() override
|
||||
{
|
||||
printf("System breakpoint reached, GIP: 0x%p\n",
|
||||
_registers->Gip());
|
||||
_thread->StepInto(this, &MyDebugger::cbStepSystem);
|
||||
mRegisters->Gip());
|
||||
mThread->StepInto(this, &MyDebugger::cbStepSystem);
|
||||
}
|
||||
|
||||
void cbInternalError(const std::string & error) override
|
||||
|
|
@ -160,7 +160,7 @@ protected:
|
|||
firstChance ? "first chance" : "second chance",
|
||||
exceptionRecord.ExceptionCode,
|
||||
exceptionRecord.ExceptionAddress,
|
||||
_registers->Gip());
|
||||
mRegisters->Gip());
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ public:
|
|||
{
|
||||
if (!Init(szFileName, szCommandLine, szCurrentFolder))
|
||||
return nullptr;
|
||||
return &_mainProcess;
|
||||
return &mMainProcess;
|
||||
}
|
||||
|
||||
PROCESS_INFORMATION* InitDLLDebugW(const wchar_t* szFileName, bool ReserveModuleBase, const wchar_t* szCommandLine, const wchar_t* szCurrentFolder, LPVOID EntryCallBack)
|
||||
|
|
@ -44,7 +44,7 @@ public:
|
|||
|
||||
void SetNextDbgContinueStatus(DWORD SetDbgCode)
|
||||
{
|
||||
this->_continueStatus = SetDbgCode;
|
||||
this->mContinueStatus = SetDbgCode;
|
||||
}
|
||||
|
||||
//Memory
|
||||
|
|
@ -67,11 +67,11 @@ public:
|
|||
|
||||
bool Fill(LPVOID MemoryStart, DWORD MemorySize, PBYTE FillByte)
|
||||
{
|
||||
if (!_process)
|
||||
if (!mProcess)
|
||||
return false;
|
||||
for (DWORD i = 0; i < MemorySize; i++)
|
||||
{
|
||||
if (!_process->MemWriteSafe(ptr(MemoryStart) + i, FillByte, 1))
|
||||
if (!mProcess->MemWriteSafe(ptr(MemoryStart) + i, FillByte, 1))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
@ -87,12 +87,12 @@ public:
|
|||
|
||||
bool IsFileBeingDebugged() const
|
||||
{
|
||||
return _isDebugging;
|
||||
return mIsDebugging;
|
||||
}
|
||||
|
||||
DEBUG_EVENT* GetDebugData()
|
||||
{
|
||||
return &_debugEvent;
|
||||
return &mDebugEvent;
|
||||
}
|
||||
|
||||
void SetCustomHandler(DWORD ExceptionId, PVOID CallBack)
|
||||
|
|
@ -100,34 +100,34 @@ public:
|
|||
switch (ExceptionId)
|
||||
{
|
||||
case UE_CH_CREATEPROCESS:
|
||||
_cbCREATEPROCESS = CUSTOMHANDLER(CallBack);
|
||||
mCbCREATEPROCESS = CUSTOMHANDLER(CallBack);
|
||||
break;
|
||||
case UE_CH_EXITPROCESS:
|
||||
_cbEXITPROCESS = CUSTOMHANDLER(CallBack);
|
||||
mCbEXITPROCESS = CUSTOMHANDLER(CallBack);
|
||||
break;
|
||||
case UE_CH_CREATETHREAD:
|
||||
_cbCREATETHREAD = CUSTOMHANDLER(CallBack);
|
||||
mCbCREATETHREAD = CUSTOMHANDLER(CallBack);
|
||||
break;
|
||||
case UE_CH_EXITTHREAD:
|
||||
_cbEXITTHREAD = CUSTOMHANDLER(CallBack);
|
||||
mCbEXITTHREAD = CUSTOMHANDLER(CallBack);
|
||||
break;
|
||||
case UE_CH_SYSTEMBREAKPOINT:
|
||||
_cbSYSTEMBREAKPOINT = CUSTOMHANDLER(CallBack);
|
||||
mCbSYSTEMBREAKPOINT = CUSTOMHANDLER(CallBack);
|
||||
break;
|
||||
case UE_CH_LOADDLL:
|
||||
_cbLOADDLL = CUSTOMHANDLER(CallBack);
|
||||
mCbLOADDLL = CUSTOMHANDLER(CallBack);
|
||||
break;
|
||||
case UE_CH_UNLOADDLL:
|
||||
_cbUNLOADDLL = CUSTOMHANDLER(CallBack);
|
||||
mCbUNLOADDLL = CUSTOMHANDLER(CallBack);
|
||||
break;
|
||||
case UE_CH_OUTPUTDEBUGSTRING:
|
||||
_cbOUTPUTDEBUGSTRING = CUSTOMHANDLER(CallBack);
|
||||
mCbOUTPUTDEBUGSTRING = CUSTOMHANDLER(CallBack);
|
||||
break;
|
||||
case UE_CH_UNHANDLEDEXCEPTION:
|
||||
_cbUNHANDLEDEXCEPTION = CUSTOMHANDLER(CallBack);
|
||||
mCbUNHANDLEDEXCEPTION = CUSTOMHANDLER(CallBack);
|
||||
break;
|
||||
case UE_CH_DEBUGEVENT:
|
||||
_cbDEBUGEVENT = CUSTOMHANDLER(CallBack);
|
||||
mCbDEBUGEVENT = CUSTOMHANDLER(CallBack);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
@ -137,7 +137,7 @@ public:
|
|||
void SetEngineVariable(DWORD VariableId, bool VariableSet)
|
||||
{
|
||||
if (VariableId == UE_ENGINE_SET_DEBUG_PRIVILEGE)
|
||||
_setDebugPrivilege = VariableSet;
|
||||
mSetDebugPrivilege = VariableSet;
|
||||
}
|
||||
|
||||
//Misc
|
||||
|
|
@ -180,9 +180,9 @@ public:
|
|||
|
||||
void SingleStep(DWORD StepCount, LPVOID CallBack)
|
||||
{
|
||||
if (!_thread || !CallBack)
|
||||
if (!mThread || !CallBack)
|
||||
return;
|
||||
_thread->StepInto([this, StepCount, CallBack]()
|
||||
mThread->StepInto([this, StepCount, CallBack]()
|
||||
{
|
||||
if (!StepCount)
|
||||
{
|
||||
|
|
@ -196,9 +196,9 @@ public:
|
|||
|
||||
void StepInto(LPVOID CallBack)
|
||||
{
|
||||
if (!_thread || !CallBack)
|
||||
if (!mThread || !CallBack)
|
||||
return;
|
||||
_thread->StepInto(STEPCALLBACK(CallBack));
|
||||
mThread->StepInto(STEPCALLBACK(CallBack));
|
||||
}
|
||||
|
||||
//Registers
|
||||
|
|
@ -373,9 +373,9 @@ public:
|
|||
//Software Breakpoints
|
||||
bool SetBPX(ULONG_PTR bpxAddress, DWORD bpxType, LPVOID bpxCallBack)
|
||||
{
|
||||
if (!_process)
|
||||
if (!mProcess)
|
||||
return false;
|
||||
return _process->SetBreakpoint(bpxAddress, [bpxCallBack](const BreakpointInfo &)
|
||||
return mProcess->SetBreakpoint(bpxAddress, [bpxCallBack](const BreakpointInfo &)
|
||||
{
|
||||
(BPCALLBACK(bpxCallBack))();
|
||||
}, (bpxType & UE_SINGLESHOOT) == UE_SINGLESHOOT);
|
||||
|
|
@ -383,15 +383,15 @@ public:
|
|||
|
||||
bool DeleteBPX(ULONG_PTR bpxAddress)
|
||||
{
|
||||
if (!_process)
|
||||
if (!mProcess)
|
||||
return false;
|
||||
return _process->DeleteBreakpoint(bpxAddress);
|
||||
return mProcess->DeleteBreakpoint(bpxAddress);
|
||||
}
|
||||
|
||||
bool IsBPXEnabled(ULONG_PTR bpxAddress)
|
||||
{
|
||||
return (_process->MemIsValidPtr(bpxAddress) &&
|
||||
_process->breakpoints.find({ BreakpointType::Software, bpxAddress }) != _process->breakpoints.end());
|
||||
return (mProcess->MemIsValidPtr(bpxAddress) &&
|
||||
mProcess->breakpoints.find({ BreakpointType::Software, bpxAddress }) != mProcess->breakpoints.end());
|
||||
}
|
||||
|
||||
void SetBPXOptions(long DefaultBreakPointType)
|
||||
|
|
@ -414,9 +414,9 @@ public:
|
|||
//Hardware Breakpoints
|
||||
bool SetHardwareBreakPoint(ULONG_PTR bpxAddress, DWORD IndexOfRegister, DWORD bpxType, DWORD bpxSize, LPVOID bpxCallBack)
|
||||
{
|
||||
if (!_process)
|
||||
if (!mProcess)
|
||||
return false;
|
||||
return _process->SetHardwareBreakpoint(bpxAddress,
|
||||
return mProcess->SetHardwareBreakpoint(bpxAddress,
|
||||
(HardwareSlot)IndexOfRegister, [bpxCallBack](const BreakpointInfo & info)
|
||||
{
|
||||
(HWBPCALLBACK(bpxCallBack))((const void*)info.address);
|
||||
|
|
@ -425,18 +425,18 @@ public:
|
|||
|
||||
bool DeleteHardwareBreakPoint(DWORD IndexOfRegister)
|
||||
{
|
||||
if (!_process || IndexOfRegister < 0 || IndexOfRegister > 3)
|
||||
if (!mProcess || IndexOfRegister < 0 || IndexOfRegister > 3)
|
||||
return false;
|
||||
auto address = _process->hardwareBreakpoints[IndexOfRegister].address;
|
||||
return _process->DeleteHardwareBreakpoint(address);
|
||||
auto address = mProcess->hardwareBreakpoints[IndexOfRegister].address;
|
||||
return mProcess->DeleteHardwareBreakpoint(address);
|
||||
}
|
||||
|
||||
bool GetUnusedHardwareBreakPointRegister(LPDWORD RegisterIndex)
|
||||
{
|
||||
if (!_process || !RegisterIndex)
|
||||
if (!mProcess || !RegisterIndex)
|
||||
return false;
|
||||
HardwareSlot slot;
|
||||
bool result = _process->GetFreeHardwareBreakpointSlot(slot);
|
||||
bool result = mProcess->GetFreeHardwareBreakpointSlot(slot);
|
||||
if (result)
|
||||
*RegisterIndex = (DWORD)slot;
|
||||
return result;
|
||||
|
|
@ -465,62 +465,62 @@ public:
|
|||
protected:
|
||||
void cbCreateProcessEvent(const CREATE_PROCESS_DEBUG_INFO & createProcess, const ProcessInfo & process) override
|
||||
{
|
||||
if (_cbCREATEPROCESS)
|
||||
_cbCREATEPROCESS(&createProcess);
|
||||
if (mCbCREATEPROCESS)
|
||||
mCbCREATEPROCESS(&createProcess);
|
||||
}
|
||||
|
||||
void cbExitProcessEvent(const EXIT_PROCESS_DEBUG_INFO & exitProcess, const ProcessInfo & process) override
|
||||
{
|
||||
if (_cbEXITPROCESS)
|
||||
_cbEXITPROCESS(&exitProcess);
|
||||
if (mCbEXITPROCESS)
|
||||
mCbEXITPROCESS(&exitProcess);
|
||||
}
|
||||
|
||||
void cbCreateThreadEvent(const CREATE_THREAD_DEBUG_INFO & createThread, const ThreadInfo & thread) override
|
||||
{
|
||||
if (_cbCREATETHREAD)
|
||||
_cbCREATETHREAD(&createThread);
|
||||
if (mCbCREATETHREAD)
|
||||
mCbCREATETHREAD(&createThread);
|
||||
}
|
||||
|
||||
void cbExitThreadEvent(const EXIT_THREAD_DEBUG_INFO & exitThread, const ThreadInfo & thread) override
|
||||
{
|
||||
if (_cbEXITTHREAD)
|
||||
_cbEXITTHREAD(&exitThread);
|
||||
if (mCbEXITTHREAD)
|
||||
mCbEXITTHREAD(&exitThread);
|
||||
}
|
||||
|
||||
void cbLoadDllEvent(const LOAD_DLL_DEBUG_INFO & loadDll, const DllInfo & dll) override
|
||||
{
|
||||
if (_cbLOADDLL)
|
||||
_cbLOADDLL(&loadDll);
|
||||
if (mCbLOADDLL)
|
||||
mCbLOADDLL(&loadDll);
|
||||
}
|
||||
|
||||
void cbUnloadDllEvent(const UNLOAD_DLL_DEBUG_INFO & unloadDll, const DllInfo & dll) override
|
||||
{
|
||||
if (_cbUNLOADDLL)
|
||||
_cbUNLOADDLL(&unloadDll);
|
||||
if (mCbUNLOADDLL)
|
||||
mCbUNLOADDLL(&unloadDll);
|
||||
}
|
||||
|
||||
void cbUnhandledException(const EXCEPTION_RECORD & exceptionRecord, bool firstChance) override
|
||||
{
|
||||
if (_cbUNHANDLEDEXCEPTION)
|
||||
_cbUNHANDLEDEXCEPTION(&_debugEvent.u.Exception);
|
||||
if (mCbUNHANDLEDEXCEPTION)
|
||||
mCbUNHANDLEDEXCEPTION(&mDebugEvent.u.Exception);
|
||||
}
|
||||
|
||||
void cbDebugStringEvent(const OUTPUT_DEBUG_STRING_INFO & debugString) override
|
||||
{
|
||||
if (_cbOUTPUTDEBUGSTRING)
|
||||
_cbOUTPUTDEBUGSTRING(&debugString);
|
||||
if (mCbOUTPUTDEBUGSTRING)
|
||||
mCbOUTPUTDEBUGSTRING(&debugString);
|
||||
}
|
||||
|
||||
void cbPreDebugEvent(const DEBUG_EVENT & debugEvent) override
|
||||
{
|
||||
if (_cbDEBUGEVENT)
|
||||
_cbDEBUGEVENT(&debugEvent);
|
||||
if (mCbDEBUGEVENT)
|
||||
mCbDEBUGEVENT(&debugEvent);
|
||||
}
|
||||
|
||||
void cbSystemBreakpoint() override
|
||||
{
|
||||
if (_cbSYSTEMBREAKPOINT)
|
||||
_cbSYSTEMBREAKPOINT(&_debugEvent.u.Exception);
|
||||
if (mCbSYSTEMBREAKPOINT)
|
||||
mCbSYSTEMBREAKPOINT(&mDebugEvent.u.Exception);
|
||||
}
|
||||
|
||||
private: //functions
|
||||
|
|
@ -574,13 +574,13 @@ private: //functions
|
|||
inline ThreadInfo* threadFromHandle(HANDLE hThread) const
|
||||
{
|
||||
//TODO: properly implement this
|
||||
return _thread;
|
||||
return mThread;
|
||||
}
|
||||
|
||||
inline ProcessInfo* processFromHandle(HANDLE hProcess) const
|
||||
{
|
||||
//TODO: properly implement this
|
||||
return _process;
|
||||
return mProcess;
|
||||
}
|
||||
|
||||
static inline HardwareType hwtypeFromTitan(DWORD type)
|
||||
|
|
@ -618,19 +618,19 @@ private: //functions
|
|||
}
|
||||
|
||||
private: //variables
|
||||
bool _setDebugPrivilege = false;
|
||||
bool mSetDebugPrivilege = false;
|
||||
typedef void(*CUSTOMHANDLER)(const void*);
|
||||
typedef void(*STEPCALLBACK)();
|
||||
typedef STEPCALLBACK BPCALLBACK;
|
||||
typedef CUSTOMHANDLER HWBPCALLBACK;
|
||||
CUSTOMHANDLER _cbCREATEPROCESS = nullptr;
|
||||
CUSTOMHANDLER _cbEXITPROCESS = nullptr;
|
||||
CUSTOMHANDLER _cbCREATETHREAD = nullptr;
|
||||
CUSTOMHANDLER _cbEXITTHREAD = nullptr;
|
||||
CUSTOMHANDLER _cbSYSTEMBREAKPOINT = nullptr;
|
||||
CUSTOMHANDLER _cbLOADDLL = nullptr;
|
||||
CUSTOMHANDLER _cbUNLOADDLL = nullptr;
|
||||
CUSTOMHANDLER _cbOUTPUTDEBUGSTRING = nullptr;
|
||||
CUSTOMHANDLER _cbUNHANDLEDEXCEPTION = nullptr;
|
||||
CUSTOMHANDLER _cbDEBUGEVENT = nullptr;
|
||||
CUSTOMHANDLER mCbCREATEPROCESS = nullptr;
|
||||
CUSTOMHANDLER mCbEXITPROCESS = nullptr;
|
||||
CUSTOMHANDLER mCbCREATETHREAD = nullptr;
|
||||
CUSTOMHANDLER mCbEXITTHREAD = nullptr;
|
||||
CUSTOMHANDLER mCbSYSTEMBREAKPOINT = nullptr;
|
||||
CUSTOMHANDLER mCbLOADDLL = nullptr;
|
||||
CUSTOMHANDLER mCbUNLOADDLL = nullptr;
|
||||
CUSTOMHANDLER mCbOUTPUTDEBUGSTRING = nullptr;
|
||||
CUSTOMHANDLER mCbUNHANDLEDEXCEPTION = nullptr;
|
||||
CUSTOMHANDLER mCbDEBUGEVENT = nullptr;
|
||||
};
|
||||
Loading…
Reference in New Issue