Follow in Dump N + Graph
This commit is contained in:
parent
72c958754d
commit
9e901cd8eb
|
|
@ -39,7 +39,7 @@ BreakpointsView::BreakpointsView(QWidget* parent)
|
|||
|
||||
void BreakpointsView::setupContextMenu()
|
||||
{
|
||||
mMenuBuilder = new MenuBuilder(this, [this](QMenu*)
|
||||
mMenuBuilder = new MenuBuilder(this, [](QMenu*)
|
||||
{
|
||||
return DbgIsDebugging();
|
||||
});
|
||||
|
|
@ -48,7 +48,14 @@ void BreakpointsView::setupContextMenu()
|
|||
{
|
||||
return isValidBp();
|
||||
};
|
||||
|
||||
mMenuBuilder->addAction(makeAction(DIcon(ArchValue("processor32.png", "processor64.png")), tr("Follow breakpoint"), SLOT(followBreakpointSlot())), [this](QMenu*)
|
||||
{
|
||||
if(!isValidBp())
|
||||
return false;
|
||||
if(selectedBp().type == bp_exception)
|
||||
return false;
|
||||
return true;
|
||||
});
|
||||
mMenuBuilder->addAction(makeShortcutAction(DIcon("breakpoint_remove.png"), tr("&Remove"), SLOT(removeBreakpointSlot()), "ActionDeleteBreakpoint"), validBp);
|
||||
QAction* enableDisableBreakpoint = makeShortcutAction(DIcon("breakpoint_disable.png"), tr("Disable"), SLOT(toggleBreakpointSlot()), "ActionEnableDisableBreakpoint");
|
||||
mMenuBuilder->addAction(enableDisableBreakpoint, [this, enableDisableBreakpoint](QMenu*)
|
||||
|
|
@ -557,10 +564,16 @@ void BreakpointsView::followBreakpointSlot()
|
|||
return;
|
||||
auto & bp = selectedBp();
|
||||
if(bp.type == bp_exception || !bp.active)
|
||||
{
|
||||
GuiAddStatusBarMessage(tr("Cannot follow this breakpoint.\n").toUtf8().constData());
|
||||
return;
|
||||
}
|
||||
duint addr = bp.type == bp_dll ? DbgModBaseFromName(bp.mod) : bp.addr;
|
||||
if(!DbgMemIsValidReadPtr(addr))
|
||||
{
|
||||
GuiAddStatusBarMessage(tr("Cannot follow this breakpoint.\n").toUtf8().constData());
|
||||
return;
|
||||
}
|
||||
if(DbgFunctions()->MemIsCodePage(addr, false))
|
||||
DbgCmdExecDirect(QString("disasm %1").arg(ToPtrString(addr)));
|
||||
else
|
||||
|
|
|
|||
|
|
@ -311,7 +311,7 @@ void CPUDisassembly::setupRightClickContextMenu()
|
|||
{
|
||||
return rvaToVa(getInitialSelection());
|
||||
});
|
||||
mCommonActions->build(mMenuBuilder, CommonActions::ActionBreakpoint | CommonActions::ActionMemoryMap | CommonActions::ActionComment | CommonActions::ActionBookmark);
|
||||
mCommonActions->build(mMenuBuilder, CommonActions::ActionBreakpoint | CommonActions::ActionMemoryMap | CommonActions::ActionGraph | CommonActions::ActionComment | CommonActions::ActionBookmark);
|
||||
|
||||
mMenuBuilder->addMenu(makeMenu(DIcon("dump.png"), tr("&Follow in Dump")), [this](QMenu * menu)
|
||||
{
|
||||
|
|
@ -332,8 +332,6 @@ void CPUDisassembly::setupRightClickContextMenu()
|
|||
return DbgFunctions()->GetSourceFromAddr(rvaToVa(getInitialSelection()), 0, 0);
|
||||
});
|
||||
|
||||
mMenuBuilder->addAction(makeShortcutAction(DIcon("graph.png"), tr("Graph"), SLOT(graphSlot()), "ActionGraph"));
|
||||
|
||||
mMenuBuilder->addMenu(makeMenu(DIcon("help.png"), tr("Help on Symbolic Name")), [this](QMenu * menu)
|
||||
{
|
||||
QSet<QString> labels;
|
||||
|
|
@ -1902,12 +1900,6 @@ void CPUDisassembly::setEncodeTypeSlot()
|
|||
GuiUpdateDisassemblyView();
|
||||
}
|
||||
|
||||
void CPUDisassembly::graphSlot()
|
||||
{
|
||||
if(DbgCmdExecDirect(QString("graph %1").arg(ToPtrString(rvaToVa(getSelectionStart()))).toUtf8().constData()))
|
||||
GuiFocusView(GUI_GRAPH);
|
||||
}
|
||||
|
||||
void CPUDisassembly::analyzeModuleSlot()
|
||||
{
|
||||
DbgCmdExec("cfanal");
|
||||
|
|
|
|||
|
|
@ -105,7 +105,6 @@ public slots:
|
|||
void removeAnalysisModuleSlot();
|
||||
void setEncodeTypeSlot();
|
||||
void setEncodeTypeRangeSlot();
|
||||
void graphSlot();
|
||||
void analyzeModuleSlot();
|
||||
void copyTokenTextSlot();
|
||||
void copyTokenValueSlot();
|
||||
|
|
|
|||
|
|
@ -81,8 +81,8 @@ void CPUDump::setupContextMenu()
|
|||
return DbgFunctions()->PatchInRange(rvaToVa(getSelectionStart()), rvaToVa(getSelectionEnd()));
|
||||
});
|
||||
|
||||
mCommonActions->build(mMenuBuilder, CommonActions::ActionDisasm | CommonActions::ActionMemoryMap | CommonActions::ActionDumpData | CommonActions::ActionDisasmData
|
||||
| CommonActions::ActionStackDump | CommonActions::ActionLabel | CommonActions::ActionWatch);
|
||||
mCommonActions->build(mMenuBuilder, CommonActions::ActionDisasm | CommonActions::ActionMemoryMap | CommonActions::ActionDumpData | CommonActions::ActionDumpN
|
||||
| CommonActions::ActionDisasmData | CommonActions::ActionStackDump | CommonActions::ActionLabel | CommonActions::ActionWatch);
|
||||
auto wIsValidReadPtrCallback = [this](QMenu*)
|
||||
{
|
||||
duint ptr = 0;
|
||||
|
|
@ -90,24 +90,6 @@ void CPUDump::setupContextMenu()
|
|||
return DbgMemIsValidReadPtr(ptr);
|
||||
};
|
||||
|
||||
MenuBuilder* wFollowInDumpMenu = new MenuBuilder(this, [wIsValidReadPtrCallback, this](QMenu * menu)
|
||||
{
|
||||
if(!wIsValidReadPtrCallback(menu))
|
||||
return false;
|
||||
QList<QString> tabNames;
|
||||
mMultiDump->getTabNames(tabNames);
|
||||
for(int i = 0; i < tabNames.length(); i++)
|
||||
mFollowInDumpActions[i]->setText(tabNames[i]);
|
||||
return true;
|
||||
});
|
||||
int maxDumps = mMultiDump->getMaxCPUTabs();
|
||||
for(int i = 0; i < maxDumps; i++)
|
||||
{
|
||||
QAction* action = makeAction(DIcon("dump.png"), QString(), SLOT(followInDumpNSlot()));
|
||||
wFollowInDumpMenu->addAction(action);
|
||||
mFollowInDumpActions.push_back(action);
|
||||
}
|
||||
mMenuBuilder->addMenu(makeMenu(DIcon("dump.png"), ArchValue(tr("&Follow DWORD in Dump"), tr("&Follow QWORD in Dump"))), wFollowInDumpMenu);
|
||||
mMenuBuilder->addAction(makeShortcutAction(DIcon("modify.png"), tr("&Modify Value"), SLOT(modifyValueSlot()), "ActionModifyValue"), [this](QMenu*)
|
||||
{
|
||||
return getSizeOf(mDescriptor.at(0).data.itemSize) <= sizeof(duint);
|
||||
|
|
@ -1483,13 +1465,6 @@ void CPUDump::syncWithExpressionSlot()
|
|||
updateDumpSlot();
|
||||
}
|
||||
|
||||
void CPUDump::followInDumpNSlot()
|
||||
{
|
||||
for(int i = 0; i < mFollowInDumpActions.length(); i++)
|
||||
if(mFollowInDumpActions[i] == sender())
|
||||
DbgCmdExec(QString("dump \"[%1]\", \"%2\"").arg(ToPtrString(rvaToVa(getSelectionStart()))).arg(i + 1));
|
||||
}
|
||||
|
||||
void CPUDump::allocMemorySlot()
|
||||
{
|
||||
WordEditDialog mLineEdit(this);
|
||||
|
|
|
|||
|
|
@ -81,7 +81,6 @@ public slots:
|
|||
|
||||
void selectionUpdatedSlot();
|
||||
void syncWithExpressionSlot();
|
||||
void followInDumpNSlot();
|
||||
void allocMemorySlot();
|
||||
|
||||
void headerButtonReleasedSlot(int colIndex);
|
||||
|
|
|
|||
|
|
@ -282,22 +282,7 @@ void CPUStack::setupContextMenu()
|
|||
//Follow PTR in Dump
|
||||
auto followDumpName = ArchValue(tr("Follow DWORD in &Dump"), tr("Follow QWORD in &Dump"));
|
||||
|
||||
//Follow in Dump N menu
|
||||
auto followDumpNMenu = new MenuBuilder(this, [this](QMenu*)
|
||||
{
|
||||
duint ptr;
|
||||
return DbgMemRead(rvaToVa(getInitialSelection()), (unsigned char*)&ptr, sizeof(ptr)) && DbgMemIsValidReadPtr(ptr);
|
||||
});
|
||||
int maxDumps = mMultiDump->getMaxCPUTabs();
|
||||
for(int i = 0; i < maxDumps; i++)
|
||||
{
|
||||
auto action = makeAction(tr("Dump %1").arg(i + 1), SLOT(followinDumpNSlot()));
|
||||
followDumpNMenu->addAction(action);
|
||||
mFollowInDumpActions.push_back(action);
|
||||
}
|
||||
mMenuBuilder->addMenu(makeMenu(DIcon("dump.png"), followDumpName.replace("&", "")), followDumpNMenu);
|
||||
|
||||
mCommonActions->build(mMenuBuilder, CommonActions::ActionWatch);
|
||||
mCommonActions->build(mMenuBuilder, CommonActions::ActionDumpN | CommonActions::ActionWatch);
|
||||
|
||||
mPluginMenu = new QMenu(this);
|
||||
Bridge::getBridge()->emitMenuAddToList(this, mPluginMenu, GUI_STACK_MENU);
|
||||
|
|
@ -721,23 +706,6 @@ void CPUStack::followDisasmSlot()
|
|||
}
|
||||
}
|
||||
|
||||
void CPUStack::followinDumpNSlot()
|
||||
{
|
||||
duint selectedData = rvaToVa(getInitialSelection());
|
||||
|
||||
if(DbgMemIsValidReadPtr(selectedData))
|
||||
{
|
||||
for(int i = 0; i < mFollowInDumpActions.length(); i++)
|
||||
{
|
||||
if(mFollowInDumpActions[i] == sender())
|
||||
{
|
||||
QString addrText = QString("%1").arg(ToPtrString(selectedData));
|
||||
DbgCmdExec(QString("dump [%1], %2").arg(addrText.toUtf8().constData()).arg(i + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CPUStack::followStackSlot()
|
||||
{
|
||||
duint selectedData;
|
||||
|
|
|
|||
|
|
@ -42,7 +42,6 @@ public slots:
|
|||
void selectionSet(const SELECTIONDATA* selection);
|
||||
void selectionUpdatedSlot();
|
||||
void followDisasmSlot();
|
||||
void followinDumpNSlot();
|
||||
void followStackSlot();
|
||||
void binaryEditSlot();
|
||||
void binaryFillSlot();
|
||||
|
|
@ -64,7 +63,6 @@ private:
|
|||
QAction* mFreezeStack;
|
||||
QAction* mFollowStack;
|
||||
QAction* mFollowDisasm;
|
||||
QList<QAction*> mFollowInDumpActions;
|
||||
QMenu* mPluginMenu;
|
||||
|
||||
GotoDialog* mGoto;
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ CPUWidget::CPUWidget(QWidget* parent) : QWidget(parent), ui(new Ui::CPUWidget)
|
|||
|
||||
connect(mDisas, SIGNAL(selectionChanged(dsint)), mInfo, SLOT(disasmSelectionChanged(dsint)));
|
||||
|
||||
mDump = new CPUMultiDump(mDisas, 5, 0); //dump widget
|
||||
mDump = new CPUMultiDump(mDisas, 5, this); //dump widget
|
||||
ui->mBotLeftFrameLayout->addWidget(mDump);
|
||||
|
||||
mGeneralRegs = new CPURegistersView(this);
|
||||
|
|
|
|||
|
|
@ -45,6 +45,25 @@ void CommonActions::build(MenuBuilder* builder, int actions)
|
|||
{
|
||||
builder->addAction(makeCommandAction(DIcon("dump.png"), ArchValue(tr("&Follow DWORD in Current Dump"), tr("&Follow QWORD in Current Dump")), "dump [$]", "ActionFollowDwordQwordDump"), wIsValidReadPtrCallback);
|
||||
}
|
||||
if(actions & ActionDumpN)
|
||||
{
|
||||
//Follow in Dump N menu
|
||||
MenuBuilder* followDumpNMenu = new MenuBuilder(this, [this](QMenu*)
|
||||
{
|
||||
duint ptr;
|
||||
return DbgMemRead(mGetSelection(), (unsigned char*)&ptr, sizeof(ptr)) && DbgMemIsValidReadPtr(ptr);
|
||||
});
|
||||
const int maxDumps = 5; // TODO: get this value from CPUMultiDump
|
||||
for(int i = 0; i < maxDumps; i++)
|
||||
// TODO: Get dump tab names
|
||||
followDumpNMenu->addAction(makeAction(tr("Dump %1").arg(i + 1), [i, this]
|
||||
{
|
||||
duint selectedData = mGetSelection();
|
||||
if(DbgMemIsValidReadPtr(selectedData))
|
||||
DbgCmdExec(QString("dump [%1], %2").arg(ToPtrString(selectedData)).arg(i + 1));
|
||||
}));
|
||||
builder->addMenu(makeMenu(DIcon("dump.png"), ArchValue(tr("Follow DWORD in Dump"), tr("Follow QWORD in Dump"))), followDumpNMenu);
|
||||
}
|
||||
if(actions & ActionStackDump)
|
||||
{
|
||||
builder->addAction(makeCommandAction(DIcon("stack.png"), tr("Follow in Stack"), "sdump $", "ActionFollowStack"), [this](QMenu*)
|
||||
|
|
@ -57,6 +76,10 @@ void CommonActions::build(MenuBuilder* builder, int actions)
|
|||
{
|
||||
builder->addAction(makeCommandAction(DIcon("memmap_find_address_page.png"), tr("Follow in Memory Map"), "memmapdump $", "ActionFollowMemMap"), wIsDebugging);
|
||||
}
|
||||
if(actions & ActionGraph)
|
||||
{
|
||||
builder->addAction(makeShortcutAction(DIcon("graph.png"), tr("Graph"), std::bind(&CommonActions::graphSlot, this), "ActionGraph"));
|
||||
}
|
||||
if(actions & ActionBreakpoint)
|
||||
{
|
||||
QAction* toggleBreakpointAction = makeShortcutAction(DIcon("breakpoint_toggle.png"), tr("Toggle"), std::bind(&CommonActions::toggleInt3BPActionSlot, this), "ActionToggleBreakpoint");
|
||||
|
|
@ -66,10 +89,11 @@ void CommonActions::build(MenuBuilder* builder, int actions)
|
|||
|
||||
QMenu* replaceSlotMenu = makeMenu(DIcon("breakpoint_execute.png"), tr("Set Hardware on Execution"));
|
||||
// Replacement slot menu are only used when the breakpoints are full, so using "Unknown" as the placeholder. Might want to change this in case we display the menu when there are still free slots.
|
||||
QAction* replaceSlot0Action = makeMenuAction(replaceSlotMenu, DIcon("breakpoint_execute_slot1.png"), tr("Replace Slot 0 (Unknown)"), std::bind(&CommonActions::setHwBpOnSlot0ActionSlot, this));
|
||||
QAction* replaceSlot1Action = makeMenuAction(replaceSlotMenu, DIcon("breakpoint_execute_slot2.png"), tr("Replace Slot 1 (Unknown)"), std::bind(&CommonActions::setHwBpOnSlot1ActionSlot, this));
|
||||
QAction* replaceSlot2Action = makeMenuAction(replaceSlotMenu, DIcon("breakpoint_execute_slot3.png"), tr("Replace Slot 2 (Unknown)"), std::bind(&CommonActions::setHwBpOnSlot2ActionSlot, this));
|
||||
QAction* replaceSlot3Action = makeMenuAction(replaceSlotMenu, DIcon("breakpoint_execute_slot4.png"), tr("Replace Slot 3 (Unknown)"), std::bind(&CommonActions::setHwBpOnSlot3ActionSlot, this));
|
||||
QAction* replaceSlotAction[4];
|
||||
replaceSlotAction[0] = makeMenuAction(replaceSlotMenu, DIcon("breakpoint_execute_slot1.png"), tr("Replace Slot %1 (Unknown)").arg(1), std::bind(&CommonActions::setHwBpOnSlot0ActionSlot, this));
|
||||
replaceSlotAction[1] = makeMenuAction(replaceSlotMenu, DIcon("breakpoint_execute_slot2.png"), tr("Replace Slot %1 (Unknown)").arg(2), std::bind(&CommonActions::setHwBpOnSlot1ActionSlot, this));
|
||||
replaceSlotAction[2] = makeMenuAction(replaceSlotMenu, DIcon("breakpoint_execute_slot3.png"), tr("Replace Slot %1 (Unknown)").arg(3), std::bind(&CommonActions::setHwBpOnSlot2ActionSlot, this));
|
||||
replaceSlotAction[3] = makeMenuAction(replaceSlotMenu, DIcon("breakpoint_execute_slot4.png"), tr("Replace Slot %1 (Unknown)").arg(4), std::bind(&CommonActions::setHwBpOnSlot3ActionSlot, this));
|
||||
|
||||
builder->addMenu(makeMenu(DIcon("breakpoint.png"), tr("Breakpoint")), [ = ](QMenu * menu)
|
||||
{
|
||||
|
|
@ -108,25 +132,9 @@ void CommonActions::build(MenuBuilder* builder, int actions)
|
|||
{
|
||||
for(int i = 0; i < bpList.count; i++)
|
||||
{
|
||||
if(bpList.bp[i].enabled)
|
||||
if(bpList.bp[i].enabled && bpList.bp[i].slot < 4)
|
||||
{
|
||||
switch(bpList.bp[i].slot)
|
||||
{
|
||||
case 0:
|
||||
replaceSlot0Action->setText(tr("Replace Slot %1 (0x%2)").arg(1).arg(ToPtrString(bpList.bp[i].addr)));
|
||||
break;
|
||||
case 1:
|
||||
replaceSlot1Action->setText(tr("Replace Slot %1 (0x%2)").arg(2).arg(ToPtrString(bpList.bp[i].addr)));
|
||||
break;
|
||||
case 2:
|
||||
replaceSlot2Action->setText(tr("Replace Slot %1 (0x%2)").arg(3).arg(ToPtrString(bpList.bp[i].addr)));
|
||||
break;
|
||||
case 3:
|
||||
replaceSlot3Action->setText(tr("Replace Slot %1 (0x%2)").arg(4).arg(ToPtrString(bpList.bp[i].addr)));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
replaceSlotAction[bpList.bp[i].slot]->setText(tr("Replace Slot %1 (0x%2)").arg(bpList.bp[i].slot + 1).arg(ToPtrString(bpList.bp[i].addr)));
|
||||
}
|
||||
}
|
||||
menu->addMenu(replaceSlotMenu);
|
||||
|
|
@ -165,6 +173,7 @@ void CommonActions::build(MenuBuilder* builder, int actions)
|
|||
|
||||
QAction* CommonActions::makeCommandAction(const QIcon & icon, const QString & text, const char* cmd, const char* shortcut)
|
||||
{
|
||||
// sender() doesn't work in slots
|
||||
return makeShortcutAction(icon, text, [cmd, this]()
|
||||
{
|
||||
DbgCmdExec(QString(cmd).replace("$", ToPtrString(mGetSelection())));
|
||||
|
|
@ -268,10 +277,7 @@ void CommonActions::setBookmarkSlot()
|
|||
return;
|
||||
duint wVA = mGetSelection();
|
||||
bool result;
|
||||
if(DbgGetBookmarkAt(wVA))
|
||||
result = DbgSetBookmarkAt(wVA, false);
|
||||
else
|
||||
result = DbgSetBookmarkAt(wVA, true);
|
||||
result = DbgSetBookmarkAt(wVA, !DbgGetBookmarkAt(wVA));
|
||||
if(!result)
|
||||
SimpleErrorBox(widgetparent(), tr("Error!"), tr("DbgSetBookmarkAt failed!"));
|
||||
GuiUpdateAllViews();
|
||||
|
|
@ -407,6 +413,12 @@ void CommonActions::setHwBpAt(duint va, int slot)
|
|||
BridgeFree(wBPList.bp);
|
||||
}
|
||||
|
||||
void CommonActions::graphSlot()
|
||||
{
|
||||
if(DbgCmdExecDirect(QString("graph %1").arg(ToPtrString(mGetSelection()))))
|
||||
GuiFocusView(GUI_GRAPH);
|
||||
}
|
||||
|
||||
void CommonActions::setNewOriginHereActionSlot()
|
||||
{
|
||||
if(!DbgIsDebugging())
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ public slots:
|
|||
void setHwBpOnSlot3ActionSlot();
|
||||
void setHwBpAt(duint va, int slot);
|
||||
|
||||
void graphSlot();
|
||||
void setNewOriginHereActionSlot();
|
||||
void createThreadSlot();
|
||||
private:
|
||||
|
|
|
|||
Loading…
Reference in New Issue