1
0
Fork 0

DBG: fixed various bugs and annoyances with breakpoints (there should now be full control even with 'inactive' breakpoints)

This commit is contained in:
mrexodia 2016-03-20 01:09:43 +01:00
parent 292f6a2067
commit c3f13061c2
5 changed files with 55 additions and 26 deletions

View File

@ -620,18 +620,14 @@ extern "C" DLL_EXPORT int _dbg_getbplist(BPXTYPE type, BPMAP* bpmap)
}
curBp.addr = list[i].addr;
curBp.enabled = list[i].enabled;
//TODO: fix this
if(MemIsValidReadPtr(curBp.addr))
curBp.active = true;
curBp.active = list[i].active;
strcpy_s(curBp.mod, list[i].mod);
strcpy_s(curBp.name, list[i].name);
curBp.singleshoot = list[i].singleshoot;
curBp.slot = slot;
if(curBp.active)
{
bridgeList.push_back(curBp);
retcount++;
}
bridgeList.push_back(curBp);
retcount++;
}
if(!retcount)
{

View File

@ -12,6 +12,14 @@
typedef std::pair<BP_TYPE, duint> BreakpointKey;
std::map<BreakpointKey, BREAKPOINT> breakpoints;
static void setBpActive(BREAKPOINT & bp)
{
if(bp.type == BPHARDWARE) //TODO: properly implement this (check debug registers)
bp.active = true;
else
bp.active = MemIsValidReadPtr(bp.addr);
}
BREAKPOINT* BpInfoFromAddr(BP_TYPE Type, duint Address)
{
//
@ -39,7 +47,7 @@ int BpGetList(std::vector<BREAKPOINT>* List)
{
BREAKPOINT currentBp = i.second;
currentBp.addr += ModBaseFromName(currentBp.mod);
currentBp.active = MemIsValidReadPtr(currentBp.addr);
setBpActive(currentBp);
List->push_back(currentBp);
}
@ -105,7 +113,7 @@ bool BpGet(duint Address, BP_TYPE Type, const char* Name, BREAKPOINT* Bp)
*Bp = *bpInfo;
Bp->addr += ModBaseFromAddr(Address);
Bp->active = MemIsValidReadPtr(Bp->addr);
setBpActive(*Bp);
return true;
}
@ -121,7 +129,7 @@ bool BpGet(duint Address, BP_TYPE Type, const char* Name, BREAKPOINT* Bp)
{
*Bp = i.second;
Bp->addr += ModBaseFromAddr(Address);
Bp->active = MemIsValidReadPtr(Bp->addr);
setBpActive(*Bp);
}
// Return true if the name was found at all
@ -210,7 +218,7 @@ bool BpEnumAll(BPENUMCALLBACK EnumCallback, const char* Module)
++i; // Increment here, because the callback might remove the current entry
// If a module name was sent, check it
if(Module && Module[0] != '\0')
if(Module)
{
if(strcmp(j->second.mod, Module) != 0)
continue;
@ -218,7 +226,7 @@ bool BpEnumAll(BPENUMCALLBACK EnumCallback, const char* Module)
BREAKPOINT bpInfo = j->second;
bpInfo.addr += ModBaseFromName(bpInfo.mod);
bpInfo.active = MemIsValidReadPtr(bpInfo.addr);
setBpActive(bpInfo);
// Lock must be released due to callback sub-locks
SHARED_RELEASE();
@ -356,27 +364,25 @@ void BpCacheLoad(JSON Root)
BREAKPOINT breakpoint;
memset(&breakpoint, 0, sizeof(BREAKPOINT));
breakpoint.type = (BP_TYPE)json_integer_value(json_object_get(value, "type"));
if(breakpoint.type == BPNORMAL)
breakpoint.oldbytes = (unsigned short)(json_hex_value(json_object_get(value, "oldbytes")) & 0xFFFF);
breakpoint.type = (BP_TYPE)json_integer_value(json_object_get(value, "type"));
breakpoint.addr = (duint)json_hex_value(json_object_get(value, "address"));
breakpoint.enabled = json_boolean_value(json_object_get(value, "enabled"));
breakpoint.titantype = (DWORD)json_hex_value(json_object_get(value, "titantype"));
// Name
const char* name = json_string_value(json_object_get(value, "name"));
if(name)
strcpy_s(breakpoint.name, name);
// Module
const char* mod = json_string_value(json_object_get(value, "module"));
if(mod && *mod && strlen(mod) < MAX_MODULE_SIZE)
strcpy_s(breakpoint.mod, mod);
// Build the hash map key: MOD_HASH + ADDRESS
const duint key = ModHashFromName(breakpoint.mod) + breakpoint.addr;
duint key = ModHashFromName(breakpoint.mod) + breakpoint.addr;
breakpoints.insert(std::make_pair(BreakpointKey(breakpoint.type, key), breakpoint));
}
}

