282 lines
7.4 KiB
C++
282 lines
7.4 KiB
C++
#include "cmd-gui.h"
|
|
#include "debugger.h"
|
|
#include "console.h"
|
|
#include "memory.h"
|
|
#include "recursiveanalysis.h"
|
|
#include "function.h"
|
|
#include "stringformat.h"
|
|
#include "value.h"
|
|
#include "variable.h"
|
|
|
|
bool cbDebugDisasm(int argc, char* argv[])
|
|
{
|
|
duint addr = 0;
|
|
if(argc > 1)
|
|
{
|
|
if(!valfromstring(argv[1], &addr))
|
|
addr = GetContextDataEx(hActiveThread, UE_CIP);
|
|
}
|
|
else
|
|
{
|
|
addr = GetContextDataEx(hActiveThread, UE_CIP);
|
|
}
|
|
DebugUpdateGui(addr, false);
|
|
GuiShowCpu();
|
|
GuiFocusView(GUI_DISASSEMBLY);
|
|
return true;
|
|
}
|
|
|
|
bool cbDebugDump(int argc, char* argv[])
|
|
{
|
|
if(IsArgumentsLessThan(argc, 2))
|
|
return false;
|
|
duint addr = 0;
|
|
if(!valfromstring(argv[1], &addr))
|
|
{
|
|
dprintf(QT_TRANSLATE_NOOP("DBG", "Invalid address \"%s\"!\n"), argv[1]);
|
|
return false;
|
|
}
|
|
if(argc > 2)
|
|
{
|
|
duint index = 0;
|
|
if(!valfromstring(argv[2], &index))
|
|
{
|
|
dprintf(QT_TRANSLATE_NOOP("DBG", "Invalid address \"%s\"!\n"), argv[2]);
|
|
return false;
|
|
}
|
|
GuiDumpAtN(addr, int(index));
|
|
}
|
|
else
|
|
GuiDumpAt(addr);
|
|
GuiShowCpu();
|
|
GuiFocusView(GUI_DUMP);
|
|
return true;
|
|
}
|
|
|
|
bool cbDebugStackDump(int argc, char* argv[])
|
|
{
|
|
duint addr = 0;
|
|
if(argc < 2)
|
|
addr = GetContextDataEx(hActiveThread, UE_CSP);
|
|
else if(!valfromstring(argv[1], &addr))
|
|
{
|
|
dprintf(QT_TRANSLATE_NOOP("DBG", "Invalid address \"%s\"!\n"), argv[1]);
|
|
return false;
|
|
}
|
|
duint csp = GetContextDataEx(hActiveThread, UE_CSP);
|
|
duint size = 0;
|
|
duint base = MemFindBaseAddr(csp, &size);
|
|
if(base && addr >= base && addr < (base + size))
|
|
DebugUpdateStack(addr, csp, true);
|
|
else
|
|
dputs(QT_TRANSLATE_NOOP("DBG", "Invalid stack address!"));
|
|
GuiShowCpu();
|
|
GuiFocusView(GUI_STACK);
|
|
return true;
|
|
}
|
|
|
|
bool cbDebugMemmapdump(int argc, char* argv[])
|
|
{
|
|
if(argc < 2)
|
|
return false;
|
|
duint addr;
|
|
if(!valfromstring(argv[1], &addr, false) || !MemIsValidReadPtr(addr, true))
|
|
{
|
|
dprintf(QT_TRANSLATE_NOOP("DBG", "Invalid address \"%s\"!\n"), argv[1]);
|
|
return false;
|
|
}
|
|
GuiSelectInMemoryMap(addr);
|
|
GuiFocusView(GUI_MEMMAP);
|
|
return true;
|
|
}
|
|
|
|
bool cbInstrGraph(int argc, char* argv[])
|
|
{
|
|
auto options = argc > 2 ? argv[2] : "";
|
|
auto force = !!strstr(options, "force");
|
|
auto silent = !!strstr(options, "silent");
|
|
duint entry;
|
|
if(argc < 2 || !valfromstring(argv[1], &entry))
|
|
entry = GetContextDataEx(hActiveThread, UE_CIP);
|
|
duint start, size, sel = entry;
|
|
if(FunctionGet(entry, &start))
|
|
entry = start;
|
|
auto base = MemFindBaseAddr(entry, &size);
|
|
if(!base || !MemIsValidReadPtr(entry))
|
|
{
|
|
if(!silent)
|
|
dprintf(QT_TRANSLATE_NOOP("DBG", "Invalid address %p!\n"), entry);
|
|
return false;
|
|
}
|
|
auto curEntry = GuiGraphAt(sel);
|
|
if(curEntry)
|
|
entry = curEntry;
|
|
if(!curEntry || force)
|
|
{
|
|
auto modbase = ModBaseFromAddr(base);
|
|
if(modbase)
|
|
base = modbase, size = ModSizeFromAddr(modbase);
|
|
RecursiveAnalysis analysis(base, size, entry, 0, true);
|
|
analysis.Analyse();
|
|
auto graph = analysis.GetFunctionGraph(entry);
|
|
if(!graph)
|
|
{
|
|
if(!silent)
|
|
dputs(QT_TRANSLATE_NOOP("DBG", "No graph generated..."));
|
|
return false;
|
|
}
|
|
auto graphList = graph->ToGraphList();
|
|
GuiLoadGraph(&graphList, sel);
|
|
}
|
|
GuiUpdateAllViews();
|
|
GuiFocusView(GUI_GRAPH);
|
|
return true;
|
|
}
|
|
|
|
bool cbInstrEnableGuiUpdate(int argc, char* argv[])
|
|
{
|
|
if(GuiIsUpdateDisabled())
|
|
GuiUpdateEnable(false);
|
|
duint value;
|
|
//argv[1]=="1" = update GUI
|
|
if(argc > 1 && valfromstring(argv[1], &value) && value == 1)
|
|
GuiUpdateAllViews();
|
|
return true;
|
|
}
|
|
|
|
bool cbInstrDisableGuiUpdate(int argc, char* argv[])
|
|
{
|
|
if(!GuiIsUpdateDisabled())
|
|
GuiUpdateDisable();
|
|
return true;
|
|
}
|
|
|
|
bool cbDebugSetfreezestack(int argc, char* argv[])
|
|
{
|
|
if(IsArgumentsLessThan(argc, 2))
|
|
return false;
|
|
bool freeze = *argv[1] != '0';
|
|
dbgsetfreezestack(freeze);
|
|
if(freeze)
|
|
dputs(QT_TRANSLATE_NOOP("DBG", "Stack is now frozen\n"));
|
|
else
|
|
dputs(QT_TRANSLATE_NOOP("DBG", "Stack is now unfrozen\n"));
|
|
return true;
|
|
}
|
|
|
|
static bool bRefinit = false;
|
|
|
|
bool cbInstrRefinit(int argc, char* argv[])
|
|
{
|
|
auto title = argc > 1 ? stringformatinline(argv[1]) : GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Script"));
|
|
GuiReferenceInitialize(title.c_str());
|
|
GuiReferenceAddColumn(sizeof(duint) * 2, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Address")));
|
|
GuiReferenceAddColumn(0, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "Data")));
|
|
GuiReferenceSetRowCount(0);
|
|
GuiReferenceReloadData();
|
|
bRefinit = true;
|
|
return true;
|
|
}
|
|
|
|
bool cbInstrRefadd(int argc, char* argv[])
|
|
{
|
|
if(IsArgumentsLessThan(argc, 3))
|
|
return false;
|
|
duint addr = 0;
|
|
if(!valfromstring(argv[1], &addr, false))
|
|
return false;
|
|
if(!bRefinit)
|
|
cbInstrRefinit(argc, argv);
|
|
int index = GuiReferenceGetRowCount();
|
|
GuiReferenceSetRowCount(index + 1);
|
|
char addr_text[32] = "";
|
|
sprintf_s(addr_text, "%p", addr);
|
|
GuiReferenceSetCellContent(index, 0, addr_text);
|
|
GuiReferenceSetCellContent(index, 1, stringformatinline(argv[2]).c_str());
|
|
GuiReferenceReloadData();
|
|
return true;
|
|
}
|
|
|
|
bool cbInstrRefGet(int argc, char* argv[])
|
|
{
|
|
if(IsArgumentsLessThan(argc, 2))
|
|
return false;
|
|
duint row;
|
|
if(!valfromstring(argv[1], &row, false))
|
|
return false;
|
|
auto content = GuiReferenceGetCellContent(int(row), 0);
|
|
duint addr = 0;
|
|
valfromstring(content, &addr, false);
|
|
varset("$result", addr, false);
|
|
BridgeFree(content);
|
|
return true;
|
|
}
|
|
|
|
bool cbInstrEnableLog(int argc, char* argv[])
|
|
{
|
|
GuiEnableLog();
|
|
return true;
|
|
}
|
|
|
|
bool cbInstrDisableLog(int argc, char* argv[])
|
|
{
|
|
GuiDisableLog();
|
|
return true;
|
|
}
|
|
|
|
bool cbInstrAddFavTool(int argc, char* argv[])
|
|
{
|
|
// filename, description
|
|
if(IsArgumentsLessThan(argc, 2))
|
|
return false;
|
|
|
|
if(argc == 2)
|
|
GuiAddFavouriteTool(argv[1], nullptr);
|
|
else
|
|
GuiAddFavouriteTool(argv[1], argv[2]);
|
|
return true;
|
|
}
|
|
|
|
bool cbInstrAddFavCmd(int argc, char* argv[])
|
|
{
|
|
// command, shortcut
|
|
if(IsArgumentsLessThan(argc, 2))
|
|
return false;
|
|
|
|
if(argc == 2)
|
|
GuiAddFavouriteCommand(argv[1], nullptr);
|
|
else
|
|
GuiAddFavouriteCommand(argv[1], argv[2]);
|
|
return true;
|
|
}
|
|
|
|
bool cbInstrSetFavToolShortcut(int argc, char* argv[])
|
|
{
|
|
// filename, shortcut
|
|
if(IsArgumentsLessThan(argc, 3))
|
|
return false;
|
|
|
|
GuiSetFavouriteToolShortcut(argv[1], argv[2]);
|
|
return true;
|
|
|
|
}
|
|
|
|
bool cbInstrFoldDisassembly(int argc, char* argv[])
|
|
{
|
|
if(IsArgumentsLessThan(argc, 3))
|
|
return false;
|
|
|
|
duint start, length;
|
|
if(!valfromstring(argv[1], &start))
|
|
{
|
|
dprintf(QT_TRANSLATE_NOOP("DBG", "Invalid argument 1 : %s\n"), argv[1]);
|
|
return false;
|
|
}
|
|
if(!valfromstring(argv[2], &length))
|
|
{
|
|
dprintf(QT_TRANSLATE_NOOP("DBG", "Invalid argument 2 : %s\n"), argv[2]);
|
|
return false;
|
|
}
|
|
GuiFoldDisassembly(start, length);
|
|
return true;
|
|
} |