mirror of
https://github.com/x64dbg/x64dbg.git
synced 2024-11-26 22:30:22 +00:00
WIP: refactor the breakpoint system
This commit is contained in:
parent
b833538632
commit
26a776cca5
@ -25,19 +25,20 @@ static void setBpActive(BREAKPOINT & bp)
|
||||
return;
|
||||
}
|
||||
|
||||
// Breakpoints without modules need a valid address
|
||||
if(!*bp.mod)
|
||||
// If the breakpoint wasn't set by the engine it won't be active
|
||||
if(!bp.active)
|
||||
return;
|
||||
|
||||
if(bp.mod[0] == '\0')
|
||||
{
|
||||
// Breakpoints without modules need a valid address
|
||||
bp.active = MemIsValidReadPtr(bp.addr);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto modLoaded = ModBaseFromName(bp.mod) != 0;
|
||||
if(bp.type == BPHARDWARE)
|
||||
bp.active = modLoaded;
|
||||
else
|
||||
bp.active = modLoaded && MemIsValidReadPtr(bp.addr);
|
||||
// If the module unloaded the breakpoint is no longer active
|
||||
bp.active = ModBaseFromName(bp.mod) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -73,7 +74,6 @@ int BpGetList(std::vector<BREAKPOINT>* List)
|
||||
BREAKPOINT currentBp = i.second;
|
||||
if(currentBp.type != BPDLL && currentBp.type != BPEXCEPTION)
|
||||
currentBp.addr += ModBaseFromName(currentBp.mod);
|
||||
setBpActive(currentBp);
|
||||
|
||||
List->push_back(currentBp);
|
||||
}
|
||||
@ -114,12 +114,20 @@ bool BpNew(duint Address, bool Enable, bool Singleshot, short OldBytes, BP_TYPE
|
||||
}
|
||||
strncpy_s(bp.name, Name, _TRUNCATE);
|
||||
|
||||
bp.active = true;
|
||||
if(Type != BPDLL && Type != BPEXCEPTION)
|
||||
bp.addr = Address - ModBaseFromAddr(Address);
|
||||
else
|
||||
if(Type == BPDLL || Type == BPEXCEPTION)
|
||||
{
|
||||
// These types of breakpoints are always active
|
||||
bp.active = true;
|
||||
bp.addr = Address;
|
||||
}
|
||||
else
|
||||
{
|
||||
bp.addr = Address - ModBaseFromAddr(Address);
|
||||
}
|
||||
bp.enabled = Enable;
|
||||
// TODO: a little hacky
|
||||
if(Enable)
|
||||
bp.active = true;
|
||||
bp.oldbytes = OldBytes;
|
||||
bp.singleshoot = Singleshot;
|
||||
bp.titantype = TitanType;
|
||||
@ -184,7 +192,6 @@ bool BpGet(duint Address, BP_TYPE Type, const char* Name, BREAKPOINT* Bp)
|
||||
*Bp = *bpInfo;
|
||||
if(bpInfo->type != BPDLL && bpInfo->type != BPEXCEPTION)
|
||||
Bp->addr += ModBaseFromAddr(Address);
|
||||
setBpActive(*Bp);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -230,7 +237,6 @@ bool BpGet(duint Address, BP_TYPE Type, const char* Name, BREAKPOINT* Bp)
|
||||
|
||||
*Bp = *bpInfo;
|
||||
Bp->addr = Address;
|
||||
setBpActive(*Bp);
|
||||
return true;
|
||||
}
|
||||
free(DLLName);
|
||||
@ -251,7 +257,6 @@ bool BpGet(duint Address, BP_TYPE Type, const char* Name, BREAKPOINT* Bp)
|
||||
*Bp = i.second;
|
||||
if(i.second.type != BPDLL && i.second.type != BPEXCEPTION)
|
||||
Bp->addr += ModBaseFromAddr(Address);
|
||||
setBpActive(*Bp);
|
||||
}
|
||||
|
||||
// Return true if the name was found at all
|
||||
@ -365,6 +370,7 @@ bool BpEnable(duint Address, BP_TYPE Type, bool Enable)
|
||||
return false;
|
||||
|
||||
bpInfo->enabled = Enable;
|
||||
bpInfo->active = Enable;
|
||||
|
||||
//Re-read oldbytes
|
||||
if(Enable && Type == BPNORMAL)
|
||||
@ -409,6 +415,20 @@ bool BpSetTitanType(duint Address, BP_TYPE Type, int TitanType)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BpSetActive(duint Address, BP_TYPE Type, bool Active)
|
||||
{
|
||||
ASSERT_DEBUGGING("Command function call");
|
||||
EXCLUSIVE_ACQUIRE(LockBreakpoints);
|
||||
|
||||
BREAKPOINT* bpInfo = BpInfoFromAddr(Type, Address);
|
||||
|
||||
if(!bpInfo)
|
||||
return false;
|
||||
|
||||
bpInfo->active = Active;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BpSetBreakCondition(duint Address, BP_TYPE Type, const char* Condition)
|
||||
{
|
||||
ASSERT_DEBUGGING("Command function call");
|
||||
@ -578,12 +598,17 @@ bool BpEnumAll(BPENUMCALLBACK EnumCallback, const char* Module, duint base)
|
||||
BREAKPOINT bpInfo = j->second;
|
||||
if(bpInfo.type != BPDLL && bpInfo.type != BPEXCEPTION)
|
||||
{
|
||||
if(base) //workaround for some Windows bullshit with compatibility mode
|
||||
if(base) //workaround for some Windows bullshit with compatibility mode
|
||||
bpInfo.addr += base;
|
||||
else
|
||||
bpInfo.addr += ModBaseFromName(bpInfo.mod);
|
||||
{
|
||||
char arg[deflen];
|
||||
sprintf_s(arg, "%s:$%X", bpInfo.mod, bpInfo.addr);
|
||||
BREAKPOINT found;
|
||||
if(BpGet(0, bpInfo.type, arg, &found)) //found a breakpoint with name
|
||||
bpInfo = found;
|
||||
}
|
||||
}
|
||||
setBpActive(bpInfo);
|
||||
|
||||
// Lock must be released due to callback sub-locks
|
||||
SHARED_RELEASE();
|
||||
|
@ -26,7 +26,7 @@ struct BREAKPOINT
|
||||
duint addr; // address of the breakpoint (rva relative to base of mod)
|
||||
bool enabled; // whether the breakpoint is enabled
|
||||
bool singleshoot; // whether the breakpoint should be deleted on first hit
|
||||
bool active; // whether the breakpoint is active or not
|
||||
bool active; // whether the breakpoint is active (enabled + actually set) or not
|
||||
bool silent; // whether the breakpoint diplays a default message when hit
|
||||
unsigned short oldbytes; // original bytes (for software breakpoitns)
|
||||
BP_TYPE type; // breakpoint type
|
||||
@ -56,6 +56,7 @@ bool BpDelete(duint Address, BP_TYPE Type);
|
||||
bool BpEnable(duint Address, BP_TYPE Type, bool Enable);
|
||||
bool BpSetName(duint Address, BP_TYPE Type, const char* Name);
|
||||
bool BpSetTitanType(duint Address, BP_TYPE Type, int TitanType);
|
||||
bool BpSetActive(duint Address, BP_TYPE Type, bool Active);
|
||||
bool BpSetBreakCondition(duint Address, BP_TYPE Type, const char* Condition);
|
||||
bool BpSetLogText(duint Address, BP_TYPE Type, const char* Log);
|
||||
bool BpSetLogCondition(duint Address, BP_TYPE Type, const char* Condition);
|
||||
|
@ -15,7 +15,7 @@ static bool cbDeleteAllBreakpoints(const BREAKPOINT* bp)
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Delete breakpoint failed (BpDelete): %p\n"), bp->addr);
|
||||
return false;
|
||||
}
|
||||
if(bp->enabled && !DeleteBPX(bp->addr))
|
||||
if(bp->active && !DeleteBPX(bp->addr))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Delete breakpoint failed (DeleteBPX): %p\n"), bp->addr);
|
||||
return false;
|
||||
@ -53,7 +53,7 @@ static bool cbDisableAllBreakpoints(const BREAKPOINT* bp)
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not disable breakpoint %p (BpEnable)\n"), bp->addr);
|
||||
return false;
|
||||
}
|
||||
if(!DeleteBPX(bp->addr))
|
||||
if(bp->active && !DeleteBPX(bp->addr))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not disable breakpoint %p (DeleteBPX)\n"), bp->addr);
|
||||
return false;
|
||||
@ -192,7 +192,7 @@ bool cbDebugDeleteBPX(int argc, char* argv[])
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Delete breakpoint failed (bpdel): %p\n"), found.addr);
|
||||
return false;
|
||||
}
|
||||
if(found.enabled && !DeleteBPX(found.addr))
|
||||
if(found.active && !DeleteBPX(found.addr))
|
||||
{
|
||||
GuiUpdateAllViews();
|
||||
if(!MemIsValidReadPtr(found.addr))
|
||||
@ -286,7 +286,7 @@ bool cbDebugDisableBPX(int argc, char* argv[])
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not disable breakpoint %p (BpEnable)\n"), found.addr);
|
||||
return false;
|
||||
}
|
||||
if(!DeleteBPX(found.addr))
|
||||
if(found.active && !DeleteBPX(found.addr))
|
||||
{
|
||||
GuiUpdateAllViews();
|
||||
if(!MemIsValidReadPtr(found.addr))
|
||||
@ -313,7 +313,7 @@ bool cbDebugDisableBPX(int argc, char* argv[])
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not disable breakpoint %p (BpEnable)\n"), found.addr);
|
||||
return false;
|
||||
}
|
||||
if(!DeleteBPX(found.addr))
|
||||
if(found.active && !DeleteBPX(found.addr))
|
||||
{
|
||||
GuiUpdateAllViews();
|
||||
if(!MemIsValidReadPtr(found.addr))
|
||||
@ -357,16 +357,16 @@ static bool cbEnableAllHardwareBreakpoints(const BREAKPOINT* bp)
|
||||
int titantype = bp->titantype;
|
||||
TITANSETDRX(titantype, drx);
|
||||
BpSetTitanType(bp->addr, BPHARDWARE, titantype);
|
||||
if(!BpEnable(bp->addr, BPHARDWARE, true))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable hardware breakpoint %p (BpEnable)\n"), bp->addr);
|
||||
return false;
|
||||
}
|
||||
if(!SetHardwareBreakPoint(bp->addr, drx, TITANGETTYPE(bp->titantype), TITANGETSIZE(bp->titantype), cbHardwareBreakpoint))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable hardware breakpoint %p (SetHardwareBreakPoint)\n"), bp->addr);
|
||||
return false;
|
||||
}
|
||||
if(!BpEnable(bp->addr, BPHARDWARE, true))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable hardware breakpoint %p (BpEnable)\n"), bp->addr);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -641,7 +641,7 @@ static bool cbDeleteAllMemoryBreakpoints(const BREAKPOINT* bp)
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Delete memory breakpoint failed (BpDelete): %p\n"), bp->addr);
|
||||
return false;
|
||||
}
|
||||
if(bp->enabled && !RemoveMemoryBPX(bp->addr, size))
|
||||
if(bp->active && !RemoveMemoryBPX(bp->addr, size))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Delete memory breakpoint failed (RemoveMemoryBPX): %p\n"), bp->addr);
|
||||
return false;
|
||||
@ -655,16 +655,16 @@ static bool cbEnableAllMemoryBreakpoints(const BREAKPOINT* bp)
|
||||
return true;
|
||||
duint size = 0;
|
||||
MemFindBaseAddr(bp->addr, &size);
|
||||
if(!BpEnable(bp->addr, BPMEMORY, true))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable memory breakpoint %p (BpEnable)\n"), bp->addr);
|
||||
return false;
|
||||
}
|
||||
if(!SetMemoryBPXEx(bp->addr, size, bp->titantype, !bp->singleshoot, cbMemoryBreakpoint))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable memory breakpoint %p (SetMemoryBPXEx)\n"), bp->addr);
|
||||
return false;
|
||||
}
|
||||
if(!BpEnable(bp->addr, BPMEMORY, true))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable memory breakpoint %p (BpEnable)\n"), bp->addr);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -677,7 +677,7 @@ static bool cbDisableAllMemoryBreakpoints(const BREAKPOINT* bp)
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not disable memory breakpoint %p (BpEnable)\n"), bp->addr);
|
||||
return false;
|
||||
}
|
||||
if(!RemoveMemoryBPX(bp->addr, 0))
|
||||
if(bp->active && !RemoveMemoryBPX(bp->addr, 0))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not disable memory breakpoint %p (RemoveMemoryBPX)\n"), bp->addr);
|
||||
return false;
|
||||
@ -780,7 +780,7 @@ bool cbDebugDeleteMemoryBreakpoint(int argc, char* argv[])
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Delete memory breakpoint failed: %p (BpDelete)\n"), found.addr);
|
||||
return false;
|
||||
}
|
||||
if(!RemoveMemoryBPX(found.addr, size))
|
||||
if(found.active && !RemoveMemoryBPX(found.addr, size))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Delete memory breakpoint failed: %p (RemoveMemoryBPX)\n"), found.addr);
|
||||
return false;
|
||||
@ -801,7 +801,7 @@ bool cbDebugDeleteMemoryBreakpoint(int argc, char* argv[])
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Delete memory breakpoint failed: %p (BpDelete)\n"), found.addr);
|
||||
return false;
|
||||
}
|
||||
if(!RemoveMemoryBPX(found.addr, size))
|
||||
if(found.active && !RemoveMemoryBPX(found.addr, size))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Delete memory breakpoint failed: %p (RemoveMemoryBPX)\n"), found.addr);
|
||||
return false;
|
||||
@ -885,7 +885,7 @@ bool cbDebugDisableMemoryBreakpoint(int argc, char* argv[])
|
||||
}
|
||||
duint size = 0;
|
||||
MemFindBaseAddr(found.addr, &size);
|
||||
if(!RemoveMemoryBPX(found.addr, size))
|
||||
if(found.active && !RemoveMemoryBPX(found.addr, size))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not disable memory breakpoint %p (RemoveMemoryBPX)\n"), found.addr);
|
||||
return false;
|
||||
@ -923,16 +923,16 @@ static bool cbEnableAllDllBreakpoints(const BREAKPOINT* bp)
|
||||
if(bp->type != BPDLL || bp->enabled)
|
||||
return true;
|
||||
|
||||
if(!BpEnable(bp->addr, BPDLL, true))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable DLL breakpoint %s (BpEnable)\n"), bp->mod);
|
||||
return false;
|
||||
}
|
||||
if(!dbgsetdllbreakpoint(bp->mod, bp->titantype, bp->singleshoot))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable DLL breakpoint %s (LibrarianSetBreakPoint)\n"), bp->mod);
|
||||
return false;
|
||||
}
|
||||
if(!BpEnable(bp->addr, BPDLL, true))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable DLL breakpoint %s (BpEnable)\n"), bp->mod);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1059,15 +1059,15 @@ bool cbDebugBpDllEnable(int argc, char* argv[])
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "DLL breakpoint already enabled!"));
|
||||
return true;
|
||||
}
|
||||
if(!dbgsetdllbreakpoint(found.mod, found.titantype, found.singleshoot))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable DLL breakpoint %s (LibrarianSetBreakPoint)\n"), found.mod);
|
||||
}
|
||||
if(!BpEnable(found.addr, BPDLL, true))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable DLL breakpoint %s (BpEnable)\n"), found.mod);
|
||||
return false;
|
||||
}
|
||||
if(!dbgsetdllbreakpoint(found.mod, found.titantype, found.singleshoot))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable DLL breakpoint %s (LibrarianSetBreakPoint)\n"), found.mod);
|
||||
}
|
||||
dputs(QT_TRANSLATE_NOOP("DBG", "DLL breakpoint enable!"));
|
||||
GuiUpdateAllViews();
|
||||
return true;
|
||||
|
@ -1098,10 +1098,12 @@ bool cbSetModuleBreakpoints(const BREAKPOINT* bp)
|
||||
bp->addr,
|
||||
((unsigned char*)&bp->oldbytes)[0], ((unsigned char*)&bp->oldbytes)[1],
|
||||
((unsigned char*)&oldbytes)[0], ((unsigned char*)&oldbytes)[1]);
|
||||
BpEnable(bp->addr, BPNORMAL, false);
|
||||
BpEnable(bp->addr, bp->type, false);
|
||||
}
|
||||
else if(!SetBPX(bp->addr, bp->titantype, cbUserBreakpoint))
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not set breakpoint %p! (SetBPX)\n"), bp->addr);
|
||||
else
|
||||
BpSetActive(bp->addr, bp->type, true);
|
||||
}
|
||||
else
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "MemRead failed on breakpoint address %p!\n"), bp->addr);
|
||||
@ -1114,6 +1116,8 @@ bool cbSetModuleBreakpoints(const BREAKPOINT* bp)
|
||||
MemFindBaseAddr(bp->addr, &size);
|
||||
if(!SetMemoryBPXEx(bp->addr, size, bp->titantype, !bp->singleshoot, cbMemoryBreakpoint))
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not set memory breakpoint %p! (SetMemoryBPXEx)\n"), bp->addr);
|
||||
else
|
||||
BpSetActive(bp->addr, bp->type, true);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1127,11 +1131,14 @@ bool cbSetModuleBreakpoints(const BREAKPOINT* bp)
|
||||
}
|
||||
int titantype = bp->titantype;
|
||||
TITANSETDRX(titantype, drx);
|
||||
BpSetTitanType(bp->addr, BPHARDWARE, titantype);
|
||||
BpSetTitanType(bp->addr, bp->type, titantype);
|
||||
if(!SetHardwareBreakPoint(bp->addr, drx, TITANGETTYPE(bp->titantype), TITANGETSIZE(bp->titantype), cbHardwareBreakpoint))
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not set hardware breakpoint %p! (SetHardwareBreakPoint)\n"), bp->addr);
|
||||
else
|
||||
{
|
||||
BpSetActive(bp->addr, bp->type, true);
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Set hardware breakpoint on %p!\n"), bp->addr);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1177,6 +1184,7 @@ static bool cbRemoveModuleBreakpoints(const BREAKPOINT* bp)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
BpSetActive(bp->addr, bp->type, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user