mirror of https://github.com/x64dbg/GleeBug
various fixes to memory breakpoints
This commit is contained in:
parent
eb4262d8ec
commit
1cf82cb3cc
|
|
@ -40,6 +40,9 @@ namespace GleeBug
|
||||||
return;
|
return;
|
||||||
const auto info = foundInfo->second;
|
const auto info = foundInfo->second;
|
||||||
|
|
||||||
|
if (!info.enabled)
|
||||||
|
return; //not a valid software breakpoint
|
||||||
|
|
||||||
//set continue status
|
//set continue status
|
||||||
mContinueStatus = DBG_CONTINUE;
|
mContinueStatus = DBG_CONTINUE;
|
||||||
|
|
||||||
|
|
@ -135,7 +138,7 @@ namespace GleeBug
|
||||||
if (foundInfo == mProcess->breakpoints.end())
|
if (foundInfo == mProcess->breakpoints.end())
|
||||||
return; //not a valid hardware breakpoint
|
return; //not a valid hardware breakpoint
|
||||||
const auto info = foundInfo->second;
|
const auto info = foundInfo->second;
|
||||||
if (info.internal.hardware.slot != breakpointSlot)
|
if (info.internal.hardware.slot != breakpointSlot || !info.enabled)
|
||||||
return; //not a valid hardware breakpoint
|
return; //not a valid hardware breakpoint
|
||||||
|
|
||||||
//set continue status
|
//set continue status
|
||||||
|
|
@ -163,6 +166,47 @@ namespace GleeBug
|
||||||
mProcess->DeleteGenericBreakpoint(info);
|
mProcess->DeleteGenericBreakpoint(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Debugger::exceptionGuardPage(const EXCEPTION_RECORD & exceptionRecord, bool firstChance)
|
||||||
|
{
|
||||||
|
char error[128] = "";
|
||||||
|
auto exceptionAddress = ptr(exceptionRecord.ExceptionAddress);
|
||||||
|
|
||||||
|
auto foundRange = mProcess->memoryBreakpointRanges.find(Range(exceptionAddress, exceptionAddress));
|
||||||
|
if (foundRange == mProcess->memoryBreakpointRanges.end())
|
||||||
|
{
|
||||||
|
auto foundPage = mProcess->memoryBreakpointPages.find(exceptionAddress & ~(PAGE_SIZE - 1));
|
||||||
|
if (foundPage != mProcess->memoryBreakpointPages.end())
|
||||||
|
{
|
||||||
|
const auto & page = foundPage->second;
|
||||||
|
//TODO: single step and page protection changes
|
||||||
|
if (!mProcess->MemProtect(foundPage->first, PAGE_SIZE, foundPage->second.NewProtect))
|
||||||
|
{
|
||||||
|
sprintf_s(error, "MemProtect failed on 0x%p", foundPage->first);
|
||||||
|
cbInternalError(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto foundInfo = mProcess->breakpoints.find({ BreakpointType::Memory, foundRange->first });
|
||||||
|
if (foundInfo == mProcess->breakpoints.end())
|
||||||
|
{
|
||||||
|
sprintf_s(error, "inconsistent memory breakpoint at 0x%p", exceptionAddress);
|
||||||
|
cbInternalError(error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto info = foundInfo->second;
|
||||||
|
if (!info.enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
//exceptionRecord.
|
||||||
|
}
|
||||||
|
|
||||||
|
void Debugger::exceptionAccessViolation(const EXCEPTION_RECORD & exceptionRecord, bool firstChance)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void Debugger::exceptionEvent(const EXCEPTION_DEBUG_INFO & exceptionInfo)
|
void Debugger::exceptionEvent(const EXCEPTION_DEBUG_INFO & exceptionInfo)
|
||||||
{
|
{
|
||||||
//let the debuggee handle exceptions per default
|
//let the debuggee handle exceptions per default
|
||||||
|
|
@ -183,6 +227,12 @@ namespace GleeBug
|
||||||
case STATUS_SINGLE_STEP:
|
case STATUS_SINGLE_STEP:
|
||||||
exceptionSingleStep(exceptionRecord, firstChance);
|
exceptionSingleStep(exceptionRecord, firstChance);
|
||||||
break;
|
break;
|
||||||
|
case STATUS_GUARD_PAGE_VIOLATION:
|
||||||
|
exceptionGuardPage(exceptionRecord, firstChance);
|
||||||
|
break;
|
||||||
|
case STATUS_ACCESS_VIOLATION:
|
||||||
|
exceptionAccessViolation(exceptionRecord, firstChance);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
//call the unhandled exception callback
|
//call the unhandled exception callback
|
||||||
|
|
|
||||||
|
|
@ -261,10 +261,7 @@ namespace GleeBug
|
||||||
data.NewProtect = permanentDep ? RemoveExecuteAccess(RemoveWriteAccess(data.OldProtect)) : data.OldProtect | PAGE_GUARD;
|
data.NewProtect = permanentDep ? RemoveExecuteAccess(RemoveWriteAccess(data.OldProtect)) : data.OldProtect | PAGE_GUARD;
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD oldProtect;
|
return MemProtect(page, PAGE_SIZE, data.NewProtect);
|
||||||
auto vps = !!VirtualProtectEx(hProcess, LPVOID(page), PAGE_SIZE, data.NewProtect, &oldProtect);
|
|
||||||
printf("VirtualProtect(0x%p, 0x%X, %08X, %08X) = %d\n", page, PAGE_SIZE, data.NewProtect, oldProtect, vps);
|
|
||||||
return vps;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Process::SetMemoryBreakpoint(ptr address, ptr size, MemoryType type, bool singleshoot)
|
bool Process::SetMemoryBreakpoint(ptr address, ptr size, MemoryType type, bool singleshoot)
|
||||||
|
|
@ -320,11 +317,7 @@ namespace GleeBug
|
||||||
if (!success)
|
if (!success)
|
||||||
{
|
{
|
||||||
for (const auto & page : breakpointData)
|
for (const auto & page : breakpointData)
|
||||||
{
|
MemProtect(page.addr, PAGE_SIZE, page.OldProtect);
|
||||||
DWORD oldProtect;
|
|
||||||
auto vps = !!VirtualProtectEx(hProcess, LPVOID(page.addr), PAGE_SIZE, page.OldProtect, &oldProtect);
|
|
||||||
printf("VirtualProtect(0x%p, 0x%X, %08X, %08X) = %d\n", page, PAGE_SIZE, page.OldProtect, oldProtect, vps);
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -389,10 +382,7 @@ namespace GleeBug
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Protect = data.OldProtect;
|
Protect = data.OldProtect;
|
||||||
DWORD oldProtect;
|
if (!MemProtect(page, PAGE_SIZE, Protect))
|
||||||
auto vps = !!VirtualProtectEx(hProcess, LPVOID(page), PAGE_SIZE, Protect, &oldProtect);
|
|
||||||
printf("VirtualProtect(0x%p, 0x%X, %08X, %08X) = %d\n", page, PAGE_SIZE, Protect, oldProtect, vps);
|
|
||||||
if (!vps)
|
|
||||||
success = false;
|
success = false;
|
||||||
if (!data.Refcount)
|
if (!data.Refcount)
|
||||||
memoryBreakpointPages.erase(foundData);
|
memoryBreakpointPages.erase(foundData);
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,18 @@ namespace GleeBug
|
||||||
return MemReadUnsafe(address, &byte, sizeof(byte));
|
return MemReadUnsafe(address, &byte, sizeof(byte));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Process::MemProtect(ptr address, ptr size, DWORD newProtect, DWORD* oldProtect)
|
||||||
|
{
|
||||||
|
DWORD dwOldProtect;
|
||||||
|
auto vps = VirtualProtectEx(hProcess, LPVOID(address), size, newProtect, &dwOldProtect);
|
||||||
|
printf("MemProtect(0x%p, 0x%X, %08X, %08X) = %d\n", address, size, newProtect, dwOldProtect, vps);
|
||||||
|
if (!vps)
|
||||||
|
return false;
|
||||||
|
if (oldProtect)
|
||||||
|
*oldProtect = dwOldProtect;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
ptr Process::MemFindPattern(ptr data, size_t datasize, const Pattern::WildcardPattern & pattern, bool safe) const
|
ptr Process::MemFindPattern(ptr data, size_t datasize, const Pattern::WildcardPattern & pattern, bool safe) const
|
||||||
{
|
{
|
||||||
std::vector<uint8> buffer(datasize);
|
std::vector<uint8> buffer(datasize);
|
||||||
|
|
|
||||||
|
|
@ -122,6 +122,16 @@ namespace GleeBug
|
||||||
*/
|
*/
|
||||||
bool MemIsValidPtr(ptr address) const;
|
bool MemIsValidPtr(ptr address) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Memory protect (execute VirtualProtect in the context of the process).
|
||||||
|
\param address The address to change protection for.
|
||||||
|
\param size The size to change protection for.
|
||||||
|
\param newProtect The new protection.
|
||||||
|
\param [out] oldProtect The old protection.
|
||||||
|
\return true if it succeeds, false if it fails.
|
||||||
|
*/
|
||||||
|
bool MemProtect(ptr address, ptr size, DWORD newProtect, DWORD* oldProtect = nullptr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Finds the first occurrence of a pattern in process memory.
|
\brief Finds the first occurrence of a pattern in process memory.
|
||||||
\param data The address to start searching from.
|
\param data The address to start searching from.
|
||||||
|
|
|
||||||
|
|
@ -259,6 +259,10 @@ namespace GleeBug
|
||||||
*/
|
*/
|
||||||
virtual void exceptionHardwareBreakpoint(ptr exceptionAddress);
|
virtual void exceptionHardwareBreakpoint(ptr exceptionAddress);
|
||||||
|
|
||||||
|
virtual void exceptionGuardPage(const EXCEPTION_RECORD & exceptionRecord, bool firstChance);
|
||||||
|
|
||||||
|
virtual void exceptionAccessViolation(const EXCEPTION_RECORD & exceptionRecord, bool firstChance);
|
||||||
|
|
||||||
protected: //variables
|
protected: //variables
|
||||||
PROCESS_INFORMATION mMainProcess;
|
PROCESS_INFORMATION mMainProcess;
|
||||||
uint32 mContinueStatus = DBG_EXCEPTION_NOT_HANDLED;
|
uint32 mContinueStatus = DBG_EXCEPTION_NOT_HANDLED;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue