mirror of https://github.com/x64dbg/TitanEngine
track deleted breakpoints to handle stale events safely
This commit is contained in:
parent
8072f96a26
commit
5cc80cf3d9
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
std::vector<BreakPointDetail> BreakPointBuffer;
|
||||
std::unordered_map<ULONG_PTR, MemoryBreakpointPageDetail> MemoryBreakpointPages;
|
||||
std::unordered_set<ULONG_PTR> recentlyDeletedBpx;
|
||||
|
||||
ULONG_PTR dr7uint(DR7* dr7)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
|
||||
#include "Global.Engine.Threading.h"
|
||||
#include "Global.Engine.h"
|
||||
|
|
@ -11,6 +12,7 @@
|
|||
|
||||
extern std::vector<BreakPointDetail> BreakPointBuffer;
|
||||
extern std::unordered_map<ULONG_PTR, MemoryBreakpointPageDetail> MemoryBreakpointPages;
|
||||
extern std::unordered_set<ULONG_PTR> recentlyDeletedBpx;
|
||||
|
||||
void uintdr7(ULONG_PTR dr7, DR7* ret);
|
||||
ULONG_PTR dr7uint(DR7* dr7);
|
||||
|
|
|
|||
|
|
@ -89,6 +89,7 @@ void DebuggerReset()
|
|||
}
|
||||
std::vector<BreakPointDetail>().swap(BreakPointBuffer);
|
||||
std::unordered_map<ULONG_PTR, MemoryBreakpointPageDetail>().swap(MemoryBreakpointPages);
|
||||
recentlyDeletedBpx.clear();
|
||||
}
|
||||
|
||||
void ClearProcessList()
|
||||
|
|
|
|||
|
|
@ -303,6 +303,7 @@ __declspec(dllexport) bool TITCALL DeleteBPX(ULONG_PTR bpxAddress)
|
|||
FlushInstructionCache(dbgProcessInformation.hProcess, NULL, 0);
|
||||
VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)bpxAddress, BreakPointBuffer.at(found).BreakPointSize, OldProtect, &OldProtect);
|
||||
BreakPointBuffer.erase(BreakPointBuffer.begin() + found);
|
||||
recentlyDeletedBpx.insert(bpxAddress);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -101,6 +101,8 @@ __declspec(dllexport) void TITCALL DebugLoop()
|
|||
memset(&DLLDebugFileName, 0, sizeof(DLLDebugFileName));
|
||||
engineFileIsBeingDebugged = true;
|
||||
|
||||
uint32_t consecutiveTimeouts = 0;
|
||||
|
||||
while(!BreakDBG) //actual debug loop
|
||||
{
|
||||
bool synchronizedStep = false;
|
||||
|
|
@ -124,10 +126,17 @@ __declspec(dllexport) void TITCALL DebugLoop()
|
|||
else
|
||||
{
|
||||
// Regular timeout, wait again
|
||||
// After 2 consecutive timeouts, clear recently deleted breakpoints
|
||||
consecutiveTimeouts++;
|
||||
if(consecutiveTimeouts >= 2)
|
||||
recentlyDeletedBpx.clear();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Event received, reset timeout counter
|
||||
consecutiveTimeouts = 0;
|
||||
|
||||
if(IsDbgReplyLaterSupported)
|
||||
{
|
||||
if(DBGEvent.dwDebugEventCode == EXCEPTION_DEBUG_EVENT)
|
||||
|
|
@ -590,15 +599,13 @@ __declspec(dllexport) void TITCALL DebugLoop()
|
|||
if(DebugAttachedToProcess || !FirstBPX) //program generated a breakpoint exception
|
||||
{
|
||||
ULONG_PTR exceptionAddress = (ULONG_PTR)DBGEvent.u.Exception.ExceptionRecord.ExceptionAddress;
|
||||
unsigned char currentByte = 0xCC;
|
||||
MemoryReadSafe(dbgProcessInformation.hProcess, (void*)exceptionAddress, ¤tByte, 1, nullptr);
|
||||
|
||||
if(currentByte != 0xCC)
|
||||
if(recentlyDeletedBpx.find(exceptionAddress) != recentlyDeletedBpx.end())
|
||||
{
|
||||
//breakpoint was deleted - the byte is no longer 0xCC
|
||||
//reset IP to exception address and continue gracefully
|
||||
DBGCode = DBG_CONTINUE;
|
||||
//breakpoint was recently deleted - handle the stale event gracefully
|
||||
hActiveThread = EngineOpenThread(THREAD_GETSETSUSPEND, false, DBGEvent.dwThreadId);
|
||||
if(hActiveThread != NULL)
|
||||
{
|
||||
CONTEXT myDBGContext;
|
||||
myDBGContext.ContextFlags = ContextControlFlags;
|
||||
GetThreadContext(hActiveThread, &myDBGContext);
|
||||
|
|
@ -609,10 +616,12 @@ __declspec(dllexport) void TITCALL DebugLoop()
|
|||
#endif
|
||||
SetThreadContext(hActiveThread, &myDBGContext);
|
||||
EngineCloseHandle(hActiveThread);
|
||||
DBGCode = DBG_CONTINUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//byte is still 0xCC - this is a real int3 in the original code!!
|
||||
//not a recently deleted breakpoint - pass to debuggee
|
||||
DBGCode = DBG_EXCEPTION_NOT_HANDLED;
|
||||
if(DBGCustomHandler->chBreakPoint != NULL)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue