DBG/GUI : Added back setfreezestack command to lock the stack with ability to freely scroll in the stack when its frozen without it resetting back to first selection (hard to explain lol)
GUI : When pressing +/- (Goto->Previous/Next) in Disassembly widget, window title gets updated accordingly to display the module we are in. Minor fix in command line save/load : free the json object used
This commit is contained in:
parent
941b93f5c0
commit
c152a420e6
|
@ -741,7 +741,7 @@ typedef enum
|
|||
GUI_REF_GETCELLCONTENT, // param1=int row, param2=int col
|
||||
GUI_REF_RELOADDATA, // param1=unused, param2=unused
|
||||
GUI_REF_SETSINGLESELECTION, // param1=int index, param2=bool scroll
|
||||
GUI_REF_SETPROGRESS, // param1=int progress, param2=unused
|
||||
GUI_REF_SETPROGRESS, // param1=int progress, param2=unused
|
||||
GUI_REF_SETSEARCHSTARTCOL, // param1=int col param2=unused
|
||||
GUI_STACK_DUMP_AT, // param1=duint addr, param2=duint csp
|
||||
GUI_UPDATE_DUMP_VIEW, // param1=unused, param2=unused
|
||||
|
@ -758,7 +758,7 @@ typedef enum
|
|||
GUI_GETLINE_WINDOW, // param1=const char* title, param2=char* text
|
||||
GUI_AUTOCOMPLETE_ADDCMD, // param1=const char* cmd, param2=ununsed
|
||||
GUI_AUTOCOMPLETE_DELCMD, // param1=const char* cmd, param2=ununsed
|
||||
GUI_AUTOCOMPLETE_CLEARALL, // param1=unused, param2=unused
|
||||
GUI_AUTOCOMPLETE_CLEARALL, // param1=unused, param2=unused
|
||||
GUI_SCRIPT_ENABLEHIGHLIGHTING, // param1=bool enable, param2=unused
|
||||
GUI_ADD_MSG_TO_STATUSBAR, // param1=const char* msg, param2=unused
|
||||
GUI_UPDATE_SIDEBAR, // param1=unused, param2=unused
|
||||
|
|
|
@ -57,11 +57,16 @@ void CmdLineCacheLoad(JSON Root)
|
|||
|
||||
// Return if there was nothing to load
|
||||
if (!jsonCmdLine)
|
||||
{
|
||||
json_decref(jsonCmdLine);
|
||||
return;
|
||||
}
|
||||
|
||||
const char *cmdLine = json_string_value(json_object_get(jsonCmdLine, "cmdLine"));
|
||||
|
||||
strcpy_s(commandLine, cmdLine);
|
||||
|
||||
json_decref(jsonCmdLine);
|
||||
}
|
||||
|
||||
void copyCommandLine(const char* cmdLine)
|
||||
|
|
|
@ -34,6 +34,7 @@ static bool isDetachedByUser = false;
|
|||
static bool bIsAttached = false;
|
||||
static bool bSkipExceptions = false;
|
||||
static bool bBreakOnNextDll = false;
|
||||
static bool bFreezeStack = false;
|
||||
static int ecount = 0;
|
||||
static std::vector<ExceptionRange> ignoredExceptionRange;
|
||||
static HANDLE hEvent = 0;
|
||||
|
@ -155,6 +156,11 @@ void dbgsetisdetachedbyuser(bool b)
|
|||
isDetachedByUser = b;
|
||||
}
|
||||
|
||||
void dbgsetfreezestack(bool freeze)
|
||||
{
|
||||
bFreezeStack = freeze;
|
||||
}
|
||||
|
||||
void dbgclearignoredexceptions()
|
||||
{
|
||||
ignoredExceptionRange.clear();
|
||||
|
@ -215,7 +221,7 @@ void DebugUpdateGui(duint disasm_addr, bool stack)
|
|||
}
|
||||
duint csp = GetContextDataEx(hActiveThread, UE_CSP);
|
||||
if(stack)
|
||||
GuiStackDumpAt(csp, csp);
|
||||
DebugUpdateStack(csp, csp);
|
||||
static duint cacheCsp = 0;
|
||||
if(csp != cacheCsp)
|
||||
{
|
||||
|
@ -234,6 +240,17 @@ void DebugUpdateGui(duint disasm_addr, bool stack)
|
|||
GuiUpdateAllViews();
|
||||
}
|
||||
|
||||
void DebugUpdateStack(duint dumpAddr, duint csp, bool forceDump)
|
||||
{
|
||||
if (!forceDump && bFreezeStack)
|
||||
{
|
||||
SELECTIONDATA selection;
|
||||
if (GuiSelectionGet(GUI_STACK, &selection))
|
||||
dumpAddr = selection.start;
|
||||
}
|
||||
GuiStackDumpAt(dumpAddr, csp);
|
||||
}
|
||||
|
||||
void cbUserBreakpoint()
|
||||
{
|
||||
hActiveThread = ThreadGetHandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
|
||||
|
@ -1117,6 +1134,7 @@ DWORD WINAPI threadDebugLoop(void* lpParameter)
|
|||
bIsAttached = false;
|
||||
bSkipExceptions = false;
|
||||
bBreakOnNextDll = false;
|
||||
bFreezeStack = false;
|
||||
INIT_STRUCT* init = (INIT_STRUCT*)lpParameter;
|
||||
bFileIsDll = IsFileDLLW(StringUtils::Utf8ToUtf16(init->exe).c_str(), 0);
|
||||
pDebuggedEntry = GetPE32DataW(StringUtils::Utf8ToUtf16(init->exe).c_str(), 0, UE_OEP);
|
||||
|
@ -1425,6 +1443,7 @@ DWORD WINAPI threadAttachLoop(void* lpParameter)
|
|||
lock(WAITID_STOP);
|
||||
bIsAttached = true;
|
||||
bSkipExceptions = false;
|
||||
bFreezeStack = false;
|
||||
DWORD pid = (DWORD)lpParameter;
|
||||
static PROCESS_INFORMATION pi_attached;
|
||||
fdProcessInfo = &pi_attached;
|
||||
|
|
|
@ -69,10 +69,12 @@ bool dbgisrunning();
|
|||
bool dbgisdll();
|
||||
void dbgsetattachevent(HANDLE handle);
|
||||
void DebugUpdateGui(duint disasm_addr, bool stack);
|
||||
void DebugUpdateStack(duint dumpAddr, duint csp, bool forceDump = false);
|
||||
void dbgsetskipexceptions(bool skip);
|
||||
void dbgsetstepping(bool stepping);
|
||||
void dbgsetispausedbyuser(bool b);
|
||||
void dbgsetisdetachedbyuser(bool b);
|
||||
void dbgsetfreezestack(bool freeze);
|
||||
void dbgclearignoredexceptions();
|
||||
void dbgaddignoredexception(ExceptionRange range);
|
||||
bool dbgisignoredexception(unsigned int exception);
|
||||
|
|
|
@ -1056,7 +1056,7 @@ CMDRESULT cbDebugStackDump(int argc, char* argv[])
|
|||
duint size = 0;
|
||||
duint base = MemFindBaseAddr(csp, &size);
|
||||
if(base && addr >= base && addr < (base + size))
|
||||
GuiStackDumpAt(addr, csp);
|
||||
DebugUpdateStack(addr, csp, true);
|
||||
else
|
||||
dputs("Invalid stack address!");
|
||||
return STATUS_CONTINUE;
|
||||
|
@ -2102,3 +2102,16 @@ CMDRESULT cbDebugSkip(int argc, char* argv[])
|
|||
DebugUpdateGui(cip, false); //update GUI
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugSetfreezestack(int argc, char* argv[])
|
||||
{
|
||||
if (argc < 2)
|
||||
{
|
||||
dputs("Not enough arguments!");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
bool freeze = *argv[1] != '0';
|
||||
dbgsetfreezestack(freeze);
|
||||
dprintf("Stack is now %s\n", freeze ? "freezed" : "unfreezed");
|
||||
return STATUS_CONTINUE;
|
||||
}
|
|
@ -64,6 +64,7 @@ CMDRESULT cbDebugDownloadSymbol(int argc, char* argv[]);
|
|||
CMDRESULT cbDebugGetPageRights(int argc, char* argv[]);
|
||||
CMDRESULT cbDebugSetPageRights(int argc, char* argv[]);
|
||||
CMDRESULT cbDebugSkip(int argc, char* argv[]);
|
||||
CMDRESULT cbDebugSetfreezestack(int argc, char* argv[]);
|
||||
|
||||
//misc
|
||||
void showcommandlineerror(cmdline_error_t* cmdline_error);
|
||||
|
|
|
@ -767,7 +767,7 @@ CMDRESULT cbInstrPush(int argc, char* argv[])
|
|||
}
|
||||
Script::Stack::Push(value);
|
||||
duint csp = GetContextDataEx(hActiveThread, UE_CSP);
|
||||
GuiStackDumpAt(csp, csp);
|
||||
DebugUpdateStack(csp, csp);
|
||||
GuiUpdateRegisterView();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
@ -776,7 +776,7 @@ CMDRESULT cbInstrPop(int argc, char* argv[])
|
|||
{
|
||||
duint value = Script::Stack::Pop();
|
||||
duint csp = GetContextDataEx(hActiveThread, UE_CSP);
|
||||
GuiStackDumpAt(csp, csp);
|
||||
DebugUpdateStack(csp, csp);
|
||||
GuiUpdateRegisterView();
|
||||
if (argc > 1)
|
||||
{
|
||||
|
|
|
@ -2187,7 +2187,7 @@ bool valtostring(const char* string, duint value, bool silent)
|
|||
else if(strstr(regName(), "sp")) //update stack
|
||||
{
|
||||
duint csp = GetContextDataEx(hActiveThread, UE_CSP);
|
||||
GuiStackDumpAt(csp, csp);
|
||||
DebugUpdateStack(csp, csp);
|
||||
GuiUpdateRegisterView();
|
||||
}
|
||||
else
|
||||
|
|
|
@ -94,6 +94,7 @@ static void registercommands()
|
|||
dbgcmdnew("setcmdline\1setcommandline", cbDebugSetCmdline, true); //Set CmdLine
|
||||
dbgcmdnew("loadlib", cbDebugLoadLib, true); //Load DLL
|
||||
dbgcmdnew("skip", cbDebugSkip, true); //skip one instruction
|
||||
dbgcmdnew("setfreezestack", cbDebugSetfreezestack, false); //freeze the stack from auto updates
|
||||
|
||||
//breakpoints
|
||||
dbgcmdnew("bplist", cbDebugBplist, true); //breakpoint list
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "Disassembly.h"
|
||||
#include "Configuration.h"
|
||||
#include "Bridge.h"
|
||||
#include "MainWindow.h"
|
||||
|
||||
Disassembly::Disassembly(QWidget* parent) : AbstractTableView(parent)
|
||||
{
|
||||
|
@ -1271,6 +1272,7 @@ void Disassembly::disassembleAt(dsint parVA, dsint parCIP, bool history, dsint n
|
|||
{
|
||||
dsint wBase = DbgMemFindBaseAddr(parVA, 0);
|
||||
dsint wSize = DbgMemGetPageSize(wBase);
|
||||
|
||||
if(!wBase || !wSize)
|
||||
return;
|
||||
dsint wRVA = parVA - wBase;
|
||||
|
@ -1300,6 +1302,7 @@ void Disassembly::disassembleAt(dsint parVA, dsint parCIP, bool history, dsint n
|
|||
mCurrentVa++;
|
||||
newHistory.va = selectionVA;
|
||||
newHistory.tableOffset = selectionTableOffset;
|
||||
newHistory.windowTitle = MainWindow::windowTitle;
|
||||
mVaHistory.push_back(newHistory);
|
||||
}
|
||||
}
|
||||
|
@ -1360,6 +1363,7 @@ void Disassembly::disassembleAt(dsint parVA, dsint parCIP, bool history, dsint n
|
|||
//new disassembled address
|
||||
newHistory.va = parVA;
|
||||
newHistory.tableOffset = getTableOffset();
|
||||
newHistory.windowTitle = MainWindow::windowTitle;
|
||||
if(mVaHistory.size())
|
||||
{
|
||||
if(mVaHistory.last().va != parVA) //not 2x the same va in history
|
||||
|
@ -1469,6 +1473,9 @@ void Disassembly::historyPrevious()
|
|||
return;
|
||||
mCurrentVa--;
|
||||
disassembleAt(mVaHistory.at(mCurrentVa).va, rvaToVa(mCipRva), false, mVaHistory.at(mCurrentVa).tableOffset);
|
||||
|
||||
// Update window title
|
||||
emit updateWindowTitle(mVaHistory.at(mCurrentVa).windowTitle);
|
||||
}
|
||||
|
||||
void Disassembly::historyNext()
|
||||
|
@ -1478,6 +1485,9 @@ void Disassembly::historyNext()
|
|||
return;
|
||||
mCurrentVa++;
|
||||
disassembleAt(mVaHistory.at(mCurrentVa).va, rvaToVa(mCipRva), false, mVaHistory.at(mCurrentVa).tableOffset);
|
||||
|
||||
// Update window title
|
||||
emit updateWindowTitle(mVaHistory.at(mCurrentVa).windowTitle);
|
||||
}
|
||||
|
||||
bool Disassembly::historyHasPrevious()
|
||||
|
|
|
@ -98,6 +98,7 @@ public:
|
|||
signals:
|
||||
void selectionChanged(dsint parVA);
|
||||
void disassembledAt(dsint parVA, dsint parCIP, bool history, dsint newTableOffset);
|
||||
void updateWindowTitle(QString title);
|
||||
|
||||
public slots:
|
||||
void disassembleAt(dsint parVA, dsint parCIP);
|
||||
|
@ -131,6 +132,7 @@ private:
|
|||
{
|
||||
dsint va;
|
||||
dsint tableOffset;
|
||||
QString windowTitle;
|
||||
} HistoryData_t;
|
||||
|
||||
QList<HistoryData_t> mVaHistory;
|
||||
|
|
|
@ -11,6 +11,7 @@ CPUStack::CPUStack(QWidget* parent) : HexDump(parent)
|
|||
int charwidth = getCharWidth();
|
||||
ColumnDescriptor_t wColDesc;
|
||||
DataDescriptor_t dDesc;
|
||||
bStackFrozen = false;
|
||||
|
||||
mForceColumn = 1;
|
||||
|
||||
|
@ -42,6 +43,8 @@ CPUStack::CPUStack(QWidget* parent) : HexDump(parent)
|
|||
connect(Bridge::getBridge(), SIGNAL(stackDumpAt(duint, duint)), this, SLOT(stackDumpAt(duint, duint)));
|
||||
connect(Bridge::getBridge(), SIGNAL(selectionStackGet(SELECTIONDATA*)), this, SLOT(selectionGet(SELECTIONDATA*)));
|
||||
connect(Bridge::getBridge(), SIGNAL(selectionStackSet(const SELECTIONDATA*)), this, SLOT(selectionSet(const SELECTIONDATA*)));
|
||||
connect(Bridge::getBridge(), SIGNAL(dbgStateChanged(DBGSTATE)), this, SLOT(dbgStateChangedSlot(DBGSTATE)));
|
||||
|
||||
|
||||
Initialize();
|
||||
}
|
||||
|
@ -125,6 +128,10 @@ void CPUStack::setupContextMenu()
|
|||
connect(mGotoSp, SIGNAL(triggered()), this, SLOT(gotoSpSlot()));
|
||||
connect(mGotoBp, SIGNAL(triggered()), this, SLOT(gotoBpSlot()));
|
||||
|
||||
mFreezeStack = new QAction("Freeze stack", this);
|
||||
this->addAction(mFreezeStack);
|
||||
connect(mFreezeStack, SIGNAL(triggered()), this, SLOT(freezeStackSlot()));
|
||||
|
||||
//Find Pattern
|
||||
mFindPatternAction = new QAction("&Find Pattern...", this);
|
||||
mFindPatternAction->setShortcutContext(Qt::WidgetShortcut);
|
||||
|
@ -156,6 +163,24 @@ void CPUStack::setupContextMenu()
|
|||
connect(Config(), SIGNAL(shortcutsUpdated()), this, SLOT(refreshShortcutsSlot()));
|
||||
}
|
||||
|
||||
void CPUStack::updateFreezeStackAction()
|
||||
{
|
||||
QFont font = mFreezeStack->font();
|
||||
|
||||
if(bStackFrozen)
|
||||
{
|
||||
font.setBold(true);
|
||||
mFreezeStack->setFont(font);
|
||||
mFreezeStack->setText("Unfreeze the stack");
|
||||
}
|
||||
else
|
||||
{
|
||||
font.setBold(false);
|
||||
mFreezeStack->setFont(font);
|
||||
mFreezeStack->setText("Freeze the stack");
|
||||
}
|
||||
}
|
||||
|
||||
void CPUStack::refreshShortcutsSlot()
|
||||
{
|
||||
mBinaryEditAction->setShortcut(ConfigShortcut("ActionBinaryEdit"));
|
||||
|
@ -180,6 +205,10 @@ QString CPUStack::paintContent(QPainter* painter, dsint rowBase, int rowOffset,
|
|||
dsint wRva = (rowBase + rowOffset) * wBytePerRowCount - mByteOffset;
|
||||
duint wVa = rvaToVa(wRva);
|
||||
|
||||
// This sets the first visible row to be selected when stack is frozen, so that we can scroll the stack without it being reset to first selection
|
||||
if(bStackFrozen && rowOffset == 0)
|
||||
setSingleSelection(wRva);
|
||||
|
||||
bool wIsSelected = isSelected(wRva);
|
||||
if(wIsSelected) //highlight if selected
|
||||
painter->fillRect(QRect(x, y, w, h), QBrush(selectionColor));
|
||||
|
@ -320,6 +349,7 @@ void CPUStack::contextMenuEvent(QContextMenuEvent* event)
|
|||
wMenu->addAction(mFindPatternAction);
|
||||
wMenu->addAction(mGotoSp);
|
||||
wMenu->addAction(mGotoBp);
|
||||
wMenu->addAction(mFreezeStack);
|
||||
wMenu->addAction(mGotoExpression);
|
||||
|
||||
duint selectedData;
|
||||
|
@ -596,3 +626,23 @@ void CPUStack::modifySlot()
|
|||
mMemPage->write(&value, addr, sizeof(dsint));
|
||||
reloadData();
|
||||
}
|
||||
|
||||
void CPUStack::freezeStackSlot()
|
||||
{
|
||||
if(bStackFrozen)
|
||||
DbgCmdExec(QString("setfreezestack 0").toUtf8().constData());
|
||||
else
|
||||
DbgCmdExec(QString("setfreezestack 1").toUtf8().constData());
|
||||
|
||||
bStackFrozen = !bStackFrozen;
|
||||
|
||||
updateFreezeStackAction();
|
||||
}
|
||||
|
||||
void CPUStack::dbgStateChangedSlot(DBGSTATE state)
|
||||
{
|
||||
if(state == initialized)
|
||||
bStackFrozen = false;
|
||||
|
||||
updateFreezeStackAction();
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ public:
|
|||
void contextMenuEvent(QContextMenuEvent* event);
|
||||
void mouseDoubleClickEvent(QMouseEvent* event);
|
||||
void setupContextMenu();
|
||||
void updateFreezeStackAction();
|
||||
|
||||
signals:
|
||||
void displayReferencesWidget();
|
||||
|
@ -41,9 +42,12 @@ public slots:
|
|||
void binaryPasteIgnoreSizeSlot();
|
||||
void undoSelectionSlot();
|
||||
void modifySlot();
|
||||
void freezeStackSlot();
|
||||
void dbgStateChangedSlot(DBGSTATE state);
|
||||
|
||||
private:
|
||||
duint mCsp;
|
||||
bool bStackFrozen;
|
||||
|
||||
QMenu* mBinaryMenu;
|
||||
QAction* mBinaryEditAction;
|
||||
|
@ -55,6 +59,7 @@ private:
|
|||
QAction* mUndoSelection;
|
||||
QAction* mGotoSp;
|
||||
QAction* mGotoBp;
|
||||
QAction* mFreezeStack;
|
||||
QAction* mGotoExpression;
|
||||
QAction* mFindPatternAction;
|
||||
QAction* mFollowDisasm;
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
#include "AttachDialog.h"
|
||||
#include "LineEditDialog.h"
|
||||
|
||||
QString MainWindow::windowTitle = "";
|
||||
|
||||
MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), ui(new Ui::MainWindow)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
@ -233,6 +235,7 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), ui(new Ui::MainWi
|
|||
connect(ui->actionChangeCommandLine, SIGNAL(triggered()), this, SLOT(changeCommandLine()));
|
||||
connect(ui->actionManual, SIGNAL(triggered()), this, SLOT(displayManual()));
|
||||
|
||||
connect(mCpuWidget->getDisasmWidget(), SIGNAL(updateWindowTitle(QString)), this, SLOT(updateWindowTitleSlot(QString)));
|
||||
connect(mCpuWidget->getDisasmWidget(), SIGNAL(displayReferencesWidget()), this, SLOT(displayReferencesWidget()));
|
||||
connect(mCpuWidget->getDisasmWidget(), SIGNAL(displaySourceManagerWidget()), this, SLOT(displaySourceViewWidget()));
|
||||
connect(mCpuWidget->getDisasmWidget(), SIGNAL(displaySnowmanWidget()), this, SLOT(displaySnowmanWidget()));
|
||||
|
@ -645,9 +648,15 @@ void MainWindow::dropEvent(QDropEvent* pEvent)
|
|||
void MainWindow::updateWindowTitleSlot(QString filename)
|
||||
{
|
||||
if(filename.length())
|
||||
{
|
||||
setWindowTitle(QString(mWindowMainTitle) + QString(" - ") + filename);
|
||||
windowTitle = filename;
|
||||
}
|
||||
else
|
||||
{
|
||||
setWindowTitle(QString(mWindowMainTitle));
|
||||
windowTitle = QString(mWindowMainTitle);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::execeStepOver()
|
||||
|
|
|
@ -190,6 +190,9 @@ private:
|
|||
protected:
|
||||
void dragEnterEvent(QDragEnterEvent* pEvent);
|
||||
void dropEvent(QDropEvent* pEvent);
|
||||
|
||||
public:
|
||||
static QString windowTitle;
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
||||
|
|
Loading…
Reference in New Issue