View File

@ -571,6 +571,8 @@ bool cbSetModuleBreakpoints(const BREAKPOINT* bp)
BpSetTitanType(bp->addr, BPHARDWARE, titantype);
if(!SetHardwareBreakPoint(bp->addr, drx, TITANGETTYPE(bp->titantype), TITANGETSIZE(bp->titantype), (void*)cbHardwareBreakpoint))
dprintf("Could not set hardware breakpoint " fhex "! (SetHardwareBreakPoint)\n", bp->addr);
else
dprintf("Set hardware breakpoint on " fhex "!\n", bp->addr);
}
break;
@ -690,6 +692,7 @@ static void cbCreateProcess(CREATE_PROCESS_DEBUG_INFO* CreateProcessInfo)
char modname[256] = "";
if(ModNameFromAddr((duint)base, modname, true))
BpEnumAll(cbSetModuleBreakpoints, modname);
BpEnumAll(cbSetModuleBreakpoints, "");
GuiUpdateBreakpointsView();
pCreateProcessBase = (duint)CreateProcessInfo->lpBaseOfImage;
if(!bFileIsDll && !bIsAttached) //Set entry breakpoint
@ -1175,6 +1178,8 @@ bool cbEnableAllBreakpoints(const BREAKPOINT* bp)
}
if(!SetBPX(bp->addr, bp->titantype, (void*)cbUserBreakpoint))
{
if(!MemIsValidReadPtr(bp->addr))
return true;
dprintf("Could not enable breakpoint " fhex " (SetBPX)\n", bp->addr);
return false;
}
@ -1776,6 +1781,7 @@ static void debugLoopFunction(void* lpParameter, bool attach)
ThreadClear();
SymClearMemoryCache();
GuiSetDebugState(stopped);
GuiUpdateAllViews();
dputs("Debugging stopped!");
varset("$hp", (duint)0, true);
varset("$pid", (duint)0, true);

View File

