diff --git a/src/dbg/commands/cmd-undocumented.cpp b/src/dbg/commands/cmd-undocumented.cpp index c48de524..c50e1658 100644 --- a/src/dbg/commands/cmd-undocumented.cpp +++ b/src/dbg/commands/cmd-undocumented.cpp @@ -204,53 +204,6 @@ bool cbInstrCopystr(int argc, char* argv[]) return true; } -bool cbInstrLoopList(int argc, char* argv[]) -{ - //setup reference view - GuiReferenceInitialize(GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Loops"))); - GuiReferenceAddColumn(2 * sizeof(duint), GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Start"))); - GuiReferenceAddColumn(2 * sizeof(duint), GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "End"))); - GuiReferenceAddColumn(64, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Disassembly (Start)"))); - GuiReferenceAddColumn(0, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Label/Comment"))); - GuiReferenceSetRowCount(0); - GuiReferenceReloadData(); - size_t cbsize; - LoopEnum(0, &cbsize); - if(!cbsize) - { - dputs(QT_TRANSLATE_NOOP("DBG", "No loops")); - return true; - } - Memory loops(cbsize, "cbInstrLoopList:loops"); - LoopEnum(loops(), 0); - int count = (int)(cbsize / sizeof(LOOPSINFO)); - for(int i = 0; i < count; i++) - { - GuiReferenceSetRowCount(i + 1); - char addrText[20] = ""; - sprintf_s(addrText, "%p", loops()[i].start); - GuiReferenceSetCellContent(i, 0, addrText); - sprintf_s(addrText, "%p", loops()[i].end); - GuiReferenceSetCellContent(i, 1, addrText); - char disassembly[GUI_MAX_DISASSEMBLY_SIZE] = ""; - if(GuiGetDisassembly(loops()[i].start, disassembly)) - GuiReferenceSetCellContent(i, 2, disassembly); - char label[MAX_LABEL_SIZE] = ""; - if(LabelGet(loops()[i].start, label)) - GuiReferenceSetCellContent(i, 3, label); - else - { - char comment[MAX_COMMENT_SIZE] = ""; - if(CommentGet(loops()[i].start, comment)) - GuiReferenceSetCellContent(i, 3, comment); - } - } - varset("$result", count, false); - dprintf(QT_TRANSLATE_NOOP("DBG", "%d loop(s) listed\n"), count); - GuiReferenceReloadData(); - return true; -} - bool cbInstrCapstone(int argc, char* argv[]) { if(IsArgumentsLessThan(argc, 2)) diff --git a/src/dbg/commands/cmd-undocumented.h b/src/dbg/commands/cmd-undocumented.h index e74951bf..fd3fb520 100644 --- a/src/dbg/commands/cmd-undocumented.h +++ b/src/dbg/commands/cmd-undocumented.h @@ -7,7 +7,6 @@ bool cbDebugBenchmark(int argc, char* argv[]); bool cbInstrSetstr(int argc, char* argv[]); bool cbInstrGetstr(int argc, char* argv[]); bool cbInstrCopystr(int argc, char* argv[]); -bool cbInstrLoopList(int argc, char* argv[]); bool cbInstrCapstone(int argc, char* argv[]); bool cbInstrVisualize(int argc, char* argv[]); bool cbInstrMeminfo(int argc, char* argv[]); diff --git a/src/dbg/commands/cmd-user-database.cpp b/src/dbg/commands/cmd-user-database.cpp index 50005db0..737cc1c6 100644 --- a/src/dbg/commands/cmd-user-database.cpp +++ b/src/dbg/commands/cmd-user-database.cpp @@ -8,6 +8,7 @@ #include "bookmark.h" #include "function.h" #include "argument.h" +#include "loop.h" bool cbInstrDbsave(int argc, char* argv[]) { @@ -447,4 +448,103 @@ bool cbInstrArgumentClear(int argc, char* argv[]) GuiUpdateAllViews(); dputs(QT_TRANSLATE_NOOP("DBG", "All arguments deleted!")); return true; +} + +bool cbInstrLoopAdd(int argc, char* argv[]) +{ + if(IsArgumentsLessThan(argc, 3)) + return false; + duint start = 0; + duint end = 0; + if(!valfromstring(argv[1], &start, false) || !valfromstring(argv[2], &end, false)) + return false; + if(!LoopAdd(start, end, true)) + { + dputs(QT_TRANSLATE_NOOP("DBG", "Failed to add loop")); + return false; + } + dputs(QT_TRANSLATE_NOOP("DBG", "Loop added!")); + GuiUpdateAllViews(); + return true; +} + +bool cbInstrLoopDel(int argc, char* argv[]) +{ + if(IsArgumentsLessThan(argc, 2)) + return false; + duint addr = 0; + if(!valfromstring(argv[1], &addr, false)) + return false; + duint depth = 0; + if(argc >= 3 && !valfromstring(argv[2], &depth, false)) + return false; + if(!LoopDelete(int(depth), addr)) + { + dputs(QT_TRANSLATE_NOOP("DBG", "Failed to delete loop")); + return false; + } + dputs(QT_TRANSLATE_NOOP("DBG", "Loop deleted!")); + GuiUpdateAllViews(); + return true; +} + +bool cbInstrLoopList(int argc, char* argv[]) +{ + //setup reference view + GuiReferenceInitialize(GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Loops"))); + GuiReferenceAddColumn(2 * sizeof(duint), GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Start"))); + GuiReferenceAddColumn(2 * sizeof(duint), GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "End"))); + GuiReferenceAddColumn(2 * sizeof(duint), GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Depth"))); + GuiReferenceAddColumn(2 * sizeof(duint), GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Parent"))); + GuiReferenceAddColumn(64, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Disassembly (Start)"))); + GuiReferenceAddColumn(0, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Label/Comment"))); + GuiReferenceSetRowCount(0); + GuiReferenceReloadData(); + size_t cbsize; + LoopEnum(0, &cbsize); + if(!cbsize) + { + dputs(QT_TRANSLATE_NOOP("DBG", "No loops")); + return true; + } + Memory loops(cbsize, "cbInstrLoopList:loops"); + LoopEnum(loops(), 0); + int count = (int)(cbsize / sizeof(LOOPSINFO)); + for(int i = 0; i < count; i++) + { + GuiReferenceSetRowCount(i + 1); + char addrText[20] = ""; + sprintf_s(addrText, "%p", loops()[i].start); + GuiReferenceSetCellContent(i, 0, addrText); + sprintf_s(addrText, "%p", loops()[i].end); + GuiReferenceSetCellContent(i, 1, addrText); + sprintf_s(addrText, "%d", loops()[i].depth); + GuiReferenceSetCellContent(i, 2, addrText); + sprintf_s(addrText, "%p", loops()[i].parent); + GuiReferenceSetCellContent(i, 3, addrText); + char disassembly[GUI_MAX_DISASSEMBLY_SIZE] = ""; + if(GuiGetDisassembly(loops()[i].start, disassembly)) + GuiReferenceSetCellContent(i, 4, disassembly); + char label[MAX_LABEL_SIZE] = ""; + if(LabelGet(loops()[i].start, label)) + GuiReferenceSetCellContent(i, 5, label); + else + { + char comment[MAX_COMMENT_SIZE] = ""; + if(CommentGet(loops()[i].start, comment)) + GuiReferenceSetCellContent(i, 5, comment); + } + } + varset("$result", count, false); + dprintf(QT_TRANSLATE_NOOP("DBG", "%d loop(s) listed\n"), count); + GuiReferenceReloadData(); + return true; +} + +bool cbInstrLoopClear(int argc, char* argv[]) +{ + LoopClear(); + GuiUpdateAllViews(); + dputs(QT_TRANSLATE_NOOP("DBG", "All loops deleted!")); + return true; } \ No newline at end of file diff --git a/src/dbg/commands/cmd-user-database.h b/src/dbg/commands/cmd-user-database.h index 7170e793..899ad61e 100644 --- a/src/dbg/commands/cmd-user-database.h +++ b/src/dbg/commands/cmd-user-database.h @@ -31,4 +31,7 @@ bool cbInstrArgumentDel(int argc, char* argv[]); bool cbInstrArgumentList(int argc, char* argv[]); bool cbInstrArgumentClear(int argc, char* argv[]); - +bool cbInstrLoopAdd(int argc, char* argv[]); +bool cbInstrLoopDel(int argc, char* argv[]); +bool cbInstrLoopList(int argc, char* argv[]); +bool cbInstrLoopClear(int argc, char* argv[]); \ No newline at end of file diff --git a/src/dbg/x64dbg.cpp b/src/dbg/x64dbg.cpp index 4301e163..a645fbce 100644 --- a/src/dbg/x64dbg.cpp +++ b/src/dbg/x64dbg.cpp @@ -302,6 +302,11 @@ static void registercommands() dbgcmdnew("argumentlist", cbInstrArgumentList, true); //list arguments dbgcmdnew("argumentclear", cbInstrArgumentClear, false); //delete all arguments + dbgcmdnew("loopadd", cbInstrLoopAdd, true); //add loop TODO: undocumented + dbgcmdnew("loopdel", cbInstrLoopDel, true); //delete loop TODO: undocumented + dbgcmdnew("looplist", cbInstrLoopList, true); //list loops TODO: undocumented + dbgcmdnew("loopclear", cbInstrLoopClear, true); //clear loops TODO: undocumented + //analysis dbgcmdnew("analyse\1analyze\1anal", cbInstrAnalyse, true); //secret analysis command dbgcmdnew("exanal\1exanalyse\1exanalyze", cbInstrExanalyse, true); //exception directory analysis @@ -413,7 +418,6 @@ static void registercommands() dbgcmdnew("setstr\1strset", cbInstrSetstr, false); //set a string variable dbgcmdnew("getstr\1strget", cbInstrGetstr, false); //get a string variable dbgcmdnew("copystr\1strcpy", cbInstrCopystr, true); //write a string variable to memory - dbgcmdnew("looplist", cbInstrLoopList, true); //list loops dbgcmdnew("capstone", cbInstrCapstone, true); //disassemble using capstone dbgcmdnew("visualize", cbInstrVisualize, true); //visualize analysis dbgcmdnew("meminfo", cbInstrMeminfo, true); //command to debug memory map bugs