1
0
Fork 0

Add autocomment for breakpoint

This commit is contained in:
torusrxxx 2021-12-26 17:24:00 +08:00
parent 025fcf5125
commit 3817686d95
No known key found for this signature in database
GPG Key ID: A795C73A0F1CFADD
2 changed files with 229 additions and 144 deletions

View File

@ -287,6 +287,225 @@ static bool getLabel(duint addr, char* label, bool noFuncOffset)
return retval;
}
static bool getAutoComment(duint addr, String & comment)
{
bool retval;
duint disp;
char fileName[MAX_STRING_SIZE] = {};
int lineNumber = 0;
if(!bNoSourceLineAutoComments && SymGetSourceLine(addr, fileName, &lineNumber, &disp) && !disp)
{
char* actualName = fileName;
char* l = strrchr(fileName, '\\');
if(l)
actualName = l + 1;
comment = StringUtils::sprintf("%s:%u", actualName, lineNumber);
retval = true;
}
DISASM_INSTR instr;
String temp_string;
BRIDGE_ADDRINFO newinfo;
char string_text[MAX_STRING_SIZE] = "";
Zydis cp;
auto getregs = !bOnlyCipAutoComments || addr == lastContext.cip;
disasmget(cp, addr, &instr, getregs);
// Some nop variants have 'operands' that should be ignored
if(cp.Success() && !cp.IsNop())
{
//Ignore register values when not on CIP and OnlyCipAutoComments is enabled: https://github.com/x64dbg/x64dbg/issues/1383
if(!getregs)
{
for(int i = 0; i < instr.argcount; i++)
instr.arg[i].value = instr.arg[i].constant;
}
if(addr == lastContext.cip && (cp.GetId() == ZYDIS_MNEMONIC_SYSCALL || (cp.GetId() == ZYDIS_MNEMONIC_INT && cp[0].imm.value.u == 0x2e)))
{
auto syscallName = SyscallToName((unsigned int)lastContext.cax);
if(!syscallName.empty())
{
if(!comment.empty())
{
comment.push_back(',');
comment.push_back(' ');
}
comment.append(syscallName);
retval = true;
}
}
for(int i = 0; i < instr.argcount; i++)
{
memset(&newinfo, 0, sizeof(BRIDGE_ADDRINFO));
newinfo.flags = flaglabel;
STRING_TYPE strtype = str_none;
if(instr.arg[i].constant == instr.arg[i].value) //avoid: call <module.label> ; addr:label
{
auto constant = instr.arg[i].constant;
if(instr.arg[i].type == arg_normal && instr.arg[i].value == addr + instr.instr_size && cp.IsCall())
temp_string.assign("call $0");
else if(instr.arg[i].type == arg_normal && instr.arg[i].value == addr + instr.instr_size && cp.IsJump())
temp_string.assign("jmp $0");
else if(instr.type == instr_branch)
continue;
else if(instr.arg[i].type == arg_normal && constant < 256 && (isprint(int(constant)) || isspace(int(constant))) && (strstr(instr.instruction, "cmp") || strstr(instr.instruction, "mov")))
{
temp_string.assign(instr.arg[i].mnemonic);
temp_string.push_back(':');
temp_string.push_back('\'');
temp_string.append(StringUtils::Escape((unsigned char)constant));
temp_string.push_back('\'');
}
else if(DbgGetStringAt(instr.arg[i].constant, string_text))
{
temp_string.assign(instr.arg[i].mnemonic);
temp_string.push_back(':');
temp_string.append(string_text);
}
}
else if(instr.arg[i].memvalue && (DbgGetStringAt(instr.arg[i].memvalue, string_text) || _dbg_addrinfoget(instr.arg[i].memvalue, instr.arg[i].segment, &newinfo)))
{
if(*string_text)
{
temp_string.assign("[");
temp_string.append(instr.arg[i].mnemonic);
temp_string.push_back(']');
temp_string.push_back(':');
temp_string.append(string_text);
}
else if(*newinfo.label)
{
temp_string.assign("[");
temp_string.append(instr.arg[i].mnemonic);
temp_string.push_back(']');
temp_string.push_back(':');
temp_string.append(newinfo.label);
}
}
else if(instr.arg[i].value && (DbgGetStringAt(instr.arg[i].value, string_text) || _dbg_addrinfoget(instr.arg[i].value, instr.arg[i].segment, &newinfo)))
{
if(instr.type != instr_normal) //stack/jumps (eg add esp, 4 or jmp 401110) cannot directly point to strings
{
if(*newinfo.label)
{
temp_string = instr.arg[i].mnemonic;
temp_string.push_back(':');
temp_string.append(newinfo.label);
}
}
else if(*string_text)
{
temp_string = instr.arg[i].mnemonic;
temp_string.push_back(':');
temp_string.append(string_text);
}
else if(*newinfo.label)
{
temp_string = instr.arg[i].mnemonic;
temp_string.push_back(':');
temp_string.append(newinfo.label);
}
}
else
continue;
if(!strstr(comment.c_str(), temp_string.c_str())) //avoid duplicate comments
{
if(!comment.empty())
{
comment.push_back(',');
comment.push_back(' ');
}
comment.append(temp_string);
retval = true;
}
}
}
BREAKPOINT bp;
// Add autocomment for breakpoints with BreakpointsView format because there's usually something useful
if(BpGet(addr, BPNORMAL, nullptr, &bp) || BpGet(addr, BPHARDWARE, nullptr, &bp))
{
auto next = [&temp_string]()
{
if(!temp_string.empty())
temp_string += ", ";
};
if(*bp.breakCondition)
{
next();
temp_string += GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "breakif"));
temp_string += "(";
temp_string += bp.breakCondition;
temp_string += ")";
}
if(bp.fastResume)
{
next();
temp_string += GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "fastresume()"));
}
else //fast resume skips all other steps
{
if(*bp.logText)
{
next();
if(*bp.logCondition)
{
temp_string += GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "logif"));
temp_string += "(";
temp_string += bp.logCondition;
temp_string += ", ";
}
else
{
temp_string += GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "log"));
temp_string += "(";
}
temp_string += bp.logText;
temp_string += ")";
}
if(*bp.commandText)
{
next();
if(*bp.commandCondition)
{
temp_string += GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "cmdif"));
temp_string += "(";
temp_string += bp.commandCondition;
temp_string += ", ";
}
else
{
temp_string += GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "cmd"));
temp_string += "(";
}
temp_string += bp.commandText;
temp_string += ")";
}
}
if(!temp_string.empty())
{
if(!comment.empty())
{
comment.push_back(',');
comment.push_back(' ');
}
comment.append(temp_string);
retval = true;
}
}
StringUtils::ReplaceAll(comment, "{", "{{");
StringUtils::ReplaceAll(comment, "}", "}}");
return retval;
}
extern "C" DLL_EXPORT bool _dbg_addrinfoget(duint addr, SEGMENTREG segment, BRIDGE_ADDRINFO* addrinfo)
{
if(!DbgIsDebugging())
@ -331,145 +550,7 @@ extern "C" DLL_EXPORT bool _dbg_addrinfoget(duint addr, SEGMENTREG segment, BRID
else
{
String comment;
duint disp;
char fileName[MAX_STRING_SIZE] = {};
int lineNumber = 0;
if(!bNoSourceLineAutoComments && SymGetSourceLine(addr, fileName, &lineNumber, &disp) && !disp)
{
char* actualName = fileName;
char* l = strrchr(fileName, '\\');
if(l)
actualName = l + 1;
comment = StringUtils::sprintf("%s:%u", actualName, lineNumber);
retval = true;
}
DISASM_INSTR instr;
String temp_string;
BRIDGE_ADDRINFO newinfo;
char string_text[MAX_STRING_SIZE] = "";
Zydis cp;
auto getregs = !bOnlyCipAutoComments || addr == lastContext.cip;
disasmget(cp, addr, &instr, getregs);
// Some nop variants have 'operands' that should be ignored
if(cp.Success() && !cp.IsNop())
{
//Ignore register values when not on CIP and OnlyCipAutoComments is enabled: https://github.com/x64dbg/x64dbg/issues/1383
if(!getregs)
{
for(int i = 0; i < instr.argcount; i++)
instr.arg[i].value = instr.arg[i].constant;
}
if(addr == lastContext.cip && (cp.GetId() == ZYDIS_MNEMONIC_SYSCALL || (cp.GetId() == ZYDIS_MNEMONIC_INT && cp[0].imm.value.u == 0x2e)))
{
auto syscallName = SyscallToName((unsigned int)lastContext.cax);
if(!syscallName.empty())
{
if(!comment.empty())
{
comment.push_back(',');
comment.push_back(' ');
}
comment.append(syscallName);
retval = true;
}
}
for(int i = 0; i < instr.argcount; i++)
{
memset(&newinfo, 0, sizeof(BRIDGE_ADDRINFO));
newinfo.flags = flaglabel;
STRING_TYPE strtype = str_none;
if(instr.arg[i].constant == instr.arg[i].value) //avoid: call <module.label> ; addr:label
{
auto constant = instr.arg[i].constant;
if(instr.arg[i].type == arg_normal && instr.arg[i].value == addr + instr.instr_size && cp.IsCall())
temp_string.assign("call $0");
else if(instr.arg[i].type == arg_normal && instr.arg[i].value == addr + instr.instr_size && cp.IsJump())
temp_string.assign("jmp $0");
else if(instr.type == instr_branch)
continue;
else if(instr.arg[i].type == arg_normal && constant < 256 && (isprint(int(constant)) || isspace(int(constant))) && (strstr(instr.instruction, "cmp") || strstr(instr.instruction, "mov")))
{
temp_string.assign(instr.arg[i].mnemonic);
temp_string.push_back(':');
temp_string.push_back('\'');
temp_string.append(StringUtils::Escape((unsigned char)constant));
temp_string.push_back('\'');
}
else if(DbgGetStringAt(instr.arg[i].constant, string_text))
{
temp_string.assign(instr.arg[i].mnemonic);
temp_string.push_back(':');
temp_string.append(string_text);
}
}
else if(instr.arg[i].memvalue && (DbgGetStringAt(instr.arg[i].memvalue, string_text) || _dbg_addrinfoget(instr.arg[i].memvalue, instr.arg[i].segment, &newinfo)))
{
if(*string_text)
{
temp_string.assign("[");
temp_string.append(instr.arg[i].mnemonic);
temp_string.push_back(']');
temp_string.push_back(':');
temp_string.append(string_text);
}
else if(*newinfo.label)
{
temp_string.assign("[");
temp_string.append(instr.arg[i].mnemonic);
temp_string.push_back(']');
temp_string.push_back(':');
temp_string.append(newinfo.label);
}
}
else if(instr.arg[i].value && (DbgGetStringAt(instr.arg[i].value, string_text) || _dbg_addrinfoget(instr.arg[i].value, instr.arg[i].segment, &newinfo)))
{
if(instr.type != instr_normal) //stack/jumps (eg add esp, 4 or jmp 401110) cannot directly point to strings
{
if(*newinfo.label)
{
temp_string = instr.arg[i].mnemonic;
temp_string.push_back(':');
temp_string.append(newinfo.label);
}
}
else if(*string_text)
{
temp_string = instr.arg[i].mnemonic;
temp_string.push_back(':');
temp_string.append(string_text);
}
else if(*newinfo.label)
{
temp_string = instr.arg[i].mnemonic;
temp_string.push_back(':');
temp_string.append(newinfo.label);
}
}
else
continue;
if(!strstr(comment.c_str(), temp_string.c_str())) //avoid duplicate comments
{
if(!comment.empty())
{
comment.push_back(',');
comment.push_back(' ');
}
comment.append(temp_string);
retval = true;
}
}
}
StringUtils::ReplaceAll(comment, "{", "{{");
StringUtils::ReplaceAll(comment, "}", "}}");
retval = getAutoComment(addr, comment);
strcpy_s(addrinfo->comment, "\1");
strncat_s(addrinfo->comment, comment.c_str(), _TRUNCATE);
}

View File

@ -458,7 +458,7 @@ void BreakpointsView::updateBreakpointsSlot()
if(*bp.breakCondition)
{
next();
colored("breakif", mSummaryKeywordColor);
colored(tr("breakif"), mSummaryKeywordColor);
colored("(", mSummaryParenColor);
text(bp.breakCondition);
colored(")", mSummaryParenColor);
@ -475,17 +475,19 @@ void BreakpointsView::updateBreakpointsSlot()
if(*bp.logText)
{
next();
colored(tr("log"), mSummaryKeywordColor);
if(*bp.logCondition)
{
colored("if", mSummaryKeywordColor);
colored(tr("logif"), mSummaryKeywordColor);
colored("(", mSummaryParenColor);
text(bp.logCondition);
colored(",", mSummaryParenColor);
text(" ");
}
else
{
colored(tr("log"), mSummaryKeywordColor);
colored("(", mSummaryParenColor);
}
colored(QString("\"%1\"").arg(bp.logText), mSummaryStringColor);
colored(")", mSummaryParenColor);
}
@ -493,17 +495,19 @@ void BreakpointsView::updateBreakpointsSlot()
if(*bp.commandText)
{
next();
colored(tr("cmd"), mSummaryKeywordColor);
if(*bp.commandCondition)
{
colored("if", mSummaryKeywordColor);
colored(tr("cmdif"), mSummaryKeywordColor);
colored("(", mSummaryParenColor);
text(bp.commandCondition);
colored(",", mSummaryParenColor);
text(" ");
}
else
{
colored(tr("cmd"), mSummaryKeywordColor);
colored("(", mSummaryParenColor);
}
colored(QString("\"%1\"").arg(bp.commandText), mSummaryStringColor);
colored(")", mSummaryParenColor);
}