@ -252,13 +252,15 @@ CMDRESULT cbDebugSetBPX(int argc, char* argv[]) //bp addr [,name [,type]]
dprintf("Error setting breakpoint at " fhex "! (bpnew)\n", addr);
return STATUS_ERROR;
}
else if(!SetBPX(addr, type, (void*)cbUserBreakpoint))
GuiUpdateAllViews();
if(!SetBPX(addr, type, (void*)cbUserBreakpoint))
{
if(!MemIsValidReadPtr(addr))
return STATUS_CONTINUE;
dprintf("Error setting breakpoint at " fhex "! (SetBPX)\n", addr);
return STATUS_ERROR;
}
dprintf("Breakpoint at " fhex " set!\n", addr);
GuiUpdateAllViews();
return STATUS_CONTINUE;
}
@ -290,8 +292,10 @@ CMDRESULT cbDebugDeleteBPX(int argc, char* argv[])
}
else if(found.enabled && !DeleteBPX(found.addr))
{
dprintf("Delete breakpoint failed (DeleteBPX): " fhex "\n", found.addr);
GuiUpdateAllViews();
if(!MemIsValidReadPtr(found.addr))
return STATUS_CONTINUE;
dprintf("Delete breakpoint failed (DeleteBPX): " fhex "\n", found.addr);
return STATUS_ERROR;
}
return STATUS_CONTINUE;
@ -309,8 +313,10 @@ CMDRESULT cbDebugDeleteBPX(int argc, char* argv[])
}
else if(found.enabled && !DeleteBPX(found.addr))
{
dprintf("Delete breakpoint failed (DeleteBPX): " fhex "\n", found.addr);
GuiUpdateAllViews();
if(!MemIsValidReadPtr(found.addr))
return STATUS_CONTINUE;
dprintf("Delete breakpoint failed (DeleteBPX): " fhex "\n", found.addr);
return STATUS_ERROR;
}
dputs("Breakpoint deleted!");
@ -341,12 +347,14 @@ CMDRESULT cbDebugEnableBPX(int argc, char* argv[])
dprintf("Could not enable breakpoint " fhex " (BpEnable)\n", found.addr);
return STATUS_ERROR;
}
GuiUpdateAllViews();
if(!SetBPX(found.addr, found.titantype, (void*)cbUserBreakpoint))
{
if(!MemIsValidReadPtr(found.addr))
return STATUS_CONTINUE;
dprintf("Could not enable breakpoint " fhex " (SetBPX)\n", found.addr);
return STATUS_ERROR;
}
GuiUpdateAllViews();
return STATUS_CONTINUE;
}
duint addr = 0;
@ -366,13 +374,15 @@ CMDRESULT cbDebugEnableBPX(int argc, char* argv[])
dprintf("Could not enable breakpoint " fhex " (BpEnable)\n", found.addr);
return STATUS_ERROR;
}
GuiUpdateAllViews();
if(!SetBPX(found.addr, found.titantype, (void*)cbUserBreakpoint))
{
if(!MemIsValidReadPtr(found.addr))
return STATUS_CONTINUE;
dprintf("Could not enable breakpoint " fhex " (SetBPX)\n", found.addr);
return STATUS_ERROR;
}
dputs("Breakpoint enabled!");
GuiUpdateAllViews();
return STATUS_CONTINUE;
}
@ -401,6 +411,9 @@ CMDRESULT cbDebugDisableBPX(int argc, char* argv[])
}
if(!DeleteBPX(found.addr))
{
GuiUpdateAllViews();
if(!MemIsValidReadPtr(found.addr))
return STATUS_CONTINUE;
dprintf("Could not disable breakpoint " fhex " (DeleteBPX)\n", found.addr);
return STATUS_ERROR;
}
@ -425,6 +438,9 @@ CMDRESULT cbDebugDisableBPX(int argc, char* argv[])
}
if(!DeleteBPX(found.addr))
{
GuiUpdateAllViews();
if(!MemIsValidReadPtr(found.addr))
return STATUS_CONTINUE;
dprintf("Could not disable breakpoint " fhex " (DeleteBPX)\n", found.addr);
return STATUS_ERROR;
}

View File

@ -264,15 +264,20 @@ duint ModHashFromName(const char* Module)
{
// return MODINFO.hash (based on the name)
ASSERT_NONNULL(Module);
ASSERT_FALSE(Module[0] == '\0');
auto len = int(strlen(Module));
if(!len)
return 0;
return murmurhash(Module, (int)strlen(Module));
return murmurhash(Module, len);
}
duint ModBaseFromName(const char* Module)
{
ASSERT_NONNULL(Module);
ASSERT_TRUE(strlen(Module) < MAX_MODULE_SIZE);
auto len = int(strlen(Module));
if(!len)
return 0;
ASSERT_TRUE(len < MAX_MODULE_SIZE);
SHARED_ACQUIRE(LockModules);
for(const auto & i : modinfo)