1
0
Fork 0

BRIDGE+DBG+GUI: reduced the code for conditional breakpoints + added commandCondition and logCondition (when not set the behavior stays the same as before)

This commit is contained in:
mrexodia 2016-05-23 03:29:52 +02:00
parent 40555f1fb9
commit 490b0ff878
9 changed files with 373 additions and 460 deletions

View File

@ -62,7 +62,7 @@ BRIDGE_IMPEXP int BridgeGetDbgVersion();
#define MAX_IMPORT_SIZE 65536
#define MAX_BREAKPOINT_SIZE 256
#define MAX_CONDITIONAL_EXPR_SIZE 256
#define MAX_CONDITIONAL_LOG_SIZE 256
#define MAX_CONDITIONAL_TEXT_SIZE 256
#define MAX_SCRIPT_LINE_SIZE 2048
#define MAX_THREAD_NAME_SIZE 256
#define MAX_STRING_SIZE 512
@ -326,9 +326,11 @@ typedef struct
// extended part
unsigned int hitCount;
bool fastResume;
char condition[MAX_CONDITIONAL_EXPR_SIZE];
char log[MAX_CONDITIONAL_LOG_SIZE];
char hitCmd[MAX_CONDITIONAL_EXPR_SIZE];
char breakCondition[MAX_CONDITIONAL_EXPR_SIZE];
char logText[MAX_CONDITIONAL_TEXT_SIZE];
char logCondition[MAX_CONDITIONAL_EXPR_SIZE];
char commandText[MAX_CONDITIONAL_EXPR_SIZE];
char commandCondition[MAX_CONDITIONAL_TEXT_SIZE];
} BRIDGEBP;
typedef struct

View File

@ -217,18 +217,18 @@ bool BpSetTitanType(duint Address, BP_TYPE Type, int TitanType)
return true;
}
bool BpSetCondition(duint Address, BP_TYPE Type, const char* Condition)
bool BpSetBreakCondition(duint Address, BP_TYPE Type, const char* Condition)
{
ASSERT_DEBUGGING("Command function call");
EXCLUSIVE_ACQUIRE(LockBreakpoints);
// Set breakpoint condition
// Set breakpoint breakCondition
BREAKPOINT* bpInfo = BpInfoFromAddr(Type, Address);
if(!bpInfo)
return false;
strcpy_s(bpInfo->condition, Condition);
strcpy_s(bpInfo->breakCondition, Condition);
return true;
}
@ -237,17 +237,32 @@ bool BpSetLogText(duint Address, BP_TYPE Type, const char* Log)
ASSERT_DEBUGGING("Command function call");
EXCLUSIVE_ACQUIRE(LockBreakpoints);
// Set breakpoint log
// Set breakpoint logText
BREAKPOINT* bpInfo = BpInfoFromAddr(Type, Address);
if(!bpInfo)
return false;
strcpy_s(bpInfo->logText, MAX_CONDITIONAL_LOG_SIZE, Log);
strcpy_s(bpInfo->logText, Log);
return true;
}
bool BpSetHitCommand(duint Address, BP_TYPE Type, const char* Cmd)
bool BpSetLogCondition(duint Address, BP_TYPE Type, const char* Condition)
{
ASSERT_DEBUGGING("Command function call");
EXCLUSIVE_ACQUIRE(LockBreakpoints);
// Set breakpoint logText
BREAKPOINT* bpInfo = BpInfoFromAddr(Type, Address);
if(!bpInfo)
return false;
strcpy_s(bpInfo->logCondition, Condition);
return true;
}
bool BpSetCommandText(duint Address, BP_TYPE Type, const char* Cmd)
{
ASSERT_DEBUGGING("Command function call");
EXCLUSIVE_ACQUIRE(LockBreakpoints);
@ -258,7 +273,22 @@ bool BpSetHitCommand(duint Address, BP_TYPE Type, const char* Cmd)
if(!bpInfo)
return false;
strcpy_s(bpInfo->hitcmd, MAX_CONDITIONAL_EXPR_SIZE, Cmd);
strcpy_s(bpInfo->commandText, Cmd);
return true;
}
bool BpSetCommandCondition(duint Address, BP_TYPE Type, const char* Condition)
{
ASSERT_DEBUGGING("Command function call");
EXCLUSIVE_ACQUIRE(LockBreakpoints);
// Set breakpoint hit command
BREAKPOINT* bpInfo = BpInfoFromAddr(Type, Address);
if(!bpInfo)
return false;
strcpy_s(bpInfo->commandCondition, Condition);
return true;
}
@ -381,9 +411,11 @@ void BpToBridge(const BREAKPOINT* Bp, BRIDGEBP* BridgeBp)
memset(BridgeBp, 0, sizeof(BRIDGEBP));
strcpy_s(BridgeBp->mod, Bp->mod);
strcpy_s(BridgeBp->name, Bp->name);
strcpy_s(BridgeBp->condition, Bp->condition);
strcpy_s(BridgeBp->log, Bp->logText);
strcpy_s(BridgeBp->hitCmd, Bp->hitcmd);
strcpy_s(BridgeBp->breakCondition, Bp->breakCondition);
strcpy_s(BridgeBp->logText, Bp->logText);
strcpy_s(BridgeBp->logCondition, Bp->logCondition);
strcpy_s(BridgeBp->commandText, Bp->commandText);
strcpy_s(BridgeBp->commandCondition, Bp->commandCondition);
BridgeBp->active = Bp->active;
BridgeBp->addr = Bp->addr;
@ -452,10 +484,12 @@ void BpCacheSave(JSON Root)
json_object_set_new(jsonObj, "titantype", json_hex(breakpoint.titantype));
json_object_set_new(jsonObj, "name", json_string(breakpoint.name));
json_object_set_new(jsonObj, "module", json_string(breakpoint.mod));
json_object_set_new(jsonObj, "condition", json_string(breakpoint.condition));
json_object_set_new(jsonObj, "log", json_string(breakpoint.logText));
json_object_set_new(jsonObj, "hitcommand", json_string(breakpoint.hitcmd));
json_object_set_new(jsonObj, "fastresume", json_boolean(breakpoint.fastResume));
json_object_set_new(jsonObj, "breakCondition", json_string(breakpoint.breakCondition));
json_object_set_new(jsonObj, "logText", json_string(breakpoint.logText));
json_object_set_new(jsonObj, "logCondition", json_string(breakpoint.logCondition));
json_object_set_new(jsonObj, "commandText", json_string(breakpoint.commandText));
json_object_set_new(jsonObj, "commandCondition", json_string(breakpoint.commandCondition));
json_object_set_new(jsonObj, "fastResume", json_boolean(breakpoint.fastResume));
json_array_append_new(jsonBreakpoints, jsonObj);
}
@ -466,6 +500,14 @@ void BpCacheSave(JSON Root)
json_decref(jsonBreakpoints);
}
template<typename T>
static void loadStringValue(JSON value, T dest, const char* key)
{
auto text = json_string_value(json_object_get(value, key));
if(text)
strcpy_s(dest, _TRUNCATE, text);
}
void BpCacheLoad(JSON Root)
{
EXCLUSIVE_ACQUIRE(LockBreakpoints);
@ -494,33 +536,17 @@ void BpCacheLoad(JSON Root)
breakpoint.enabled = json_boolean_value(json_object_get(value, "enabled"));
breakpoint.titantype = (DWORD)json_hex_value(json_object_get(value, "titantype"));
// Name
const char* text = json_string_value(json_object_get(value, "name"));
if(text)
strcpy_s(breakpoint.name, text);
// 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);
// Condition
text = json_string_value(json_object_get(value, "condition"));
if(text)
strcpy_s(breakpoint.condition, text);
// Log string
text = json_string_value(json_object_get(value, "log"));
if(text)
strcpy_s(breakpoint.logText, text);
// Hit command
text = json_string_value(json_object_get(value, "hitcommand"));
if(text)
strcpy_s(breakpoint.hitcmd, text);
// String values
loadStringValue(value, breakpoint.name, "name");
loadStringValue(value, breakpoint.mod, "module");
loadStringValue(value, breakpoint.breakCondition, "breakCondition");
loadStringValue(value, breakpoint.logText, "logText");
loadStringValue(value, breakpoint.logCondition, "logCondition");
loadStringValue(value, breakpoint.commandText, "commandText");
loadStringValue(value, breakpoint.commandCondition, "commandCondition");
// Fast resume
breakpoint.fastResume = json_boolean_value(json_object_get(value, "fastresume"));
breakpoint.fastResume = json_boolean_value(json_object_get(value, "fastResume"));
// Build the hash map key: MOD_HASH + ADDRESS
duint key = ModHashFromName(breakpoint.mod) + breakpoint.addr;

View File

@ -19,20 +19,22 @@ enum BP_TYPE
struct BREAKPOINT
{
duint addr;
bool enabled;
bool singleshoot;
bool active;
unsigned short oldbytes;
BP_TYPE type;
DWORD titantype;
char name[MAX_BREAKPOINT_SIZE];
char mod[MAX_MODULE_SIZE];
char condition[MAX_CONDITIONAL_EXPR_SIZE]; // condition to stop. If true, debugger halts.
char logText[MAX_CONDITIONAL_LOG_SIZE]; // text to log.
char hitcmd[MAX_CONDITIONAL_EXPR_SIZE]; // script command to execute.
uint32 hitcount; // hit counter
bool fastResume; // if true, debugger resumes without any GUI/Script/Plugin interaction.
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
unsigned short oldbytes; // original bytes (for software breakpoitns)
BP_TYPE type; // breakpoint type
DWORD titantype; // type passed to titanengine
char name[MAX_BREAKPOINT_SIZE]; // breakpoint name
char mod[MAX_MODULE_SIZE]; // module name
char breakCondition[MAX_CONDITIONAL_EXPR_SIZE]; // condition to stop. If true, debugger halts.
char logText[MAX_CONDITIONAL_TEXT_SIZE]; // text to log.
char logCondition[MAX_CONDITIONAL_EXPR_SIZE]; // condition to log
char commandText[MAX_CONDITIONAL_TEXT_SIZE]; // script command to execute.
char commandCondition[MAX_CONDITIONAL_EXPR_SIZE]; // condition to execute the command
uint32 hitcount; // hit counter
bool fastResume; // if true, debugger resumes without any GUI/Script/Plugin interaction.
};
// Breakpoint enumeration callback
@ -47,9 +49,11 @@ 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 BpSetCondition(duint Address, BP_TYPE Type, const char* Condition);
bool BpSetBreakCondition(duint Address, BP_TYPE Type, const char* Condition);
bool BpSetLogText(duint Address, BP_TYPE Type, const char* Log);
bool BpSetHitCommand(duint Address, BP_TYPE Type, const char* Cmd);
bool BpSetLogCondition(duint Address, BP_TYPE Type, const char* Condition);
bool BpSetCommandText(duint Address, BP_TYPE Type, const char* Cmd);
bool BpSetCommandCondition(duint Address, BP_TYPE Type, const char* Condition);
bool BpSetFastResume(duint Address, BP_TYPE Type, bool fastResume);
bool BpEnumAll(BPENUMCALLBACK EnumCallback, const char* Module);
bool BpEnumAll(BPENUMCALLBACK EnumCallback);

View File

@ -270,39 +270,6 @@ void DebugUpdateStack(duint dumpAddr, duint csp, bool forceDump)
GuiStackDumpAt(dumpAddr, csp);
}
void BreakpointProlog(duint condition, BREAKPOINT & bp, PLUG_CB_BREAKPOINT & bpInfo)
{
// update GUI
if(condition != 0)
{
GuiSetDebugState(paused);
DebugUpdateGui(GetContextDataEx(hActiveThread, UE_CIP), true);
}
// plugin interaction
lock(WAITID_RUN);
PLUG_CB_PAUSEDEBUG pauseInfo;
memset(&pauseInfo, 0, sizeof(pauseInfo));
plugincbcall(CB_PAUSEDEBUG, &pauseInfo);
plugincbcall(CB_BREAKPOINT, &bpInfo);
// conditional
if(bp.logText[0] != 0)
{
dprintf("%s\n", stringformatinline(bp.logText).c_str());
}
if(bp.hitcmd[0] != 0 && condition != 0)
{
DbgCmdExec(bp.hitcmd);
}
if(condition == 0)
{
unlock(WAITID_RUN);
SetForegroundWindow(GuiGetWindowHandle());
bSkipExceptions = false;
}
//lock
wait(WAITID_RUN);
}
static void printSoftBpInfo(const BREAKPOINT & bp)
{
auto bptype = "INT3";
@ -414,158 +381,164 @@ static void printMemBpInfo(const BREAKPOINT & bp, const void* ExceptionAddress)
}
}
void cbUserBreakpoint()
static bool getConditionValue(const char* expression)
{
auto word = *(uint16*)expression;
if(word == '0') // short circuit for condition "0\0"
return false;
if(word == '1') //short circuit for condition "1\0"
return true;
duint value;
if(valfromstring(expression, &value))
return value != 0;
return true;
}
static void getConditionValues(const BREAKPOINT & bp, bool & breakCondition, bool & logCondition, bool & commandCondition)
{
if(*bp.breakCondition)
breakCondition = getConditionValue(bp.breakCondition);
else
breakCondition = true; //break if no condition is set
if(*bp.logCondition)
logCondition = getConditionValue(bp.logCondition);
else
logCondition = true; //log if no condition is set
if(*bp.commandCondition)
commandCondition = getConditionValue(bp.commandCondition);
else
commandCondition = breakCondition; //if no condition is set, execute the command when the debugger would break
}
static void BreakpointProlog(BREAKPOINT & bp, bool breakCondition, bool logCondition, bool commandCondition)
{
// update GUI
if(breakCondition)
{
GuiSetDebugState(paused);
DebugUpdateGui(GetContextDataEx(hActiveThread, UE_CIP), true);
}
// plugin interaction
lock(WAITID_RUN);
PLUG_CB_PAUSEDEBUG pauseInfo;
pauseInfo.reserved = nullptr;
plugincbcall(CB_PAUSEDEBUG, &pauseInfo);
PLUG_CB_BREAKPOINT bpInfo;
BRIDGEBP bridgebp;
bpInfo.breakpoint = &bridgebp;
memset(&bpInfo, 0, sizeof(bpInfo));
BpToBridge(&bp, &bridgebp);
plugincbcall(CB_BREAKPOINT, &bpInfo);
if(*bp.logText && logCondition) //log
{
dprintf("%s\n", stringformatinline(bp.logText).c_str());
}
if(*bp.commandText && commandCondition) //command
{
//TODO: commands like run/step etc will fuck up your shit
DbgCmdExec(bp.commandText);
}
if(breakCondition) //break the debugger
{
SetForegroundWindow(GuiGetWindowHandle());
bSkipExceptions = false;
}
else //resume immediately
unlock(WAITID_RUN);
//wait until the user resumes
wait(WAITID_RUN);
}
static void cbGenericBreakpoint(BP_TYPE bptype, void* ExceptionAddress = nullptr)
{
hActiveThread = ThreadGetHandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
BREAKPOINT* bpPtr;
BREAKPOINT bp;
BRIDGEBP pluginBp;
PLUG_CB_BREAKPOINT bpInfo;
ULONG_PTR CIP;
duint condition = 1;
memset(&bpInfo, 0, sizeof(bpInfo));
CIP = GetContextDataEx(hActiveThread, UE_CIP);
auto CIP = GetContextDataEx(hActiveThread, UE_CIP);
BREAKPOINT* bpPtr = nullptr;
SHARED_ACQUIRE(LockBreakpoints);
bpPtr = BpInfoFromAddr(BPNORMAL, CIP);
if(!(bpPtr && bpPtr->enabled))
dputs("Breakpoint reached not in list!");
else
switch(bptype)
{
// increment hit count
InterlockedIncrement(&bpPtr->hitcount);
// condition eval
bp = *bpPtr;
SHARED_RELEASE();
bp.addr += ModBaseFromAddr(CIP);
//setBpActive(bp);
//if(bp.type == BPHARDWARE) //TODO: properly implement this (check debug registers)
// bp.active = true;
//else
bp.active = MemIsValidReadPtr(bp.addr);
if(bp.condition[0] != 0)
{
if(*(uint16*)bp.condition == 0x30) // short curcit for condition "0"
condition = 0;
else
valfromstring(bp.condition, &condition); // if this fails, condition remains 1
if(bp.fastResume && condition == 0) // fast resume : ignore GUI/Script/Plugin/Singleshoot/Other
return;
}
if(bp.logText[0] == 0 && condition != 0)
{
printSoftBpInfo(bp);
} // else: BreakpointProlog outputs the log.
if(bp.singleshoot)
BpDelete(bp.addr, BPNORMAL);
BpToBridge(&bp, &pluginBp);
bpInfo.breakpoint = &pluginBp;
case BPNORMAL:
bpPtr = BpInfoFromAddr(bptype, CIP);
break;
case BPHARDWARE:
bpPtr = BpInfoFromAddr(bptype, duint(ExceptionAddress));
break;
case BPMEMORY:
bpPtr = BpInfoFromAddr(bptype, MemFindBaseAddr(duint(ExceptionAddress), nullptr, true));
default:
break;
}
BreakpointProlog(condition, bp, bpInfo);
if(!(bpPtr && bpPtr->enabled)) //invalid / disabled breakpoint hit (most likely a bug)
{
dputs("Breakpoint reached not in list!");
GuiSetDebugState(paused);
DebugUpdateGui(GetContextDataEx(hActiveThread, UE_CIP), true);
//lock
lock(WAITID_RUN);
SetForegroundWindow(GuiGetWindowHandle());
bSkipExceptions = false;
PLUG_CB_PAUSEDEBUG pauseInfo;
pauseInfo.reserved = nullptr;
plugincbcall(CB_PAUSEDEBUG, &pauseInfo);
wait(WAITID_RUN);
return;
}
// increment hit count
InterlockedIncrement(&bpPtr->hitcount);
auto bp = *bpPtr;
SHARED_RELEASE();
bp.addr += ModBaseFromAddr(CIP);
bp.active = true; //a breakpoint that has been hit is active
//get condition values
bool breakCondition;
bool logCondition;
bool commandCondition;
getConditionValues(bp, breakCondition, logCondition, commandCondition);
if(breakCondition)
{
if(bp.singleshoot)
BpDelete(bp.addr, bptype);
switch(bptype)
{
case BPNORMAL:
printSoftBpInfo(bp);
break;
case BPHARDWARE:
printHwBpInfo(bp);
break;
case BPMEMORY:
printMemBpInfo(bp, ExceptionAddress);
break;
default:
break;
}
}
else if(bp.fastResume) // fast resume: ignore GUI/Script/Plugin/Other if the debugger would not break
return;
BreakpointProlog(bp, breakCondition, logCondition, commandCondition);
}
void cbUserBreakpoint()
{
cbGenericBreakpoint(BPNORMAL);
}
void cbHardwareBreakpoint(void* ExceptionAddress)
{
hActiveThread = ThreadGetHandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
BREAKPOINT* bpPtr;
BREAKPOINT bp;
BRIDGEBP pluginBp;
PLUG_CB_BREAKPOINT bpInfo;
ULONG_PTR CIP;
duint condition = 1;
memset(&bpInfo, 0, sizeof(bpInfo));
CIP = GetContextDataEx(hActiveThread, UE_CIP);
SHARED_ACQUIRE(LockBreakpoints);
bpPtr = BpInfoFromAddr(BPHARDWARE, (duint)ExceptionAddress);
if(!(bpPtr && bpPtr->enabled))
dputs("Hardware breakpoint reached not in list!");
else
{
// increment hit count
InterlockedIncrement(&bpPtr->hitcount);
// condition eval
bp = *bpPtr;
SHARED_RELEASE();
bp.addr += ModBaseFromAddr(CIP);
//setBpActive(bp);
//if(bp.type == BPHARDWARE) //TODO: properly implement this (check debug registers)
bp.active = true;
//else
// bp.active = MemIsValidReadPtr(bp.addr);
if(bp.condition[0] != 0)
{
if(*(uint16*)bp.condition == 0x30) // short curcit for condition "0"
condition = 0;
else
valfromstring(bp.condition, &condition); // if this fails, condition remains 1
if(bp.fastResume && condition == 0) // fast resume : ignore GUI/Script/Plugin/Singleshoot/Other
return;
}
if(bp.logText[0] == 0 && condition != 0)
{
printHwBpInfo(bp);
} // else: BreakpointProlog outputs the log.
if(bp.singleshoot)
BpDelete(bp.addr, BPHARDWARE);
BpToBridge(&bp, &pluginBp);
bpInfo.breakpoint = &pluginBp;
}
BreakpointProlog(condition, bp, bpInfo);
cbGenericBreakpoint(BPHARDWARE, ExceptionAddress);
}
void cbMemoryBreakpoint(void* ExceptionAddress)
{
hActiveThread = ThreadGetHandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
BREAKPOINT bp;
BRIDGEBP pluginBp;
PLUG_CB_BREAKPOINT bpInfo;
duint size;
duint base = MemFindBaseAddr((duint)ExceptionAddress, &size, true);
ULONG_PTR CIP;
duint condition = 1;
memset(&bpInfo, 0, sizeof(bpInfo));
CIP = GetContextDataEx(hActiveThread, UE_CIP);
SHARED_ACQUIRE(LockBreakpoints);
auto bpPtr = BpInfoFromAddr(BPMEMORY, base);
if(!(bpPtr && bpPtr->enabled))
dputs("Memory breakpoint reached not in list!");
else
{
// increment hit count
InterlockedIncrement(&bpPtr->hitcount);
// condition eval
bp = *bpPtr;
SHARED_RELEASE();
bp.addr += ModBaseFromAddr(CIP);
//setBpActive(bp);
//if(bp.type == BPHARDWARE) //TODO: properly implement this (check debug registers)
// bp.active = true;
//else
bp.active = MemIsValidReadPtr(bp.addr);
if(bp.condition[0] != 0)
{
if(*(uint16*)bp.condition == 0x30) // short curcit for condition "0"
condition = 0;
else
valfromstring(bp.condition, &condition); // if this fails, condition remains 1
if(bp.fastResume && condition == 0) // fast resume : ignore GUI/Script/Plugin/Singleshoot/Other
return;
}
if(bp.logText[0] == 0 && condition != 0)
{
printMemBpInfo(bp, ExceptionAddress);
} // else: BreakpointProlog outputs the log.
BpToBridge(&bp, &pluginBp);
bpInfo.breakpoint = &pluginBp;
}
if(bp.singleshoot)
BpDelete(bp.addr, BPMEMORY); //delete from breakpoint list
BreakpointProlog(condition, bp, bpInfo);
cbGenericBreakpoint(BPMEMORY, ExceptionAddress);
}
void cbLibrarianBreakpoint(void* lpData)

