mirror of https://github.com/x64dbg/GleeBug
Restore PAGE_GUARD memory breakpoints properly
This commit is contained in:
parent
2cc003cdcf
commit
e0a457965f
|
|
@ -22,7 +22,7 @@ namespace GleeBug
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//check if this address had a breakpoint that was recently deleted
|
//check if this address had a breakpoint that was recently deleted
|
||||||
auto& deletedBps = mProcess->recentlyDeletedSwbp;
|
auto & deletedBps = mProcess->recentlyDeletedSwbp;
|
||||||
auto foundIt = deletedBps.find(exceptionAddress);
|
auto foundIt = deletedBps.find(exceptionAddress);
|
||||||
if(foundIt != deletedBps.end() && mThread)
|
if(foundIt != deletedBps.end() && mThread)
|
||||||
{
|
{
|
||||||
|
|
@ -260,16 +260,20 @@ namespace GleeBug
|
||||||
auto pageAddr = bpxPage->first;
|
auto pageAddr = bpxPage->first;
|
||||||
auto pageProperties = bpxPage->second;
|
auto pageProperties = bpxPage->second;
|
||||||
|
|
||||||
//TODO: If I only have a page with Read bp and the exception was not on read, I don't execute the callback. Because since this was implemented with PAGE_GUARD, writtes or executes still trigger
|
// PAGE_GUARD is shared by access/read/write/execute breakpoints, so the exception type in
|
||||||
//This callback.
|
// ExceptionInformation[0] decides whether this guard-page fault actually belongs to this breakpoint.
|
||||||
//FIX: If the memoryBreakpointPages for this page does not have a access flag and has a read flag, but the exception was not on read. Then we resume the debuggee.
|
// Access breakpoints intentionally match every access type.
|
||||||
if((exceptionRecord.ExceptionInformation[0] != 0))
|
const auto accessType = exceptionRecord.ExceptionInformation[0];
|
||||||
{
|
const auto isAccessBreakpoint = (pageProperties.Type & 0x1) != 0;
|
||||||
//The bpx is solely on read.
|
const auto matchesRead = accessType == 0 && (((pageProperties.Type & 0x2) != 0) || isAccessBreakpoint);
|
||||||
if(((pageProperties.Type & 0x2) != 0) && ((pageProperties.Type & 0x1) == 0))
|
const auto matchesWrite = accessType == 1 && (((pageProperties.Type & 0x4) != 0) || isAccessBreakpoint);
|
||||||
|
const auto matchesExecute = accessType == 8 && (((pageProperties.Type & 0x8) != 0) || isAccessBreakpoint);
|
||||||
|
if(!matchesRead && !matchesWrite && !matchesExecute)
|
||||||
{
|
{
|
||||||
mContinueStatus = DBG_CONTINUE;
|
mContinueStatus = DBG_CONTINUE;
|
||||||
//We restore the protection
|
// This page belongs to some memory breakpoint, but not one that should trigger on this access type.
|
||||||
|
// Restore the original protection, single-step the faulting instruction, then re-apply the guard/page
|
||||||
|
// permissions if the page is still tracked by any memory breakpoint.
|
||||||
if(!mProcess->MemProtect(pageAddr, PAGE_SIZE, pageProperties.OldProtect))
|
if(!mProcess->MemProtect(pageAddr, PAGE_SIZE, pageProperties.OldProtect))
|
||||||
{
|
{
|
||||||
sprintf_s(error, "MemProtect failed on 0x%p", (void*)pageAddr);
|
sprintf_s(error, "MemProtect failed on 0x%p", (void*)pageAddr);
|
||||||
|
|
@ -278,39 +282,14 @@ namespace GleeBug
|
||||||
|
|
||||||
mProcess->StepInternal([this, pageAddr]()
|
mProcess->StepInternal([this, pageAddr]()
|
||||||
{
|
{
|
||||||
//seek out the page address
|
|
||||||
auto found_page = mProcess->memoryBreakpointPages.find(pageAddr);
|
auto found_page = mProcess->memoryBreakpointPages.find(pageAddr);
|
||||||
if(found_page == mProcess->memoryBreakpointPages.end())
|
if(found_page == mProcess->memoryBreakpointPages.end())
|
||||||
{
|
|
||||||
//no page being used by bpx? Then just return
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
mProcess->MemProtect(pageAddr, PAGE_SIZE, found_page->second.NewProtect);
|
mProcess->MemProtect(pageAddr, PAGE_SIZE, found_page->second.NewProtect);
|
||||||
return;
|
return;
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if(((pageProperties.Type & 0x1) != 0))
|
|
||||||
{
|
|
||||||
//We are fine if the breakpoint is on Access and somethine other than a read occurred.
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//This exception handler was called within a page that had no breakpoints on read or access. Probably the program generated this exception! what a 0x1337 brat.
|
|
||||||
//In this situation we return control to debuggee.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//The generated exception is on read.
|
|
||||||
//If the page doesn't have a breakpoint on read or on access then something else must have gone wrong - we pass execution to debuggee.
|
|
||||||
if((!(pageProperties.Type & 0x2)) && (!(pageProperties.Type & 0x1)))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue