1
0
Fork 0

Follow in Dump N + Graph

This commit is contained in:
torusrxxx 2020-11-20 18:26:20 +08:00
parent 72c958754d
commit 9e901cd8eb
No known key found for this signature in database
GPG Key ID: A795C73A0F1CFADD
10 changed files with 59 additions and 102 deletions

View File

@ -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

View File

@ -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");

View File

@ -105,7 +105,6 @@ public slots:
void removeAnalysisModuleSlot();
void setEncodeTypeSlot();
void setEncodeTypeRangeSlot();
void graphSlot();
void analyzeModuleSlot();
void copyTokenTextSlot();
void copyTokenValueSlot();

View File

@ -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);

View File

@ -81,7 +81,6 @@ public slots:
void selectionUpdatedSlot();
void syncWithExpressionSlot();
void followInDumpNSlot();
void allocMemorySlot();
void headerButtonReleasedSlot(int colIndex);

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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())

View File

@ -68,6 +68,7 @@ public slots:
void setHwBpOnSlot3ActionSlot();
void setHwBpAt(duint va, int slot);
void graphSlot();
void setNewOriginHereActionSlot();
void createThreadSlot();
private: