1
0
Fork 0

DLL breakpoint GUI (#1048)

* New Splitter Widget

* DLL breakpoint interface

* Conditional DLL Breakpoint

* maintain translation file

* Don't animate when it stops

* fixed some issues

* DLL Breakpoint GUI

* DLL Breakpoint GUI

* Fixed DLL Path problem

* When not debugging, the user can use "run" button to restart.

* further fixes
This commit is contained in:
Torusrxxx 2016-09-05 22:28:25 +00:00 committed by Duncan Ogilvie
parent 9b703ae9b2
commit 4e2636416c
18 changed files with 794 additions and 294 deletions

View File

@ -231,6 +231,10 @@ static bool _getbridgebp(BPXTYPE type, duint addr, BRIDGEBP* bp)
case bp_memory:
bptype = BPMEMORY;
break;
case bp_dll:
bptype = BPDLL;
addr = ModHashFromName(reinterpret_cast<const char*>(addr));
break;
default:
return false;
}

View File

@ -116,11 +116,12 @@ bool BpNewDll(const char* module, bool Enable, bool Singleshot, DWORD TitanType,
bp.singleshoot = Singleshot;
bp.titantype = TitanType;
bp.type = BPDLL;
bp.addr = BpGetDLLBpAddr(module);
// Insert new entry to the global list
EXCLUSIVE_ACQUIRE(LockBreakpoints);
return breakpoints.insert(std::make_pair(BreakpointKey(BPDLL, ModHashFromName(bp.mod)), bp)).second;
return breakpoints.insert(std::make_pair(BreakpointKey(BPDLL, bp.addr), bp)).second;
}
bool BpGet(duint Address, BP_TYPE Type, const char* Name, BREAKPOINT* Bp)
@ -174,10 +175,10 @@ bool BpGet(duint Address, BP_TYPE Type, const char* Name, BREAKPOINT* Bp)
bool BpGetAny(BP_TYPE Type, const char* Name, BREAKPOINT* Bp)
{
if(BpGet(0, Type, Name, Bp))
return true;
if(Type != BPDLL)
{
if(BpGet(0, Type, Name, Bp))
return true;
duint addr;
if(valfromstring(Name, &addr))
if(BpGet(addr, Type, 0, Bp))
@ -185,7 +186,7 @@ bool BpGetAny(BP_TYPE Type, const char* Name, BREAKPOINT* Bp)
}
else
{
if(BpGet(ModHashFromName(Name), Type, Name, Bp))
if(BpGet(BpGetDLLBpAddr(Name), Type, 0, Bp))
return true;
}
return false;
@ -201,8 +202,13 @@ bool BpUpdateDllPath(const char* module1, BREAKPOINT** newBpInfo)
{
if(_stricmp(i.second.mod, module1) == 0)
{
strcpy_s(i.second.mod, module1);
*newBpInfo = &i.second;
BREAKPOINT temp;
temp = i.second;
strcpy_s(temp.mod, module1);
temp.addr = ModHashFromName(module1);
breakpoints.erase(i.first);
auto newItem = breakpoints.insert(std::make_pair(BreakpointKey(BPDLL, temp.addr), temp));
*newBpInfo = &newItem.first->second;
return true;
}
const char* dashPos = max(strrchr(i.second.mod, '\\'), strrchr(i.second.mod, '/'));
@ -212,8 +218,13 @@ bool BpUpdateDllPath(const char* module1, BREAKPOINT** newBpInfo)
dashPos += 1;
if(dashPos1 != nullptr && _stricmp(dashPos, dashPos1 + 1) == 0) // filename matches
{
strcpy_s(i.second.mod, module1);
*newBpInfo = &i.second;
BREAKPOINT temp;
temp = i.second;
strcpy_s(temp.mod, dashPos1 + 1);
temp.addr = ModHashFromName(dashPos1 + 1);
breakpoints.erase(i.first);
auto newItem = breakpoints.insert(std::make_pair(BreakpointKey(BPDLL, temp.addr), temp));
*newBpInfo = &newItem.first->second;
return true;
}
}
@ -222,6 +233,16 @@ bool BpUpdateDllPath(const char* module1, BREAKPOINT** newBpInfo)
return false;
}
duint BpGetDLLBpAddr(const char* fileName)
{
const char* dashPos1 = max(strrchr(fileName, '\\'), strrchr(fileName, '/'));
if(dashPos1 == nullptr)
dashPos1 = fileName;
else
dashPos1++;
return ModHashFromName(dashPos1);
}
bool BpDelete(duint Address, BP_TYPE Type)
{
ASSERT_DEBUGGING("Command function call");
@ -589,9 +610,9 @@ void BpCacheSave(JSON Root)
const JSON jsonBreakpoints = json_array();
// Loop all breakpoints
for(auto & i : breakpoints)
for(const auto & i : breakpoints)
{
auto & breakpoint = i.second;
const auto & breakpoint = i.second;
// Ignore single-shot breakpoints
if(breakpoint.singleshoot)
@ -676,7 +697,15 @@ void BpCacheLoad(JSON Root)
breakpoint.silent = json_boolean_value(json_object_get(value, "silent"));
// Build the hash map key: MOD_HASH + ADDRESS
duint key = ModHashFromName(breakpoint.mod) + breakpoint.addr;
duint key;
if(breakpoint.type != BPDLL)
{
key = ModHashFromName(breakpoint.mod) + breakpoint.addr;
}
else
{
key = BpGetDLLBpAddr(breakpoint.mod);
}
breakpoints.insert(std::make_pair(BreakpointKey(breakpoint.type, key), breakpoint));
}
}

View File

@ -61,6 +61,7 @@ bool BpSetFastResume(duint Address, BP_TYPE Type, bool fastResume);
bool BpSetSingleshoot(duint Address, BP_TYPE Type, bool singleshoot);
bool BpEnumAll(BPENUMCALLBACK EnumCallback, const char* Module, duint base = 0);
bool BpSetSilent(duint Address, BP_TYPE Type, bool silent);
duint BpGetDLLBpAddr(const char* fileName);
bool BpEnumAll(BPENUMCALLBACK EnumCallback);
int BpGetCount(BP_TYPE Type, bool EnabledOnly = false);
uint32 BpGetHitCount(duint Address, BP_TYPE Type);

View File

@ -4,6 +4,262 @@
#include "memory.h"
#include "variable.h"
// breakpoint enumeration callbacks
static bool cbDeleteAllBreakpoints(const BREAKPOINT* bp)
{
if(bp->type != BPNORMAL)
return true;
if(!BpDelete(bp->addr, BPNORMAL))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Delete breakpoint failed (BpDelete): %p\n"), bp->addr);
return false;
}
if(bp->enabled && !DeleteBPX(bp->addr))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Delete breakpoint failed (DeleteBPX): %p\n"), bp->addr);
return false;
}
return true;
}
static bool cbEnableAllBreakpoints(const BREAKPOINT* bp)
{
if(bp->type != BPNORMAL || bp->enabled)
return true;
if(!SetBPX(bp->addr, bp->titantype, (void*)cbUserBreakpoint))
{
if(!MemIsValidReadPtr(bp->addr))
return true;
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable breakpoint %p (SetBPX)\n"), bp->addr);
return false;
}
if(!BpEnable(bp->addr, BPNORMAL, true))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable breakpoint %p (BpEnable)\n"), bp->addr);
return false;
}
return true;
}
static bool cbDisableAllBreakpoints(const BREAKPOINT* bp)
{
if(bp->type != BPNORMAL || !bp->enabled)
return true;
if(!BpEnable(bp->addr, BPNORMAL, false))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not disable breakpoint %p (BpEnable)\n"), bp->addr);
return false;
}
if(!DeleteBPX(bp->addr))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not disable breakpoint %p (DeleteBPX)\n"), bp->addr);
return false;
}
return true;
}
static bool cbEnableAllHardwareBreakpoints(const BREAKPOINT* bp)
{
if(bp->type != BPHARDWARE || bp->enabled)
return true;
DWORD drx = 0;
if(!GetUnusedHardwareBreakPointRegister(&drx))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Did not enable hardware breakpoint %p (all slots full)\n"), bp->addr);
return true;
}
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), (void*)cbHardwareBreakpoint))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable hardware breakpoint %p (SetHardwareBreakPoint)\n"), bp->addr);
return false;
}
return true;
}
static bool cbDisableAllHardwareBreakpoints(const BREAKPOINT* bp)
{
if(bp->type != BPHARDWARE)
return true;
if(!BpEnable(bp->addr, BPHARDWARE, false))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not disable hardware breakpoint %p (BpEnable)\n"), bp->addr);
return false;
}
if(bp->enabled && !DeleteHardwareBreakPoint(TITANGETDRX(bp->titantype)))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not disable hardware breakpoint %p (DeleteHardwareBreakPoint)\n"), bp->addr);
return false;
}
return true;
}
static bool cbEnableAllMemoryBreakpoints(const BREAKPOINT* bp)
{
if(bp->type != BPMEMORY || bp->enabled)
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, (void*)cbMemoryBreakpoint))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable memory breakpoint %p (SetMemoryBPXEx)\n"), bp->addr);
return false;
}
return true;
}
static bool cbDisableAllMemoryBreakpoints(const BREAKPOINT* bp)
{
if(bp->type != BPMEMORY || !bp->enabled)
return true;
if(!BpEnable(bp->addr, BPMEMORY, false))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not disable memory breakpoint %p (BpEnable)\n"), bp->addr);
return false;
}
if(!RemoveMemoryBPX(bp->addr, 0))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not disable memory breakpoint %p (RemoveMemoryBPX)\n"), bp->addr);
return false;
}
return true;
}
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(!LibrarianSetBreakPoint(bp->mod, bp->titantype, bp->singleshoot, (void*)cbLibrarianBreakpoint))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable DLL breakpoint %s (LibrarianSetBreakPoint)\n"), bp->mod);
return false;
}
return true;
}
static bool cbDisableAllDllBreakpoints(const BREAKPOINT* bp)
{
if(bp->type != BPDLL || !bp->enabled)
return true;
if(!BpEnable(bp->addr, BPDLL, false))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not disable DLL breakpoint %s (BpEnable)\n"), bp->mod);
return false;
}
if(!LibrarianRemoveBreakPoint(bp->mod, bp->titantype))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not disable DLL breakpoint %s (LibrarianRemoveBreakPoint)\n"), bp->mod);
return false;
}
return true;
}
static bool cbDeleteAllDllBreakpoints(const BREAKPOINT* bp)
{
if(bp->type != BPDLL || !bp->enabled)
return true;
if(!BpDelete(bp->addr, BPDLL))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not delete DLL breakpoint %s (BpDelete)\n"), bp->mod);
return false;
}
if(!LibrarianRemoveBreakPoint(bp->mod, bp->titantype))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not delete DLL breakpoint %s (LibrarianRemoveBreakPoint)\n"), bp->mod);
return false;
}
return true;
}
static bool cbBreakpointList(const BREAKPOINT* bp)
{
const char* type = 0;
if(bp->type == BPNORMAL)
{
if(bp->singleshoot)
type = "SS";
else
type = "BP";
}
else if(bp->type == BPHARDWARE)
type = "HW";
else if(bp->type == BPMEMORY)
type = "GP";
else if(bp->type == BPDLL)
type = "DLL";
bool enabled = bp->enabled;
if(bp->type == BPDLL)
{
if(*bp->name)
dprintf_untranslated("%d:%s:\"%s\":\"%s\"\n", enabled, type, bp->mod, bp->name);
else
dprintf_untranslated("%d:%s:\"%s\"\n", enabled, type, bp->mod);
}
else if(*bp->name)
dprintf_untranslated("%d:%s:%p:\"%s\"\n", enabled, type, bp->addr, bp->name);
else
dprintf_untranslated("%d:%s:%p\n", enabled, type, bp->addr);
return true;
}
static bool cbDeleteAllMemoryBreakpoints(const BREAKPOINT* bp)
{
if(bp->type != BPMEMORY)
return true;
duint size;
MemFindBaseAddr(bp->addr, &size);
if(!BpDelete(bp->addr, BPMEMORY))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Delete memory breakpoint failed (BpDelete): %p\n"), bp->addr);
return false;
}
if(bp->enabled && !RemoveMemoryBPX(bp->addr, size))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Delete memory breakpoint failed (RemoveMemoryBPX): %p\n"), bp->addr);
return false;
}
return true;
}
static bool cbDeleteAllHardwareBreakpoints(const BREAKPOINT* bp)
{
if(bp->type != BPHARDWARE)
return true;
if(!BpDelete(bp->addr, BPHARDWARE))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Delete hardware breakpoint failed (BpDelete): %p\n"), bp->addr);
return false;
}
if(bp->enabled && !DeleteHardwareBreakPoint(TITANGETDRX(bp->titantype)))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Delete hardware breakpoint failed (DeleteHardwareBreakPoint): %p\n"), bp->addr);
return false;
}
return true;
}
// command callbacks
CMDRESULT cbDebugSetBPXOptions(int argc, char* argv[])
{
if(argc < 2)
@ -314,7 +570,7 @@ static CMDRESULT cbDebugSetBPXTextCommon(BP_TYPE Type, int argc, char* argv[], c
dputs(QT_TRANSLATE_NOOP("DBG", "not enough arguments!\n"));
return STATUS_ERROR;
}
auto value = "";
char* value = "";
if(argc > 2)
value = argv[2];
@ -399,7 +655,7 @@ static CMDRESULT cbDebugResetBPXHitCountCommon(BP_TYPE Type, int argc, char* arg
}
if(!BpResetHitCount(bp.addr, Type, (uint32)value))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Can't set hit count on breakpoint \"%s\""), argv[1]);
dprintf(QT_TRANSLATE_NOOP("DBG", "Can't set hit count on breakpoint \"%s\"\n"), argv[1]);
return STATUS_ERROR;
}
DebugUpdateBreakpointsViewAsync();
@ -429,7 +685,7 @@ static CMDRESULT cbDebugSetBPXFastResumeCommon(BP_TYPE Type, int argc, char* arg
}
if(!BpSetFastResume(bp.addr, Type, fastResume))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Can't set fast resume on breakpoint \"%1\""), argv[1]);
dprintf(QT_TRANSLATE_NOOP("DBG", "Can't set fast resume on breakpoint \"%1\"\n"), argv[1]);
return STATUS_ERROR;
}
DebugUpdateBreakpointsViewAsync();
@ -459,7 +715,7 @@ static CMDRESULT cbDebugSetBPXSingleshootCommon(BP_TYPE Type, int argc, char* ar
}
if(!BpSetSingleshoot(bp.addr, Type, singleshoot))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Can't set singleshoot on breakpoint \"%1\""), argv[1]);
dprintf(QT_TRANSLATE_NOOP("DBG", "Can't set singleshoot on breakpoint \"%1\"\n"), argv[1]);
return STATUS_ERROR;
}
DebugUpdateBreakpointsViewAsync();
@ -489,7 +745,7 @@ static CMDRESULT cbDebugSetBPXSilentCommon(BP_TYPE Type, int argc, char* argv[])
}
if(!BpSetSilent(bp.addr, Type, silent))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Can't set silent on breakpoint \"%1\""), argv[1]);
dprintf(QT_TRANSLATE_NOOP("DBG", "Can't set silent on breakpoint \"%1\"\n"), argv[1]);
return STATUS_ERROR;
}
DebugUpdateBreakpointsViewAsync();
@ -1140,7 +1396,7 @@ CMDRESULT cbDebugEnableMemoryBreakpoint(int argc, char* argv[])
CMDRESULT cbDebugDisableMemoryBreakpoint(int argc, char* argv[])
{
if(argc < 2) //delete all memory breakpoints
if(argc < 2) //disable all memory breakpoints
{
if(!BpGetCount(BPMEMORY))
{
@ -1225,13 +1481,18 @@ CMDRESULT cbDebugBpDll(int argc, char* argv[])
bool singleshoot = true;
if(argc > 3)
singleshoot = false;
if(!BpNewDll(argv[1], true, true, type, ""))
if(!BpNewDll(argv[1], true, false, type, ""))
{
dputs(QT_TRANSLATE_NOOP("DBG", "Error creating Dll breakpoint! (BpNewDll)"));
return STATUS_ERROR;
}
if(!LibrarianSetBreakPoint(argv[1], type, singleshoot, (void*)cbLibrarianBreakpoint))
{
dputs(QT_TRANSLATE_NOOP("DBG", "Error creating Dll breakpoint! (LibrarianSetBreakPoint)"));
return STATUS_ERROR;
}
dprintf(QT_TRANSLATE_NOOP("DBG", "Dll breakpoint set on \"%s\"!\n"), argv[1]);
DebugUpdateBreakpointsViewAsync();
return STATUS_CONTINUE;
}
@ -1239,18 +1500,114 @@ CMDRESULT cbDebugBcDll(int argc, char* argv[])
{
if(argc < 2)
{
dputs(QT_TRANSLATE_NOOP("DBG", "Not enough arguments"));
return STATUS_ERROR;
// delete all Dll breakpoints
if(!BpGetCount(BPDLL))
{
dputs(QT_TRANSLATE_NOOP("DBG", "No DLL breakpoints to delete!"));
return STATUS_CONTINUE;
}
if(!BpEnumAll(cbDeleteAllDllBreakpoints)) //at least one deletion failed
return STATUS_ERROR;
dputs(QT_TRANSLATE_NOOP("DBG", "All DLL breakpoints deleted!"));
DebugUpdateBreakpointsViewAsync();
return STATUS_CONTINUE;
}
if(!BpDelete(ModHashFromName(argv[1]), BPDLL))
BREAKPOINT bp;
if(!BpGetAny(BPDLL, argv[1], &bp))
return STATUS_ERROR;
if(!BpDelete(bp.addr, BPDLL))
{
dputs(QT_TRANSLATE_NOOP("DBG", "Failed to remove DLL breakpoint..."));
return STATUS_ERROR;
}
if(!LibrarianRemoveBreakPoint(argv[1], UE_ON_LIB_ALL))
if(!LibrarianRemoveBreakPoint(bp.mod, bp.titantype))
{
dputs(QT_TRANSLATE_NOOP("DBG", "Failed to remove DLL breakpoint..."));
return STATUS_ERROR;
}
dputs(QT_TRANSLATE_NOOP("DBG", "DLL breakpoint removed!"));
DebugUpdateBreakpointsViewAsync();
return STATUS_CONTINUE;
}
CMDRESULT cbDebugBpDllDisable(int argc, char* argv[])
{
if(argc < 2) //disable all DLL breakpoints
{
if(!BpGetCount(BPDLL))
{
dputs(QT_TRANSLATE_NOOP("DBG", "No DLL breakpoints to disable!"));
return STATUS_CONTINUE;
}
if(!BpEnumAll(cbDisableAllDllBreakpoints)) //at least one deletion failed
return STATUS_ERROR;
dputs(QT_TRANSLATE_NOOP("DBG", "All DLL breakpoints disabled!"));
GuiUpdateAllViews();
return STATUS_CONTINUE;
}
BREAKPOINT found;
duint addr = 0;
if(!BpGetAny(BPDLL, argv[1], &found)) //invalid DLL breakpoint
{
dprintf(QT_TRANSLATE_NOOP("DBG", "No such DLL breakpoint \"%s\"\n"), argv[1]);
return STATUS_ERROR;
}
if(!found.enabled)
{
dputs(QT_TRANSLATE_NOOP("DBG", "DLL breakpoint already disabled!"));
return STATUS_CONTINUE;
}
if(!BpEnable(found.addr, BPDLL, false))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not disable DLL breakpoint %s (BpEnable)\n"), found.mod);
return STATUS_ERROR;
}
if(!LibrarianSetBreakPoint(found.mod, found.titantype, found.singleshoot, (void*)cbLibrarianBreakpoint))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not disable DLL breakpoint %s (LibrarianSetBreakPoint)\n"), found.mod);
}
dputs(QT_TRANSLATE_NOOP("DBG", "DLL breakpoint disabled!"));
GuiUpdateAllViews();
return STATUS_CONTINUE;
}
CMDRESULT cbDebugBpDllEnable(int argc, char* argv[])
{
if(argc < 2) //disable all DLL breakpoints
{
if(!BpGetCount(BPDLL))
{
dputs(QT_TRANSLATE_NOOP("DBG", "No DLL breakpoints to enable!"));
return STATUS_CONTINUE;
}
if(!BpEnumAll(cbEnableAllDllBreakpoints)) //at least one deletion failed
return STATUS_ERROR;
dputs(QT_TRANSLATE_NOOP("DBG", "All DLL breakpoints enabled!"));
GuiUpdateAllViews();
return STATUS_CONTINUE;
}
BREAKPOINT found;
duint addr = 0;
if(!BpGetAny(BPDLL, argv[1], &found)) //invalid DLL breakpoint
{
dprintf(QT_TRANSLATE_NOOP("DBG", "No such DLL breakpoint \"%s\"\n"), argv[1]);
return STATUS_ERROR;
}
if(found.enabled)
{
dputs(QT_TRANSLATE_NOOP("DBG", "DLL breakpoint already enabled!"));
return STATUS_CONTINUE;
}
if(!BpEnable(found.addr, BPDLL, true))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable DLL breakpoint %s (BpEnable)\n"), found.mod);
return STATUS_ERROR;
}
if(!LibrarianRemoveBreakPoint(found.mod, found.titantype))
{
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 STATUS_CONTINUE;
}

View File

@ -592,9 +592,9 @@ static void printDllBpInfo(const BREAKPOINT & bp)
bptype = _strdup("");
}
if(*bp.name)
dprintf(QT_TRANSLATE_NOOP("DBG", "DLL Breakpoint %s(%s):Module %s"), bp.name, bptype, bp.mod);
dprintf(QT_TRANSLATE_NOOP("DBG", "DLL Breakpoint %s(%s):Module %s\n"), bp.name, bptype, bp.mod);
else
dprintf(QT_TRANSLATE_NOOP("DBG", "DLL Breakpoint(%s):Module %s"), bptype, bp.mod);
dprintf(QT_TRANSLATE_NOOP("DBG", "DLL Breakpoint(%s):Module %s\n"), bptype, bp.mod);
free(bptype);
}
@ -687,7 +687,7 @@ static void cbGenericBreakpoint(BP_TYPE bptype, void* ExceptionAddress = nullptr
bpPtr = BpInfoFromAddr(bptype, MemFindBaseAddr(duint(ExceptionAddress), nullptr, true));
break;
case BPDLL:
bpPtr = BpInfoFromAddr(BPDLL, ModHashFromName(reinterpret_cast<const char*>(ExceptionAddress)));
bpPtr = BpInfoFromAddr(BPDLL, BpGetDLLBpAddr(reinterpret_cast<const char*>(ExceptionAddress)));
break;
default:
break;
@ -965,6 +965,17 @@ bool cbSetModuleBreakpoints(const BREAKPOINT* bp)
return true;
}
bool cbSetDLLBreakpoints(const BREAKPOINT* bp)
{
if(!bp->enabled)
return true;
if(bp->type != BPDLL)
return true;
dputs("debug:dll breakpoint in database\n");
LibrarianSetBreakPoint(bp->mod, bp->titantype, bp->singleshoot, (void*)cbLibrarianBreakpoint);
return true;
}
EXCEPTION_DEBUG_INFO getLastExceptionInfo()
{
return lastExceptionInfo;
@ -1181,6 +1192,7 @@ static void cbCreateProcess(CREATE_PROCESS_DEBUG_INFO* CreateProcessInfo)
char modname[256] = "";
if(ModNameFromAddr((duint)base, modname, true))
BpEnumAll(cbSetModuleBreakpoints, modname, duint(base));
BpEnumAll(cbSetDLLBreakpoints);
BpEnumAll(cbSetModuleBreakpoints, "");
GuiUpdateBreakpointsView();
pCreateProcessBase = (duint)CreateProcessInfo->lpBaseOfImage;
@ -1755,207 +1767,6 @@ static void cbDebugEvent(DEBUG_EVENT* DebugEvent)
plugincbcall(CB_DEBUGEVENT, &debugEventInfo);
}
bool cbDeleteAllBreakpoints(const BREAKPOINT* bp)
{
if(bp->type != BPNORMAL)
return true;
if(!BpDelete(bp->addr, BPNORMAL))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Delete breakpoint failed (BpDelete): %p\n"), bp->addr);
return false;
}
if(bp->enabled && !DeleteBPX(bp->addr))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Delete breakpoint failed (DeleteBPX): %p\n"), bp->addr);
return false;
}
return true;
}
bool cbEnableAllBreakpoints(const BREAKPOINT* bp)
{
if(bp->type != BPNORMAL || bp->enabled)
return true;
if(!SetBPX(bp->addr, bp->titantype, (void*)cbUserBreakpoint))
{
if(!MemIsValidReadPtr(bp->addr))
return true;
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable breakpoint %p (SetBPX)\n"), bp->addr);
return false;
}
if(!BpEnable(bp->addr, BPNORMAL, true))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable breakpoint %p (BpEnable)\n"), bp->addr);
return false;
}
return true;
}
bool cbDisableAllBreakpoints(const BREAKPOINT* bp)
{
if(bp->type != BPNORMAL || !bp->enabled)
return true;
if(!BpEnable(bp->addr, BPNORMAL, false))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not disable breakpoint %p (BpEnable)\n"), bp->addr);
return false;
}
if(!DeleteBPX(bp->addr))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not disable breakpoint %p (DeleteBPX)\n"), bp->addr);
return false;
}
return true;
}
bool cbEnableAllHardwareBreakpoints(const BREAKPOINT* bp)
{
if(bp->type != BPHARDWARE || bp->enabled)
return true;
DWORD drx = 0;
if(!GetUnusedHardwareBreakPointRegister(&drx))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Did not enable hardware breakpoint %p (all slots full)\n"), bp->addr);
return true;
}
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), (void*)cbHardwareBreakpoint))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable hardware breakpoint %p (SetHardwareBreakPoint)\n"), bp->addr);
return false;
}
return true;
}
bool cbDisableAllHardwareBreakpoints(const BREAKPOINT* bp)
{
if(bp->type != BPHARDWARE)
return true;
if(!BpEnable(bp->addr, BPHARDWARE, false))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not disable hardware breakpoint %p (BpEnable)\n"), bp->addr);
return false;
}
if(bp->enabled && !DeleteHardwareBreakPoint(TITANGETDRX(bp->titantype)))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not disable hardware breakpoint %p (DeleteHardwareBreakPoint)\n"), bp->addr);
return false;
}
return true;
}
bool cbEnableAllMemoryBreakpoints(const BREAKPOINT* bp)
{
if(bp->type != BPMEMORY || bp->enabled)
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, (void*)cbMemoryBreakpoint))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not enable memory breakpoint %p (SetMemoryBPXEx)\n"), bp->addr);
return false;
}
return true;
}
bool cbDisableAllMemoryBreakpoints(const BREAKPOINT* bp)
{
if(bp->type != BPMEMORY || !bp->enabled)
return true;
if(!BpEnable(bp->addr, BPMEMORY, false))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not disable memory breakpoint %p (BpEnable)\n"), bp->addr);
return false;
}
if(!RemoveMemoryBPX(bp->addr, 0))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not disable memory breakpoint %p (RemoveMemoryBPX)\n"), bp->addr);
return false;
}
return true;
}
bool cbBreakpointList(const BREAKPOINT* bp)
{
const char* type = 0;
if(bp->type == BPNORMAL)
{
if(bp->singleshoot)
type = "SS";
else
type = "BP";
}
else if(bp->type == BPHARDWARE)
type = "HW";
else if(bp->type == BPMEMORY)
type = "GP";
else if(bp->type == BPDLL)
type = "DLL";
bool enabled = bp->enabled;
if(bp->type == BPDLL)
{
if(*bp->name)
dprintf_untranslated("%d:%s:\"%s\":\"%s\"\n", enabled, type, bp->mod, bp->name);
else
dprintf_untranslated("%d:%s:\"%s\"\n", enabled, type, bp->mod);
}
else if(*bp->name)
dprintf_untranslated("%d:%s:%p:\"%s\"\n", enabled, type, bp->addr, bp->name);
else
dprintf_untranslated("%d:%s:%p\n", enabled, type, bp->addr);
return true;
}
bool cbDeleteAllMemoryBreakpoints(const BREAKPOINT* bp)
{
if(bp->type != BPMEMORY)
return true;
duint size;
MemFindBaseAddr(bp->addr, &size);
if(!BpDelete(bp->addr, BPMEMORY))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Delete memory breakpoint failed (BpDelete): %p\n"), bp->addr);
return false;
}
if(bp->enabled && !RemoveMemoryBPX(bp->addr, size))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Delete memory breakpoint failed (RemoveMemoryBPX): %p\n"), bp->addr);
return false;
}
return true;
}
bool cbDeleteAllHardwareBreakpoints(const BREAKPOINT* bp)
{
if(bp->type != BPHARDWARE)
return true;
if(!BpDelete(bp->addr, BPHARDWARE))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Delete hardware breakpoint failed (BpDelete): %p\n"), bp->addr);
return false;
}
if(bp->enabled && !DeleteHardwareBreakPoint(TITANGETDRX(bp->titantype)))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "Delete hardware breakpoint failed (DeleteHardwareBreakPoint): %p\n"), bp->addr);
return false;
}
return true;
}
static void cbAttachDebugger()
{
if(hEvent) //Signal the AeDebug event

View File

@ -121,16 +121,6 @@ void cbUserBreakpoint();
void cbDebugLoadLibBPX();
void cbLibrarianBreakpoint(void* lpData);
DWORD WINAPI threadDebugLoop(void* lpParameter);
bool cbDeleteAllBreakpoints(const BREAKPOINT* bp);
bool cbEnableAllBreakpoints(const BREAKPOINT* bp);
bool cbDisableAllBreakpoints(const BREAKPOINT* bp);
bool cbEnableAllHardwareBreakpoints(const BREAKPOINT* bp);
bool cbDisableAllHardwareBreakpoints(const BREAKPOINT* bp);
bool cbEnableAllMemoryBreakpoints(const BREAKPOINT* bp);
bool cbDisableAllMemoryBreakpoints(const BREAKPOINT* bp);
bool cbBreakpointList(const BREAKPOINT* bp);
bool cbDeleteAllMemoryBreakpoints(const BREAKPOINT* bp);
bool cbDeleteAllHardwareBreakpoints(const BREAKPOINT* bp);
void cbTOCNDStep();
void cbTICNDStep();
void cbTIBTStep();

View File

@ -69,6 +69,8 @@ CMDRESULT cbDebugSetBPXDLLFastResume(int argc, char* argv[]);
CMDRESULT cbDebugSetBPXDLLSingleshoot(int argc, char* argv[]);
CMDRESULT cbDebugSetBPXDLLSilent(int argc, char* argv[]);
CMDRESULT cbDebugResetBPXDLLHitCount(int argc, char* argv[]);
CMDRESULT cbDebugBpDllDisable(int argc, char* argv[]);
CMDRESULT cbDebugBpDllEnable(int argc, char* argv[]);
CMDRESULT cbDebugBplist(int argc, char* argv[]);
CMDRESULT cbDebugStepInto(int argc, char* argv[]);
CMDRESULT cbDebugeStepInto(int argc, char* argv[]);

View File

@ -138,6 +138,8 @@ static void registercommands()
dbgcmdnew("DisableMemoryBreakpoint\1membpd\1bpmd", cbDebugDisableMemoryBreakpoint, true); //enable memory breakpoint
dbgcmdnew("LibrarianSetBreakPoint\1bpdll", cbDebugBpDll, true); //set dll breakpoint
dbgcmdnew("LibrarianRemoveBreakPoint\1bcdll", cbDebugBcDll, true); //remove dll breakpoint
dbgcmdnew("LibrarianDisableBreakPoint", cbDebugBpDllDisable, true);
dbgcmdnew("LibrarianEnableBreakPoint", cbDebugBpDllEnable, true);
//breakpoints (conditional)
dbgcmdnew("SetBreakpointName\1bpname", cbDebugSetBPXName, true); //set breakpoint name
@ -174,16 +176,16 @@ static void registercommands()
dbgcmdnew("SetMemoryGetBreakpointHitCount", cbDebugGetBPXMemoryHitCount, true); //get breakpoint hit count
dbgcmdnew("ResetMemoryBreakpointHitCount", cbDebugResetBPXMemoryHitCount, true); //reset breakpoint hit count
dbgcmdnew("SetLibrarianBreakpointName", cbDebugSetBPXDLLName, true); //set breakpoint name
dbgcmdnew("SetLibrarianBreakpointCondition", cbDebugSetBPXMemoryCondition, true); //set breakpoint breakCondition
dbgcmdnew("SetLibrarianBreakpointLog", cbDebugSetBPXMemoryLog, true); //set breakpoint log
dbgcmdnew("SetLibrarianBreakpointLogCondition", cbDebugSetBPXMemoryLogCondition, true); //set breakpoint logCondition
dbgcmdnew("SetLibrarianBreakpointCommand", cbDebugSetBPXMemoryCommand, true); //set breakpoint command on hit
dbgcmdnew("SetLibrarianBreakpointCommandCondition", cbDebugSetBPXMemoryCommandCondition, true); //set breakpoint commandCondition
dbgcmdnew("SetLibrarianBreakpointFastResume", cbDebugSetBPXMemoryFastResume, true); //set breakpoint fast resume
dbgcmdnew("SetLibrarianBreakpointSingleshoot", cbDebugSetBPXMemorySingleshoot, true); //set breakpoint singleshoot
dbgcmdnew("SetLibrarianBreakpointSilent", cbDebugSetBPXMemorySilent, true); //set breakpoint fast resume
dbgcmdnew("SetLibrarianGetBreakpointHitCount", cbDebugGetBPXMemoryHitCount, true); //get breakpoint hit count
dbgcmdnew("ResetLibrarianBreakpointHitCount", cbDebugResetBPXMemoryHitCount, true); //reset breakpoint hit count
dbgcmdnew("SetLibrarianBreakpointCondition", cbDebugSetBPXDLLCondition, true); //set breakpoint breakCondition
dbgcmdnew("SetLibrarianBreakpointLog", cbDebugSetBPXDLLLog, true); //set breakpoint log
dbgcmdnew("SetLibrarianBreakpointLogCondition", cbDebugSetBPXDLLLogCondition, true); //set breakpoint logCondition
dbgcmdnew("SetLibrarianBreakpointCommand", cbDebugSetBPXDLLCommand, true); //set breakpoint command on hit
dbgcmdnew("SetLibrarianBreakpointCommandCondition", cbDebugSetBPXDLLCommandCondition, true); //set breakpoint commandCondition
dbgcmdnew("SetLibrarianBreakpointFastResume", cbDebugSetBPXDLLFastResume, true); //set breakpoint fast resume
dbgcmdnew("SetLibrarianBreakpointSingleshoot", cbDebugSetBPXDLLSingleshoot, true); //set breakpoint singleshoot
dbgcmdnew("SetLibrarianBreakpointSilent", cbDebugSetBPXDLLSilent, true); //set breakpoint fast resume
dbgcmdnew("SetLibrarianGetBreakpointHitCount", cbDebugGetBPXDLLHitCount, true); //get breakpoint hit count
dbgcmdnew("ResetLibrarianBreakpointHitCount", cbDebugResetBPXDLLHitCount, true); //reset breakpoint hit count
dbgcmdnew("bpgoto", cbDebugSetBPGoto, true);

View File

@ -55,11 +55,25 @@ BreakpointsView::BreakpointsView(QWidget* parent) : QWidget(parent)
mMemBPTable->addColumnAt(wCharWidth * 10, tr("Comment"), false);
mMemBPTable->loadColumnFromConfig("MemoryBreakpoint");
// DLL
mDLLBPTable = new StdTable(this);
mDLLBPTable->setContextMenuPolicy(Qt::CustomContextMenu);
mDLLBPTable->addColumnAt(8 + wCharWidth * 32, tr("Name"), false);
mDLLBPTable->addColumnAt(8 + wCharWidth * 32, tr("Module"), false);
mDLLBPTable->addColumnAt(8 + wCharWidth * 8, tr("State"), false);
mDLLBPTable->addColumnAt(8 + wCharWidth * 10, tr("Hit count"), false);
mDLLBPTable->addColumnAt(8 + wCharWidth * 32, tr("Log text"), false);
mDLLBPTable->addColumnAt(8 + wCharWidth * 32, tr("Condition"), false);
mDLLBPTable->addColumnAt(8 + wCharWidth * 2, tr("Fast resume"), false);
mDLLBPTable->addColumnAt(8 + wCharWidth * 16, tr("Command on hit"), false);
mDLLBPTable->loadColumnFromConfig("DLLBreakpoint");
// Splitter
mSplitter = new LabeledSplitter(this);
mSplitter->addWidget(mSoftBPTable, tr("Software breakpoint"));
mSplitter->addWidget(mHardBPTable, tr("Hardware breakpoint"));
mSplitter->addWidget(mMemBPTable, tr("Memory breakpoint"));
mSplitter->addWidget(mDLLBPTable, tr("DLL breakpoint"));
mSplitter->collapseLowerTabs();
// Layout
@ -89,6 +103,9 @@ BreakpointsView::BreakpointsView(QWidget* parent) : QWidget(parent)
connect(mMemBPTable, SIGNAL(doubleClickedSignal()), this, SLOT(doubleClickMemorySlot()));
connect(mMemBPTable, SIGNAL(enterPressedSignal()), this, SLOT(doubleClickMemorySlot()));
connect(mMemBPTable, SIGNAL(selectionChangedSignal(int)), this, SLOT(selectionChangedMemorySlot()));
connect(mDLLBPTable, SIGNAL(contextMenuSignal(const QPoint &)), this, SLOT(DLLBPContextMenuSlot(const QPoint &)));
connect(mDLLBPTable, SIGNAL(selectionChangedSignal(int)), this, SLOT(selectionChangedDLLSlot()));
mCurrentType = bp_normal;
}
@ -105,14 +122,14 @@ void BreakpointsView::reloadData()
{
QString addr_text = QString("%1").arg(wBPList.bp[wI].addr, sizeof(dsint) * 2, 16, QChar('0')).toUpper();
mHardBPTable->setCellContent(wI, 0, addr_text);
mHardBPTable->setCellContent(wI, 1, QString(wBPList.bp[wI].name));
mHardBPTable->setCellContent(wI, 1, QString::fromUtf8(wBPList.bp[wI].name));
QString label_text;
char label[MAX_LABEL_SIZE] = "";
if(DbgGetLabelAt(wBPList.bp[wI].addr, SEG_DEFAULT, label))
label_text = "<" + QString(wBPList.bp[wI].mod) + "." + QString(label) + ">";
label_text = "<" + QString::fromUtf8(wBPList.bp[wI].mod) + "." + QString::fromUtf8(label) + ">";
else
label_text = QString(wBPList.bp[wI].mod);
label_text = QString::fromUtf8(wBPList.bp[wI].mod);
mHardBPTable->setCellContent(wI, 2, label_text);
if(wBPList.bp[wI].active == false)
@ -146,14 +163,14 @@ void BreakpointsView::reloadData()
{
QString addr_text = QString("%1").arg(wBPList.bp[wI].addr, sizeof(dsint) * 2, 16, QChar('0')).toUpper();
mSoftBPTable->setCellContent(wI, 0, addr_text);
mSoftBPTable->setCellContent(wI, 1, QString(wBPList.bp[wI].name));
mSoftBPTable->setCellContent(wI, 1, QString::fromUtf8(wBPList.bp[wI].name));
QString label_text;
char label[MAX_LABEL_SIZE] = "";
if(DbgGetLabelAt(wBPList.bp[wI].addr, SEG_DEFAULT, label))
label_text = "<" + QString(wBPList.bp[wI].mod) + "." + QString(label) + ">";
label_text = "<" + QString::fromUtf8(wBPList.bp[wI].mod) + "." + QString::fromUtf8(label) + ">";
else
label_text = QString(wBPList.bp[wI].mod);
label_text = QString::fromUtf8(wBPList.bp[wI].mod);
mSoftBPTable->setCellContent(wI, 2, label_text);
if(wBPList.bp[wI].active == false)
@ -186,14 +203,14 @@ void BreakpointsView::reloadData()
{
QString addr_text = QString("%1").arg(wBPList.bp[wI].addr, sizeof(dsint) * 2, 16, QChar('0')).toUpper();
mMemBPTable->setCellContent(wI, 0, addr_text);
mMemBPTable->setCellContent(wI, 1, QString(wBPList.bp[wI].name));
mMemBPTable->setCellContent(wI, 1, QString::fromUtf8(wBPList.bp[wI].name));
QString label_text;
char label[MAX_LABEL_SIZE] = "";
if(DbgGetLabelAt(wBPList.bp[wI].addr, SEG_DEFAULT, label))
label_text = "<" + QString(wBPList.bp[wI].mod) + "." + QString(label) + ">";
label_text = "<" + QString::fromUtf8(wBPList.bp[wI].mod) + "." + QString::fromUtf8(label) + ">";
else
label_text = QString(wBPList.bp[wI].mod);
label_text = QString::fromUtf8(wBPList.bp[wI].mod);
mMemBPTable->setCellContent(wI, 2, label_text);
if(wBPList.bp[wI].active == false)
@ -217,6 +234,29 @@ void BreakpointsView::reloadData()
}
mMemBPTable->reloadData();
// DLL
DbgGetBpList(bp_dll, &wBPList);
mDLLBPTable->setRowCount(wBPList.count);
for(wI = 0; wI < wBPList.count; wI++)
{
mDLLBPTable->setCellContent(wI, 0, QString::fromUtf8(wBPList.bp[wI].name));
mDLLBPTable->setCellContent(wI, 1, QString::fromUtf8(wBPList.bp[wI].mod));
if(wBPList.bp[wI].active == false)
mDLLBPTable->setCellContent(wI, 2, tr("Inactive"));
else if(wBPList.bp[wI].enabled == true)
mDLLBPTable->setCellContent(wI, 2, tr("Enabled"));
else
mDLLBPTable->setCellContent(wI, 2, tr("Disabled"));
mDLLBPTable->setCellContent(wI, 3, QString("%1").arg(wBPList.bp[wI].hitCount));
mDLLBPTable->setCellContent(wI, 4, QString().fromUtf8(wBPList.bp[wI].logText));
mDLLBPTable->setCellContent(wI, 5, QString().fromUtf8(wBPList.bp[wI].breakCondition));
mDLLBPTable->setCellContent(wI, 6, wBPList.bp[wI].fastResume ? "X" : "");
mDLLBPTable->setCellContent(wI, 7, QString().fromUtf8(wBPList.bp[wI].commandText));
}
mDLLBPTable->reloadData();
if(wBPList.count)
BridgeFree(wBPList.bp);
}
@ -230,6 +270,7 @@ void BreakpointsView::setupRightClickContextMenu()
setupSoftBPRightClickContextMenu();
setupHardBPRightClickContextMenu();
setupMemBPRightClickContextMenu();
setupDLLBPRightClickContextMenu();
}
/************************************************************************************
@ -717,6 +758,155 @@ void BreakpointsView::resetMemoryHitCountSlot()
reloadData();
}
/************************************************************************************
DLL Context Menu Management
************************************************************************************/
void BreakpointsView::setupDLLBPRightClickContextMenu()
{
// Remove
mDLLBPRemoveAction = new QAction(tr("Remove"), this);
mDLLBPRemoveAction->setShortcutContext(Qt::WidgetShortcut);
mDLLBPTable->addAction(mDLLBPRemoveAction);
connect(mDLLBPRemoveAction, SIGNAL(triggered()), this, SLOT(removeDLLBPActionSlot()));
// Remove All
mDLLBPRemoveAllAction = new QAction(tr("Remove All"), this);
connect(mDLLBPRemoveAllAction, SIGNAL(triggered()), this, SLOT(removeAllDLLBPActionSlot()));
// Enable/Disable
mDLLBPEnableDisableAction = new QAction(tr("Enable"), this);
mDLLBPEnableDisableAction->setShortcutContext(Qt::WidgetShortcut);
mDLLBPTable->addAction(mDLLBPEnableDisableAction);
connect(mDLLBPEnableDisableAction, SIGNAL(triggered()), this, SLOT(enableDisableDLLBPActionSlot()));
// Reset hit count
mDLLBPResetHitCountAction = new QAction(tr("Reset hit count"), this);
mDLLBPTable->addAction(mDLLBPResetHitCountAction);
connect(mDLLBPResetHitCountAction, SIGNAL(triggered()), this, SLOT(resetDLLHitCountSlot()));
// Enable All
mDLLBPEnableAllAction = new QAction(tr("Enable All"), this);
mDLLBPTable->addAction(mDLLBPEnableAllAction);
connect(mDLLBPEnableAllAction, SIGNAL(triggered()), this, SLOT(enableAllDLLBPActionSlot()));
// Disable All
mDLLBPDisableAllAction = new QAction(tr("Disable All"), this);
mDLLBPTable->addAction(mDLLBPDisableAllAction);
connect(mDLLBPDisableAllAction, SIGNAL(triggered()), this, SLOT(disableAllDLLBPActionSlot()));
}
void BreakpointsView::DLLBPContextMenuSlot(const QPoint & pos)
{
StdTable* table = mDLLBPTable;
if(table->getRowCount() != 0)
{
int wI = 0;
QMenu wMenu(this);
QString wName = table->getCellContent(table->getInitialSelection(), 1);
BPMAP wBPList;
// Remove
wMenu.addAction(mDLLBPRemoveAction);
// Enable/Disable
DbgGetBpList(bp_dll, &wBPList);
for(wI = 0; wI < wBPList.count; wI++)
{
if(QString::fromUtf8(wBPList.bp[wI].mod) == wName)
{
if(wBPList.bp[wI].active == false)
{
mDLLBPEnableDisableAction->setText(tr("Enable"));
wMenu.addAction(mDLLBPEnableDisableAction);
}
else if(wBPList.bp[wI].enabled == true)
{
mDLLBPEnableDisableAction->setText(tr("Disable"));
wMenu.addAction(mDLLBPEnableDisableAction);
}
else
{
mDLLBPEnableDisableAction->setText(tr("Enable"));
wMenu.addAction(mDLLBPEnableDisableAction);
}
}
}
if(wBPList.count)
BridgeFree(wBPList.bp);
// Conditional
mCurrentType = bp_dll;
wMenu.addAction(mEditBreakpointAction);
wMenu.addAction(mDLLBPResetHitCountAction);
// Separator
wMenu.addSeparator();
// Enable All
wMenu.addAction(mDLLBPEnableAllAction);
// Disable All
wMenu.addAction(mDLLBPDisableAllAction);
// Remove All
wMenu.addAction(mDLLBPRemoveAllAction);
//Copy
QMenu wCopyMenu(tr("&Copy"), this);
table->setupCopyMenu(&wCopyMenu);
if(wCopyMenu.actions().length())
{
wMenu.addSeparator();
wMenu.addMenu(&wCopyMenu);
}
wMenu.exec(table->mapToGlobal(pos));
}
}
void BreakpointsView::removeDLLBPActionSlot()
{
StdTable* table = mDLLBPTable;
Breakpoints::removeBP(table->getCellContent(table->getInitialSelection(), 1));
}
void BreakpointsView::enableDisableDLLBPActionSlot()
{
StdTable* table = mDLLBPTable;
Breakpoints::toggleBPByDisabling(table->getCellContent(table->getInitialSelection(), 1));
table->selectNext();
}
void BreakpointsView::selectionChangedDLLSlot()
{
mCurrentType = bp_dll;
}
void BreakpointsView::resetDLLHitCountSlot()
{
StdTable* table = mDLLBPTable;
QString addrText = table->getCellContent(table->getInitialSelection(), 1);
DbgCmdExecDirect(QString("ResetLibrarianBreakpointHitCount \"%1\"").arg(addrText).toUtf8().constData());
reloadData();
}
void BreakpointsView::enableAllDLLBPActionSlot()
{
DbgCmdExec("LibrarianEnableBreakPoint");
}
void BreakpointsView::disableAllDLLBPActionSlot()
{
DbgCmdExec("LibrarianDisableBreakPoint");
}
void BreakpointsView::removeAllDLLBPActionSlot()
{
DbgCmdExec("LibrarianRemoveBreakPoint");
}
/************************************************************************************
Conditional Breakpoint Context Menu Management (Sub-menu only)
************************************************************************************/
@ -734,6 +924,10 @@ void BreakpointsView::editBreakpointSlot()
case bp_memory:
table = mMemBPTable;
break;
case bp_dll:
table = mDLLBPTable;
Breakpoints::editBP(mCurrentType, table->getCellContent(table->getInitialSelection(), 1), this);
return;
default:
return;
}

View File

@ -7,6 +7,7 @@
class StdTable;
class QVBoxLayout;
class LabeledSplitter;
class MenuBuilder;
class BreakpointsView : public QWidget
{
@ -17,6 +18,7 @@ public:
void setupHardBPRightClickContextMenu();
void setupSoftBPRightClickContextMenu();
void setupMemBPRightClickContextMenu();
void setupDLLBPRightClickContextMenu();
signals:
void showCpu();
@ -58,6 +60,16 @@ public slots:
void selectionChangedMemorySlot();
void resetMemoryHitCountSlot();
// DLL
void DLLBPContextMenuSlot(const QPoint & pos);
void removeDLLBPActionSlot();
void removeAllDLLBPActionSlot();
void enableDisableDLLBPActionSlot();
void enableAllDLLBPActionSlot();
void disableAllDLLBPActionSlot();
void selectionChangedDLLSlot();
void resetDLLHitCountSlot();
// Conditional
void editBreakpointSlot();
@ -67,6 +79,7 @@ private:
StdTable* mHardBPTable;
StdTable* mSoftBPTable;
StdTable* mMemBPTable;
StdTable* mDLLBPTable;
// Conditional BP Context Menu
BPXTYPE mCurrentType;
QAction* mEditBreakpointAction;
@ -94,6 +107,14 @@ private:
QAction* mMemBPResetHitCountAction;
QAction* mMemBPEnableAllAction;
QAction* mMemBPDisableAllAction;
// DLL BP Context Menu
QAction* mDLLBPRemoveAction;
QAction* mDLLBPRemoveAllAction;
QAction* mDLLBPEnableDisableAction;
QAction* mDLLBPResetHitCountAction;
QAction* mDLLBPEnableAllAction;
QAction* mDLLBPDisableAllAction;
};
#endif // BREAKPOINTSVIEW_H

View File

@ -10,7 +10,14 @@ EditBreakpointDialog::EditBreakpointDialog(QWidget* parent, const BRIDGEBP & bp)
ui->setupUi(this);
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint | Qt::MSWindowsFixedSizeDialogHint);
setFixedSize(this->size()); //fixed size
setWindowTitle(QString(tr("Edit Breakpoint %1")).arg(ToHexString(bp.addr)));
if(bp.type == bp_dll)
{
setWindowTitle(QString(tr("Edit Breakpoint %1")).arg(QString::fromUtf8(bp.mod)));
}
else
{
setWindowTitle(QString(tr("Edit Breakpoint %1")).arg(ToHexString(bp.addr)));
}
setWindowIcon(DIcon("breakpoint.png"));
loadFromBp();
}
@ -35,8 +42,10 @@ void EditBreakpointDialog::loadFromBp()
}
template<typename T>
void copyTruncate(T & dest, const QString & src)
void copyTruncate(T & dest, QString src)
{
src.replace(QChar('\\'), QString("\\\\"));
src.replace(QChar('"'), QString("\\\""));
strncpy_s(dest, src.toUtf8().constData(), _TRUNCATE);
}

View File

@ -112,13 +112,16 @@ void HandlesView::handlesTableContextMenuSlot(const QPoint & pos)
StdTable & table = *mHandlesTable;
QMenu wMenu;
wMenu.addAction(mActionRefresh);
wMenu.addAction(mActionCloseHandle);
QMenu wCopyMenu(tr("&Copy"));
table.setupCopyMenu(&wCopyMenu);
if(wCopyMenu.actions().length())
if(mHandlesTable->getRowCount() != 0)
{
wMenu.addSeparator();
wMenu.addMenu(&wCopyMenu);
wMenu.addAction(mActionCloseHandle);
QMenu wCopyMenu(tr("&Copy"));
table.setupCopyMenu(&wCopyMenu);
if(wCopyMenu.actions().length())
{
wMenu.addSeparator();
wMenu.addMenu(&wCopyMenu);
}
}
wMenu.exec(table.mapToGlobal(pos));
}
@ -128,12 +131,15 @@ void HandlesView::tcpConnectionsTableContextMenuSlot(const QPoint & pos)
StdTable & table = *mTcpConnectionsTable;
QMenu wMenu;
wMenu.addAction(mActionRefresh);
QMenu wCopyMenu(tr("&Copy"));
table.setupCopyMenu(&wCopyMenu);
if(wCopyMenu.actions().length())
if(mTcpConnectionsTable->getRowCount() != 0)
{
wMenu.addSeparator();
wMenu.addMenu(&wCopyMenu);
QMenu wCopyMenu(tr("&Copy"));
table.setupCopyMenu(&wCopyMenu);
if(wCopyMenu.actions().length())
{
wMenu.addSeparator();
wMenu.addMenu(&wCopyMenu);
}
}
wMenu.exec(table.mapToGlobal(pos));
}
@ -143,7 +149,7 @@ void HandlesView::privilegesTableContextMenuSlot(const QPoint & pos)
{
StdTable & table = *mPrivilegesTable;
QMenu wMenu;
bool isValid = (mPrivilegesTable->getCellContent(mPrivilegesTable->getInitialSelection(), 1) != tr("Unknown"));
bool isValid = (mPrivilegesTable->getRowCount() != 0 && mPrivilegesTable->getCellContent(mPrivilegesTable->getInitialSelection(), 1) != tr("Unknown"));
wMenu.addAction(mActionRefresh);
if(isValid)
{

View File

@ -256,7 +256,7 @@ MainWindow::MainWindow(QWidget* parent)
connect(ui->actionCommand, SIGNAL(triggered()), this, SLOT(setFocusToCommandBar()));
makeCommandAction(ui->actionClose, "stop");
connect(ui->actionMemoryMap, SIGNAL(triggered()), this, SLOT(displayMemMapWidget()));
makeCommandAction(ui->actionRun, "run");
connect(ui->actionRun, SIGNAL(triggered()), this, SLOT(runSlot()));
makeCommandAction(ui->actionRtr, "rtr");
connect(ui->actionLog, SIGNAL(triggered()), this, SLOT(displayLogWidget()));
connect(ui->actionAbout, SIGNAL(triggered()), this, SLOT(displayAboutWidget()));
@ -826,6 +826,14 @@ void MainWindow::openFile()
mCpuWidget->setDisasmFocus();
}
void MainWindow::runSlot()
{
if(DbgIsDebugging())
DbgCmdExec("run");
else
restartDebugging();
}
void MainWindow::restartDebugging()
{
if(!mMRUList.size())

View File

@ -70,6 +70,7 @@ public slots:
void restartDebugging();
void displayBreakpointWidget();
void updateWindowTitleSlot(QString filename);
void runSlot();
void execTRBit();
void execTRByte();
void execTRWord();

View File

@ -3,7 +3,7 @@ struct ActionShortcut
QAction* action;
QString shortcut;
ActionShortcut(QAction* action, const char* shortcut)
inline ActionShortcut(QAction* action, const char* shortcut)
: action(action),
shortcut(shortcut)
{

View File

@ -60,16 +60,21 @@ void Breakpoints::enableBP(const BRIDGEBP & bp)
if(bp.type == bp_hardware)
{
wCmd = "bphwe " + QString("%1").arg(bp.addr, sizeof(dsint) * 2, 16, QChar('0')).toUpper();
wCmd = QString("bphwe \"%1\"").arg(ToPtrString(bp.addr));
}
else if(bp.type == bp_normal)
{
wCmd = "be " + QString("%1").arg(bp.addr, sizeof(dsint) * 2, 16, QChar('0')).toUpper();
wCmd = QString("be \"%1\"").arg(ToPtrString(bp.addr));
}
else if(bp.type == bp_memory)
{
wCmd = "bpme " + QString("%1").arg(bp.addr, sizeof(dsint) * 2, 16, QChar('0')).toUpper();
wCmd = QString("bpme \"%1\"").arg(ToPtrString(bp.addr));
}
else if(bp.type == bp_dll)
{
wCmd = QString("LibrarianEnableBreakPoint \"%1\"").arg(QString::fromUtf8(bp.mod));
}
DbgCmdExec(wCmd.toUtf8().constData());
}
@ -117,15 +122,19 @@ void Breakpoints::disableBP(const BRIDGEBP & bp)
if(bp.type == bp_hardware)
{
wCmd = "bphwd " + QString("%1").arg(bp.addr, sizeof(dsint) * 2, 16, QChar('0')).toUpper();
wCmd = QString("bphwd \"%1\"").arg(ToPtrString(bp.addr));
}
else if(bp.type == bp_normal)
{
wCmd = "bd " + QString("%1").arg(bp.addr, sizeof(dsint) * 2, 16, QChar('0')).toUpper();
wCmd = QString("bd \"%1\"").arg(ToPtrString(bp.addr));
}
else if(bp.type == bp_memory)
{
wCmd = "bpmd " + QString("%1").arg(bp.addr, sizeof(dsint) * 2, 16, QChar('0')).toUpper();
wCmd = QString("bpmd \"%1\"").arg(ToPtrString(bp.addr));
}
else if(bp.type == bp_dll)
{
wCmd = QString("LibrarianDisableBreakPoint \"%1\"").arg(QString::fromUtf8(bp.mod));
}
DbgCmdExec(wCmd.toUtf8().constData());
@ -175,22 +184,20 @@ void Breakpoints::removeBP(const BRIDGEBP & bp)
switch(bp.type)
{
case bp_normal:
{
wCmd = "bc " + QString("%1").arg(bp.addr, sizeof(dsint) * 2, 16, QChar('0')).toUpper();
}
break;
wCmd = QString("bc \"%1\"").arg(ToPtrString(bp.addr));
break;
case bp_hardware:
{
wCmd = "bphc " + QString("%1").arg(bp.addr, sizeof(dsint) * 2, 16, QChar('0')).toUpper();
}
break;
wCmd = QString("bphc \"%1\"").arg(ToPtrString(bp.addr));
break;
case bp_memory:
{
wCmd = "bpmc " + QString("%1").arg(bp.addr, sizeof(dsint) * 2, 16, QChar('0')).toUpper();
}
break;
wCmd = QString("bpmc \"%1\"").arg(ToPtrString(bp.addr));
break;
case bp_dll:
wCmd = QString("bcdll \"%1\"").arg(QString::fromUtf8(bp.mod));
break;
default:
{
@ -232,6 +239,25 @@ void Breakpoints::removeBP(BPXTYPE type, duint va)
BridgeFree(wBPList.bp);
}
void Breakpoints::removeBP(const QString & DLLName)
{
BPMAP wBPList;
// Get breakpoints list
DbgGetBpList(bp_dll, &wBPList);
// Find breakpoint at DLLName
for(int wI = 0; wI < wBPList.count; wI++)
{
if(QString::fromUtf8(wBPList.bp[wI].mod) == DLLName)
{
removeBP(wBPList.bp[wI]);
}
}
if(wBPList.count)
BridgeFree(wBPList.bp);
}
/**
* @brief Toggle the given breakpoint by disabling it when enabled.@n
* If breakpoint is initially active and enabled, it will be disabled.@n
@ -279,6 +305,25 @@ void Breakpoints::toggleBPByDisabling(BPXTYPE type, duint va)
BridgeFree(wBPList.bp);
}
void Breakpoints::toggleBPByDisabling(const QString & DLLName)
{
BPMAP wBPList;
// Get breakpoints list
DbgGetBpList(bp_dll, &wBPList);
// Find breakpoint at module name
for(int wI = 0; wI < wBPList.count; wI++)
{
if(QString::fromUtf8(wBPList.bp[wI].mod) == DLLName)
{
toggleBPByDisabling(wBPList.bp[wI]);
}
}
if(wBPList.count)
BridgeFree(wBPList.bp);
}
void Breakpoints::toggleAllBP(BPXTYPE type, bool bEnable)
{
BPMAP wBPList;
@ -410,9 +455,14 @@ void Breakpoints::toggleBPByRemoving(BPXTYPE type, duint va)
void Breakpoints::editBP(BPXTYPE type, const QString & addrText, QWidget* widget)
{
duint addr = addrText.toULongLong(nullptr, 16);
BRIDGEBP bridgebp;
if(!DbgFunctions()->GetBridgeBp(type, addr, &bridgebp))
if(type != bp_dll)
{
duint addr = addrText.toULongLong(nullptr, 16);
if(!DbgFunctions()->GetBridgeBp(type, addr, &bridgebp))
return;
}
else if(!DbgFunctions()->GetBridgeBp(type, reinterpret_cast<duint>(addrText.toUtf8().constData()), &bridgebp))
return;
EditBreakpointDialog dialog(widget, bridgebp);
if(dialog.exec() != QDialog::Accepted)
@ -431,7 +481,7 @@ void Breakpoints::editBP(BPXTYPE type, const QString & addrText, QWidget* widget
exec(QString("SetBreakpointLogCondition %1, \"%2\"").arg(addrText).arg(bp.logCondition));
exec(QString("SetBreakpointCommand %1, \"%2\"").arg(addrText).arg(bp.commandText));
exec(QString("SetBreakpointCommandCondition %1, \"%2\"").arg(addrText).arg(bp.commandCondition));
exec(QString("ResetBreakpointHitCount %1, %2").arg(addrText).arg(bp.hitCount));
exec(QString("ResetBreakpointHitCount %1, %2").arg(addrText).arg(ToPtrString(bp.hitCount)));
exec(QString("SetBreakpointFastResume %1, %2").arg(addrText).arg(bp.fastResume));
exec(QString("SetBreakpointSilent %1, %2").arg(addrText).arg(bp.silent));
exec(QString("SetBreakpointSingleshoot %1, %2").arg(addrText).arg(bp.singleshoot));
@ -443,7 +493,7 @@ void Breakpoints::editBP(BPXTYPE type, const QString & addrText, QWidget* widget
exec(QString("SetHardwareBreakpointLogCondition %1, \"%2\"").arg(addrText).arg(bp.logCondition));
exec(QString("SetHardwareBreakpointCommand %1, \"%2\"").arg(addrText).arg(bp.commandText));
exec(QString("SetHardwareBreakpointCommandCondition %1, \"%2\"").arg(addrText).arg(bp.commandCondition));
exec(QString("ResetHardwareBreakpointHitCount %1, %2").arg(addrText).arg(bp.hitCount));
exec(QString("ResetHardwareBreakpointHitCount %1, %2").arg(addrText).arg(ToPtrString(bp.hitCount)));
exec(QString("SetHardwareBreakpointFastResume %1, %2").arg(addrText).arg(bp.fastResume));
exec(QString("SetHardwareBreakpointSilent %1, %2").arg(addrText).arg(bp.silent));
exec(QString("SetHardwareBreakpointSingleshoot %1, %2").arg(addrText).arg(bp.singleshoot));
@ -455,11 +505,23 @@ void Breakpoints::editBP(BPXTYPE type, const QString & addrText, QWidget* widget
exec(QString("SetMemoryBreakpointLogCondition %1, \"%2\"").arg(addrText).arg(bp.logCondition));
exec(QString("SetMemoryBreakpointCommand %1, \"%2\"").arg(addrText).arg(bp.commandText));
exec(QString("SetMemoryBreakpointCommandCondition %1, \"%2\"").arg(addrText).arg(bp.commandCondition));
exec(QString("ResetMemoryBreakpointHitCount %1, %2").arg(addrText).arg(bp.hitCount));
exec(QString("ResetMemoryBreakpointHitCount %1, %2").arg(addrText).arg(ToPtrString(bp.hitCount)));
exec(QString("SetMemoryBreakpointFastResume %1, %2").arg(addrText).arg(bp.fastResume));
exec(QString("SetMemoryBreakpointSilent %1, %2").arg(addrText).arg(bp.silent));
exec(QString("SetMemoryBreakpointSingleshoot %1, %2").arg(addrText).arg(bp.singleshoot));
break;
case bp_dll:
exec(QString("SetLibrarianBreakpointName \"%1\", \"\"%2\"\"").arg(addrText).arg(bp.name));
exec(QString("SetLibrarianBreakpointCondition \"%1\", \"%2\"").arg(addrText).arg(bp.breakCondition));
exec(QString("SetLibrarianBreakpointLog \"%1\", \"%2\"").arg(addrText).arg(bp.logText));
exec(QString("SetLibrarianBreakpointLogCondition \"%1\", \"%2\"").arg(addrText).arg(bp.logCondition));
exec(QString("SetLibrarianBreakpointCommand \"%1\", \"%2\"").arg(addrText).arg(bp.commandText));
exec(QString("SetLibrarianBreakpointCommandCondition \"%1\", \"%2\"").arg(addrText).arg(bp.commandCondition));
exec(QString("ResetLibrarianBreakpointHitCount \"%1\", %2").arg(addrText).arg(ToPtrString(bp.hitCount)));
exec(QString("SetLibrarianBreakpointFastResume \"%1\", %2").arg(addrText).arg(bp.fastResume));
exec(QString("SetLibrarianBreakpointSilent \"%1\", %2").arg(addrText).arg(bp.silent));
exec(QString("SetLibrarianBreakpointSingleshoot \"%1\", %2").arg(addrText).arg(bp.singleshoot));
break;
default:
return;
}

View File

@ -24,8 +24,10 @@ public:
static void disableBP(BPXTYPE type, duint va);
static void removeBP(const BRIDGEBP & bp);
static void removeBP(BPXTYPE type, duint va);
static void removeBP(const QString & DLLName);
static void toggleBPByDisabling(const BRIDGEBP & bp);
static void toggleBPByDisabling(BPXTYPE type, duint va);
static void toggleBPByDisabling(const QString & DLLName);
static void toggleAllBP(BPXTYPE type, bool bEnable);
static void toggleBPByRemoving(BPXTYPE type, duint va);
static BPXSTATE BPState(BPXTYPE type, duint va);

View File

@ -218,6 +218,7 @@ Configuration::Configuration() : QObject(), noMoreMsgbox(false)
AbstractTableView::setupColumnConfigDefaultValue(guiUint, "SoftwareBreakpoint", 10);
AbstractTableView::setupColumnConfigDefaultValue(guiUint, "HardwareBreakpoint", 10);
AbstractTableView::setupColumnConfigDefaultValue(guiUint, "MemoryBreakpoint", 10);
AbstractTableView::setupColumnConfigDefaultValue(guiUint, "DLLBreakpoint", 8);
AbstractTableView::setupColumnConfigDefaultValue(guiUint, "MemoryMap", 7);
AbstractTableView::setupColumnConfigDefaultValue(guiUint, "CallStack", 4);
AbstractTableView::setupColumnConfigDefaultValue(guiUint, "SEH", 4);