mirror of https://github.com/x64dbg/GleeBug
(hopefully) high performance safe memory read function
This commit is contained in:
parent
abc8a41a8d
commit
8f62768690
|
|
@ -32,6 +32,7 @@ namespace GleeBug
|
|||
typedef std::map<uint32, ThreadInfo> ThreadMap;
|
||||
typedef std::map<BreakpointKey, BreakpointInfo> BreakpointMap;
|
||||
typedef std::map<BreakpointKey, BreakpointCallback> BreakpointCallbackMap;
|
||||
typedef std::unordered_map<ptr, BreakpointMap::iterator> SoftwareBreakpointMap;
|
||||
|
||||
//vector typedefs
|
||||
typedef std::vector<StepCallback> StepCallbackVector;
|
||||
|
|
|
|||
|
|
@ -37,7 +37,8 @@ namespace GleeBug
|
|||
FlushInstructionCache(hProcess, nullptr, 0);
|
||||
|
||||
//insert in the breakpoint map
|
||||
breakpoints.insert({ { info.type, info.address }, info });
|
||||
auto itr = breakpoints.insert({ { info.type, info.address }, info });
|
||||
softwareBreakpointReferences[info.address] = itr.first;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -72,6 +73,7 @@ namespace GleeBug
|
|||
}
|
||||
|
||||
//remove the breakpoint from the maps
|
||||
softwareBreakpointReferences.erase(info.address);
|
||||
breakpoints.erase(found);
|
||||
breakpointCallbacks.erase({ BreakpointType::Software, address });
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -7,11 +7,60 @@ namespace GleeBug
|
|||
return !!ReadProcessMemory(this->hProcess, reinterpret_cast<const void*>(address), buffer, size, nullptr);
|
||||
}
|
||||
|
||||
bool ProcessInfo::MemReadSafe(ptr address, void* buffer, ptr size) const
|
||||
{
|
||||
if (!MemRead(address, buffer, size))
|
||||
return false;
|
||||
|
||||
//choose the filter method that has the lowest cost
|
||||
auto start = address;
|
||||
auto end = start + size;
|
||||
if (size > breakpoints.size())
|
||||
{
|
||||
for (const auto & breakpoint : breakpoints)
|
||||
{
|
||||
if (breakpoint.first.first != BreakpointType::Software)
|
||||
continue;
|
||||
const auto & info = breakpoint.second;
|
||||
auto curAddress = info.address;
|
||||
for (ptr j = 0; j < info.internal.software.size; j++)
|
||||
{
|
||||
if (curAddress + j >= start && curAddress + j < end)
|
||||
((uint8*)buffer)[curAddress + j - start] = info.internal.software.oldbytes[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (ptr i = start; i < end; i++)
|
||||
{
|
||||
auto found = softwareBreakpointReferences.find(i);
|
||||
if (found == softwareBreakpointReferences.end())
|
||||
continue;
|
||||
const auto & info = found->second->second;
|
||||
auto curAddress = info.address;
|
||||
for (ptr j = 0; j < info.internal.software.size && i < end; j++, i++)
|
||||
{
|
||||
if (curAddress + j >= start && curAddress + j < end)
|
||||
((uint8*)buffer)[curAddress + j - start] = info.internal.software.oldbytes[j];
|
||||
}
|
||||
i += info.internal.software.size - 1;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ProcessInfo::MemWrite(ptr address, const void* buffer, ptr size)
|
||||
{
|
||||
return !!WriteProcessMemory(this->hProcess, reinterpret_cast<void*>(address), buffer, size, nullptr);
|
||||
}
|
||||
|
||||
bool ProcessInfo::MemWriteSafe(ptr address, const void* buffer, ptr size)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ProcessInfo::MemIsValidPtr(ptr address) const
|
||||
{
|
||||
uint8 byte;
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ namespace GleeBug
|
|||
ThreadMap threads; //DO NOT COPY THESE OBJECTS!
|
||||
DllMap dlls;
|
||||
BreakpointMap breakpoints;
|
||||
SoftwareBreakpointMap softwareBreakpointReferences;
|
||||
BreakpointCallbackMap breakpointCallbacks;
|
||||
BreakpointInfo hardwareBreakpoints[4];
|
||||
|
||||
|
|
@ -44,6 +45,15 @@ namespace GleeBug
|
|||
*/
|
||||
bool MemRead(ptr address, void* buffer, ptr size) const;
|
||||
|
||||
/**
|
||||
\brief Safely read memory from the process, filtering out breakpoint bytes.
|
||||
\param address The virtual address to read from.
|
||||
\param [out] buffer Destination buffer. Cannot be null. May be filled partially on failure.
|
||||
\param size The size to read.
|
||||
\return true if it succeeds, false if it fails.
|
||||
*/
|
||||
bool MemReadSafe(ptr address, void* buffer, ptr size) const;
|
||||
|
||||
/**
|
||||
\brief Write memory to the process.
|
||||
\param address The virtual address to write to.
|
||||
|
|
@ -53,6 +63,15 @@ namespace GleeBug
|
|||
*/
|
||||
bool MemWrite(ptr address, const void* buffer, ptr size);
|
||||
|
||||
/**
|
||||
\brief Safely write memory to the process, preserving breakpoint bytes.
|
||||
\param address The virtual address to write to.
|
||||
\param [in] buffer Source buffer. Cannot be null.
|
||||
\param size The size to write.
|
||||
\return true if it succeeds, false if it fails.
|
||||
*/
|
||||
bool MemWriteSafe(ptr address, const void* buffer, ptr size);
|
||||
|
||||
/**
|
||||
\brief Check if an address is a valid read pointer.
|
||||
\param address The address to check.
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ protected:
|
|||
printf("Process %d created with entry 0x%p\n",
|
||||
_debugEvent.dwProcessId,
|
||||
entry);
|
||||
HardwareBreakpointSlot slot;
|
||||
/*HardwareBreakpointSlot slot;
|
||||
if (_process->GetFreeHardwareBreakpointSlot(slot))
|
||||
{
|
||||
if (_process->SetHardwareBreakpoint(entry, slot, this, &MyDebugger::cbEntryHardwareBreakpoint, HardwareBreakpointType::Execute, HardwareBreakpointSize::SizeByte))
|
||||
|
|
@ -59,12 +59,24 @@ protected:
|
|||
printf("Failed to set hardware breakpoint at 0x%p\n", entry);
|
||||
}
|
||||
else
|
||||
printf("No free hardware breakpoint slot...\n");
|
||||
printf("No free hardware breakpoint slot...\n");*/
|
||||
|
||||
/*if(_process->SetBreakpoint(entry, this, &MyDebugger::cbEntryBreakpoint))
|
||||
if(_process->SetBreakpoint(entry, this, &MyDebugger::cbEntryBreakpoint))
|
||||
printf("Breakpoint set at 0x%p!\n", entry);
|
||||
else
|
||||
printf("Failed to set breakpoint at 0x%p...\b", entry);*/
|
||||
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));
|
||||
for (int i = 0; i < sizeof(test); i++)
|
||||
printf("%02X ", test[i]);
|
||||
puts("");
|
||||
_process->MemReadSafe(start, test, sizeof(test));
|
||||
printf(" safe: ");
|
||||
for (int i = 0; i < sizeof(test); i++)
|
||||
printf("%02X ", test[i]);
|
||||
puts("");
|
||||
}
|
||||
|
||||
void cbExitProcessEvent(const EXIT_PROCESS_DEBUG_INFO & exitProcess, const ProcessInfo & process) override
|
||||
|
|
|
|||
Loading…
Reference in New Issue