View File

@ -115,7 +115,4 @@ extern char szSymbolCachePath[MAX_PATH];
extern bool bUndecorateSymbolNames;
extern bool bEnableSourceDebugging;
//private
void BreakpointProlog(duint condition, BREAKPOINT & bp, PLUG_CB_BREAKPOINT & bpInfo);
#endif // _DEBUGGER_H

View File

@ -445,8 +445,7 @@ CMDRESULT cbDebugDisableBPX(int argc, char* argv[])
return STATUS_CONTINUE;
}
CMDRESULT cbDebugSetBPXConditionCommon(BP_TYPE Type, int argc, char* argv[])
static CMDRESULT cbDebugSetBPXTextCommon(BP_TYPE Type, int argc, char* argv[], const char* description, std::function<bool(duint, BP_TYPE, const char*)> setFunction)
{
BREAKPOINT bp;
if(argc < 2)
@ -454,123 +453,94 @@ CMDRESULT cbDebugSetBPXConditionCommon(BP_TYPE Type, int argc, char* argv[])
dprintf("not enough arguments!\n");
return STATUS_ERROR;
}
else if(argc == 2)
auto value = "";
if(argc > 2)
value = argv[2];
if(!BpGetAny(Type, argv[1], &bp))
{
if(BpGetAny(Type, argv[1], &bp))
{
if(!BpSetCondition(bp.addr, Type, ""))
{
dprintf("Can't set condition on breakpoint \"%s\"\n", argv[1]);
return STATUS_ERROR;
}
return STATUS_CONTINUE;
}
else
{
dprintf("No such breakpoint \"%s\"\n", argv[1]);
return STATUS_ERROR;
}
dprintf("No such breakpoint \"%s\"\n", argv[1]);
return STATUS_ERROR;
}
else
if(!setFunction(bp.addr, Type, value))
{
if(BpGetAny(Type, argv[1], &bp))
{
BpSetCondition(bp.addr, Type, argv[2]);
return STATUS_CONTINUE;
}
else
{
dprintf("No such breakpoint \"%s\"\n", argv[1]);
return STATUS_ERROR;
}
dprintf("Can't set %s on breakpoint \"%s\"\n", description, argv[1]);
return STATUS_ERROR;
}
dprintf("%s set to \"%s\"!\n", description, value);
return STATUS_CONTINUE;
}
CMDRESULT cbDebugSetBPXConditionCommon(BP_TYPE Type, int argc, char* argv[])
{
return cbDebugSetBPXTextCommon(Type, argc, argv, "break condition", BpSetBreakCondition);
}
CMDRESULT cbDebugSetBPXLogCommon(BP_TYPE Type, int argc, char* argv[])
{
BREAKPOINT bp;
if(argc < 2)
{
dprintf("not enough arguments!\n");
return STATUS_ERROR;
}
else if(argc == 2)
{
if(BpGetAny(Type, argv[1], &bp))
{
if(!(BpSetLogText(bp.addr, Type, "")))
{
dprintf("Can't set logging text on breakpoint \"%s\"\n", argv[1]);
return STATUS_ERROR;
}
return STATUS_CONTINUE;
}
else
{
dprintf("No such breakpoint \"%s\"\n", argv[1]);
return STATUS_ERROR;
}
}
else
{
if(BpGetAny(Type, argv[1], &bp))
{
BpSetLogText(bp.addr, Type, argv[2]);
return STATUS_CONTINUE;
}
else
{
dprintf("No such breakpoint \"%s\"\n", argv[1]);
return STATUS_ERROR;
}
}
return cbDebugSetBPXTextCommon(Type, argc, argv, "logging text", BpSetLogText);
}
CMDRESULT cbDebugSetBPXLogConditionCommon(BP_TYPE Type, int argc, char* argv[])
{
return cbDebugSetBPXTextCommon(Type, argc, argv, "logging condition", BpSetLogCondition);
}
CMDRESULT cbDebugSetBPXCommandCommon(BP_TYPE Type, int argc, char* argv[])
{
BREAKPOINT bp;
return cbDebugSetBPXTextCommon(Type, argc, argv, "command on hit", BpSetCommandText);
}
CMDRESULT cbDebugSetBPXCommandConditionCommon(BP_TYPE Type, int argc, char* argv[])
{
return cbDebugSetBPXTextCommon(Type, argc, argv, "command condition", BpSetCommandCondition);
}
static CMDRESULT cbDebugGetBPXHitCountCommon(BP_TYPE Type, int argc, char* argv[])
{
if(argc < 2)
{
dprintf("not enough arguments!\n");
return STATUS_ERROR;
}
else if(argc == 2)
BREAKPOINT bp;
if(!BpGetAny(Type, argv[1], &bp))
{
if(BpGetAny(Type, argv[1], &bp))
{
if(!BpSetHitCommand(bp.addr, Type, ""))
{
dprintf("Can't set command on hit on breakpoint \"%s\"", argv[1]);
return STATUS_ERROR;
}
return STATUS_CONTINUE;
}
else
{
dprintf("No such breakpoint \"%s\"\n", argv[1]);
return STATUS_ERROR;
}
}
else
{
if(BpGetAny(Type, argv[1], &bp))
{
if(!(BpSetHitCommand(bp.addr, Type, argv[2])))
{
dprintf("Can't set command on hit on breakpoint \"%s\"", argv[1]);
return STATUS_ERROR;
}
return STATUS_CONTINUE;
}
else
{
dprintf("No such breakpoint \"%s\"\n", argv[1]);
return STATUS_ERROR;
}
dprintf("No such breakpoint \"%s\"\n", argv[1]);
return STATUS_ERROR;
}
varset("$result", bp.hitcount, false);
return STATUS_CONTINUE;
}
CMDRESULT cbDebugGetBPXHitCountCommon(BP_TYPE Type, int argc, char* argv[])
static CMDRESULT cbDebugResetBPXHitCountCommon(BP_TYPE Type, int argc, char* argv[])
{
if(argc < 2)
{
dprintf("not enough arguments!\n");
return STATUS_ERROR;
}
duint value = 0;
if(argc > 2)
if(!valfromstring(argv[2], &value, false))
return STATUS_ERROR;
BREAKPOINT bp;
if(!BpGetAny(Type, argv[1], &bp))
{
dprintf("No such breakpoint \"%s\"\n", argv[1]);
return STATUS_ERROR;
}
if(!BpResetHitCount(bp.addr, Type, (uint32)value))
{
dprintf("Can't set hit count on breakpoint \"%s\"", argv[1]);
return STATUS_ERROR;
}
return STATUS_CONTINUE;
}
static CMDRESULT cbDebugSetBPXFastResumeCommon(BP_TYPE Type, int argc, char* argv[])
{
BREAKPOINT bp;
if(argc < 2)
@ -578,129 +548,25 @@ CMDRESULT cbDebugGetBPXHitCountCommon(BP_TYPE Type, int argc, char* argv[])
dprintf("not enough arguments!\n");
return STATUS_ERROR;
}
else if(argc == 2)
{
duint result;
if(BpGetAny(Type, argv[1], &bp))
{
//result = BpGetHitCount(bp.addr, bp.type);
result = bp.hitcount; // improving performance
varset("$result", result, false);
return STATUS_CONTINUE;
}
else
{
dprintf("No such breakpoint \"%s\"\n", argv[1]);
return STATUS_ERROR;
}
}
else
{
dprintf("Too much arguments!\n");
return STATUS_ERROR;
}
}
CMDRESULT cbDebugResetBPXHitCountCommon(BP_TYPE Type, int argc, char* argv[])
{
BREAKPOINT bp;
if(argc < 2)
{
dprintf("not enough arguments!\n");
return STATUS_ERROR;
}
else if(argc == 2)
{
duint result;
if(BpGetAny(Type, argv[1], &bp))
{
result = BpResetHitCount(bp.addr, bp.type, 0);
return STATUS_CONTINUE;
}
else
{
dprintf("No such breakpoint \"%s\"\n", argv[1]);
return STATUS_ERROR;
}
}
else
auto fastResume = true;
if(argc > 2)
{
duint value;
if(!(valfromstring(argv[2], &value)))
{
dprintf("Invalid expression \"%1\"", argv[2]);
}
if(BpGetAny(Type, argv[1], &bp))
{
if(!(BpResetHitCount(bp.addr, Type, (uint32)value)))
{
dprintf("Can't set command on hit on breakpoint \"%s\"", argv[1]);
return STATUS_ERROR;
}
return STATUS_CONTINUE;
}
else
{
dprintf("No such breakpoint \"%s\"\n", argv[1]);
if(!valfromstring(argv[2], &value, false))
return STATUS_ERROR;
}
fastResume = value != 0;
}
}
CMDRESULT cbDebugSetBPXFastResumeCommon(BP_TYPE Type, int argc, char* argv[])
{
BREAKPOINT bp;
if(argc < 2)
if(!BpGetAny(Type, argv[1], &bp))
{
dprintf("not enough arguments!\n");
dprintf("No such breakpoint \"%s\"\n", argv[1]);
return STATUS_ERROR;
}
else if(argc == 2)
if(!BpSetFastResume(bp.addr, Type, fastResume))
{
duint value;
if(BpGetAny(Type, argv[1], &bp))
{
if(!valfromstring(argv[2], &value))
{
dprintf("Invalid expression \"%1\"", argv[2]);
return STATUS_ERROR;
}
if(!(BpSetFastResume(bp.addr, Type, true)))
{
dprintf("Can't set fast resume on breakpoint \"%1\"", argv[1]);
return STATUS_ERROR;
}
return STATUS_CONTINUE;
}
else
{
dprintf("No such breakpoint \"%s\"\n", argv[1]);
return STATUS_ERROR;
}
}
else
{
duint result;
if(!(valfromstring(argv[2], &result)))
{
dprintf("Invalid expression \"%1\"", argv[2]);
}
if(BpGetAny(Type, argv[1], &bp))
{
if(!(BpSetFastResume(bp.addr, Type, result != 0)))
{
dprintf("Can't set fast resume on breakpoint \"%1\"", argv[1]);
return STATUS_ERROR;
}
return STATUS_CONTINUE;
}
else
{
dprintf("No such breakpoint \"%s\"\n", argv[1]);
return STATUS_ERROR;
}
dprintf("Can't set fast resume on breakpoint \"%1\"", argv[1]);
return STATUS_ERROR;
}
return STATUS_CONTINUE;
}
CMDRESULT cbDebugSetBPXCondition(int argc, char* argv[])
@ -713,11 +579,21 @@ CMDRESULT cbDebugSetBPXLog(int argc, char* argv[])
return cbDebugSetBPXLogCommon(BPNORMAL, argc, argv);
}
CMDRESULT cbDebugSetBPXLogCondition(int argc, char* argv[])
{
return cbDebugSetBPXLogConditionCommon(BPNORMAL, argc, argv);
}
CMDRESULT cbDebugSetBPXCommand(int argc, char* argv[])
{
return cbDebugSetBPXCommandCommon(BPNORMAL, argc, argv);
}
CMDRESULT cbDebugSetBPXCommandCondition(int argc, char* argv[])
{
return cbDebugSetBPXCommandConditionCommon(BPNORMAL, argc, argv);
}
CMDRESULT cbDebugSetBPXFastResume(int argc, char* argv[])
{
return cbDebugSetBPXFastResumeCommon(BPNORMAL, argc, argv);
@ -743,11 +619,21 @@ CMDRESULT cbDebugSetBPXHardwareLog(int argc, char* argv[])
return cbDebugSetBPXLogCommon(BPHARDWARE, argc, argv);
}
CMDRESULT cbDebugSetBPXHardwareLogCondition(int argc, char* argv[])
{
return cbDebugSetBPXLogConditionCommon(BPHARDWARE, argc, argv);
}
CMDRESULT cbDebugSetBPXHardwareCommand(int argc, char* argv[])
{
return cbDebugSetBPXCommandCommon(BPHARDWARE, argc, argv);
}
CMDRESULT cbDebugSetBPXHardwareCommandCondition(int argc, char* argv[])
{
return cbDebugSetBPXCommandConditionCommon(BPHARDWARE, argc, argv);
}
CMDRESULT cbDebugSetBPXHardwareFastResume(int argc, char* argv[])
{
return cbDebugSetBPXFastResumeCommon(BPHARDWARE, argc, argv);
@ -773,11 +659,21 @@ CMDRESULT cbDebugSetBPXMemoryLog(int argc, char* argv[])
return cbDebugSetBPXLogCommon(BPMEMORY, argc, argv);
}
CMDRESULT cbDebugSetBPXMemoryLogCondition(int argc, char* argv[])
{
return cbDebugSetBPXLogConditionCommon(BPMEMORY, argc, argv);
}
CMDRESULT cbDebugSetBPXMemoryCommand(int argc, char* argv[])
{
return cbDebugSetBPXCommandCommon(BPMEMORY, argc, argv);
}
CMDRESULT cbDebugSetBPXMemoryCommandCondition(int argc, char* argv[])
{
return cbDebugSetBPXCommandConditionCommon(BPMEMORY, argc, argv);
}
CMDRESULT cbDebugResetBPXMemoryHitCount(int argc, char* argv[])
{
return cbDebugSetBPXFastResumeCommon(BPMEMORY, argc, argv);
@ -792,6 +688,7 @@ CMDRESULT cbDebugGetBPXMemoryHitCount(int argc, char* argv[])
{
return cbDebugGetBPXHitCountCommon(BPMEMORY, argc, argv);
}
CMDRESULT cbDebugSetHardwareBreakpoint(int argc, char* argv[])
{
if(argc < 2)

View File

@ -16,7 +16,9 @@ CMDRESULT cbDebugEnableBPX(int argc, char* argv[]);
CMDRESULT cbDebugDisableBPX(int argc, char* argv[]);
CMDRESULT cbDebugSetBPXCondition(int argc, char* argv[]);
CMDRESULT cbDebugSetBPXLog(int argc, char* argv[]);
CMDRESULT cbDebugSetBPXLogCondition(int argc, char* argv[]);
CMDRESULT cbDebugSetBPXCommand(int argc, char* argv[]);
CMDRESULT cbDebugSetBPXCommandCondition(int argc, char* argv[]);
CMDRESULT cbDebugGetBPXHitCount(int argc, char* argv[]);
CMDRESULT cbDebugSetBPXFastResume(int argc, char* argv[]);
CMDRESULT cbDebugResetBPXHitCount(int argc, char* argv[]);
@ -26,7 +28,9 @@ CMDRESULT cbDebugEnableHardwareBreakpoint(int argc, char* argv[]);
CMDRESULT cbDebugDisableHardwareBreakpoint(int argc, char* argv[]);
CMDRESULT cbDebugSetBPXHardwareCondition(int argc, char* argv[]);
CMDRESULT cbDebugSetBPXHardwareLog(int argc, char* argv[]);
CMDRESULT cbDebugSetBPXHardwareLogCondition(int argc, char* argv[]);
CMDRESULT cbDebugSetBPXHardwareCommand(int argc, char* argv[]);
CMDRESULT cbDebugSetBPXHardwareCommandCondition(int argc, char* argv[]);
CMDRESULT cbDebugGetBPXHardwareHitCount(int argc, char* argv[]);
CMDRESULT cbDebugSetBPXHardwareFastResume(int argc, char* argv[]);
CMDRESULT cbDebugResetBPXHardwareHitCount(int argc, char* argv[]);
@ -36,7 +40,9 @@ CMDRESULT cbDebugEnableMemoryBreakpoint(int argc, char* argv[]);
CMDRESULT cbDebugDisableMemoryBreakpoint(int argc, char* argv[]);
CMDRESULT cbDebugSetBPXMemoryCondition(int argc, char* argv[]);
CMDRESULT cbDebugSetBPXMemoryLog(int argc, char* argv[]);
CMDRESULT cbDebugSetBPXMemoryLogCondition(int argc, char* argv[]);
CMDRESULT cbDebugSetBPXMemoryCommand(int argc, char* argv[]);
CMDRESULT cbDebugSetBPXMemoryCommandCondition(int argc, char* argv[]);
CMDRESULT cbDebugGetBPXMemoryHitCount(int argc, char* argv[]);
CMDRESULT cbDebugSetBPXMemoryFastResume(int argc, char* argv[]);
CMDRESULT cbDebugResetBPXMemoryHitCount(int argc, char* argv[]);

View File

@ -124,21 +124,29 @@ static void registercommands()
dbgcmdnew("DeleteMemoryBPX\1membpc\1bpmc", cbDebugDeleteMemoryBreakpoint, true); //delete memory breakpoint
dbgcmdnew("EnableMemoryBreakpoint\1membpe\1bpme", cbDebugEnableMemoryBreakpoint, true); //enable memory breakpoint
dbgcmdnew("DisableMemoryBreakpoint\1membpd\1bpmd", cbDebugDisableMemoryBreakpoint, true); //enable memory breakpoint
dbgcmdnew("SetBreakpointCondition\1bpcond", cbDebugSetBPXCondition, true); //set breakpoint condition
dbgcmdnew("SetBreakpointLog\1bplog", cbDebugSetBPXLog, true); //set breakpoint log
//breakpoints (conditional)
dbgcmdnew("SetBreakpointCondition\1bpcond", cbDebugSetBPXCondition, true); //set breakpoint breakCondition
dbgcmdnew("SetBreakpointLog\1bplog", cbDebugSetBPXLog, true); //set breakpoint logText
dbgcmdnew("SetBreakpointLogCondition\1bplogcondition", cbDebugSetBPXLogCondition, true); //set breakpoint logCondition
dbgcmdnew("SetBreakpointCommand", cbDebugSetBPXCommand, true); //set breakpoint command on hit
dbgcmdnew("SetBreakpointCommandCondition", cbDebugSetBPXCommandCondition, true); //set breakpoint commandCondition
dbgcmdnew("SetBreakpointFastResume", cbDebugSetBPXFastResume, true); //set breakpoint fast resume
dbgcmdnew("GetBreakpointHitCount", cbDebugGetBPXHitCount, true); //get breakpoint hit count
dbgcmdnew("ResetBreakpointHitCount", cbDebugResetBPXHitCount, true); //reset breakpoint hit count
dbgcmdnew("SetHardwareBreakpointCondition\1bphwcond", cbDebugSetBPXHardwareCondition, true); //set breakpoint condition
dbgcmdnew("SetHardwareBreakpointLog\1bphwlog", cbDebugSetBPXHardwareLog, true); //set breakpoint log
dbgcmdnew("SetHardwareBreakpointCondition\1bphwcond", cbDebugSetBPXHardwareCondition, true); //set breakpoint breakCondition
dbgcmdnew("SetHardwareBreakpointLog\1bphwlog", cbDebugSetBPXHardwareLog, true); //set breakpoint logText
dbgcmdnew("SetHardwareBreakpointLogCondition\1bphwlogcondition", cbDebugSetBPXHardwareLogCondition, true); //set breakpoint logText
dbgcmdnew("SetHardwareBreakpointCommand", cbDebugSetBPXHardwareCommand, true); //set breakpoint command on hit
dbgcmdnew("SetHardwareBreakpointCommandCondition", cbDebugSetBPXHardwareCommandCondition, true); //set breakpoint commandCondition
dbgcmdnew("SetHardwareBreakpointFastResume", cbDebugSetBPXHardwareFastResume, true); //set breakpoint fast resume
dbgcmdnew("GetHardwareBreakpointHitCount", cbDebugGetBPXHardwareHitCount, true); //get breakpoint hit count
dbgcmdnew("ResetHardwareBreakpointHitCount", cbDebugResetBPXHardwareHitCount, true); //reset breakpoint hit count
dbgcmdnew("SetMemoryBreakpointCondition\1bpmcond", cbDebugSetBPXMemoryCondition, true); //set breakpoint condition
dbgcmdnew("SetMemoryBreakpointCondition\1bpmcond", cbDebugSetBPXMemoryCondition, true); //set breakpoint breakCondition
dbgcmdnew("SetMemoryBreakpointLog\1bpmlog", cbDebugSetBPXMemoryLog, true); //set breakpoint log
dbgcmdnew("SetMemoryBreakpointLogCondition\1bpmlogcondition", cbDebugSetBPXMemoryLogCondition, true); //set breakpoint logCondition
dbgcmdnew("SetMemoryBreakpointCommand", cbDebugSetBPXMemoryCommand, true); //set breakpoint command on hit
dbgcmdnew("SetMemoryBreakpointCommandCondition", cbDebugSetBPXMemoryCommandCondition, true); //set breakpoint commandCondition
dbgcmdnew("SetMemoryBreakpointFastResume", cbDebugSetBPXMemoryFastResume, true); //set breakpoint fast resume
dbgcmdnew("SetMemoryGetBreakpointHitCount", cbDebugGetBPXMemoryHitCount, true); //get breakpoint hit count
dbgcmdnew("ResetMemoryBreakpointHitCount", cbDebugResetBPXMemoryHitCount, true); //reset breakpoint hit count

View File

@ -116,10 +116,10 @@ void BreakpointsView::reloadData()
mHardBPTable->setCellContent(wI, 3, tr("Disabled"));
mHardBPTable->setCellContent(wI, 4, QString("%1").arg(wBPList.bp[wI].hitCount));
mHardBPTable->setCellContent(wI, 5, QString().fromUtf8(wBPList.bp[wI].log));
mHardBPTable->setCellContent(wI, 6, QString().fromUtf8(wBPList.bp[wI].condition));
mHardBPTable->setCellContent(wI, 5, QString().fromUtf8(wBPList.bp[wI].logText));
mHardBPTable->setCellContent(wI, 6, QString().fromUtf8(wBPList.bp[wI].breakCondition));
mHardBPTable->setCellContent(wI, 7, wBPList.bp[wI].fastResume ? "X" : "");
mHardBPTable->setCellContent(wI, 8, QString().fromUtf8(wBPList.bp[wI].hitCmd));
mHardBPTable->setCellContent(wI, 8, QString().fromUtf8(wBPList.bp[wI].commandText));
char text[MAX_COMMENT_SIZE] = "";
if(DbgGetCommentAt(wBPList.bp[wI].addr, text))
@ -162,10 +162,10 @@ void BreakpointsView::reloadData()
mSoftBPTable->setCellContent(wI, 3, tr("Disabled"));
mSoftBPTable->setCellContent(wI, 4, QString("%1").arg(wBPList.bp[wI].hitCount));
mSoftBPTable->setCellContent(wI, 5, QString().fromUtf8(wBPList.bp[wI].log));
mSoftBPTable->setCellContent(wI, 6, QString().fromUtf8(wBPList.bp[wI].condition));
mSoftBPTable->setCellContent(wI, 5, QString().fromUtf8(wBPList.bp[wI].logText));
mSoftBPTable->setCellContent(wI, 6, QString().fromUtf8(wBPList.bp[wI].breakCondition));
mSoftBPTable->setCellContent(wI, 7, wBPList.bp[wI].fastResume ? "X" : "");
mSoftBPTable->setCellContent(wI, 8, QString().fromUtf8(wBPList.bp[wI].hitCmd));
mSoftBPTable->setCellContent(wI, 8, QString().fromUtf8(wBPList.bp[wI].commandText));
char comment[MAX_COMMENT_SIZE] = "";
if(DbgGetCommentAt(wBPList.bp[wI].addr, comment))
@ -207,10 +207,10 @@ void BreakpointsView::reloadData()
mMemBPTable->setCellContent(wI, 3, tr("Disabled"));
mMemBPTable->setCellContent(wI, 4, QString("%1").arg(wBPList.bp[wI].hitCount));
mMemBPTable->setCellContent(wI, 5, QString().fromUtf8(wBPList.bp[wI].log));
mMemBPTable->setCellContent(wI, 6, QString().fromUtf8(wBPList.bp[wI].condition));
mMemBPTable->setCellContent(wI, 5, QString().fromUtf8(wBPList.bp[wI].logText));
mMemBPTable->setCellContent(wI, 6, QString().fromUtf8(wBPList.bp[wI].breakCondition));
mMemBPTable->setCellContent(wI, 7, wBPList.bp[wI].fastResume ? "X" : "");
mMemBPTable->setCellContent(wI, 8, QString().fromUtf8(wBPList.bp[wI].hitCmd));
mMemBPTable->setCellContent(wI, 8, QString().fromUtf8(wBPList.bp[wI].commandText));
char comment[MAX_COMMENT_SIZE] = "";
if(DbgGetCommentAt(wBPList.bp[wI].addr, comment))