18
18
#include < QApplication>
19
19
#include < QPushButton>
20
20
21
- DisassemblyContextMenu::DisassemblyContextMenu (QWidget *parent, MainWindow* mainWindow)
21
+ DisassemblyContextMenu::DisassemblyContextMenu (QWidget *parent, MainWindow * mainWindow)
22
22
: QMenu(parent),
23
23
offset(0 ),
24
24
canCopy(false ),
@@ -27,7 +27,8 @@ DisassemblyContextMenu::DisassemblyContextMenu(QWidget *parent, MainWindow* main
27
27
initAction (&actionCopy, tr (" Copy" ), SLOT (on_actionCopy_triggered ()), getCopySequence ());
28
28
addAction (&actionCopy);
29
29
30
- initAction (&actionCopyAddr, tr (" Copy address" ), SLOT (on_actionCopyAddr_triggered ()), getCopyAddressSequence ());
30
+ initAction (&actionCopyAddr, tr (" Copy address" ), SLOT (on_actionCopyAddr_triggered ()),
31
+ getCopyAddressSequence ());
31
32
addAction (&actionCopyAddr);
32
33
33
34
initAction (&showInSubmenu, tr (" Show in" ), nullptr );
@@ -112,9 +113,6 @@ DisassemblyContextMenu::DisassemblyContextMenu(QWidget *parent, MainWindow* main
112
113
113
114
DisassemblyContextMenu::~DisassemblyContextMenu ()
114
115
{
115
- for (QAction *action : anonymousActions) {
116
- delete action;
117
- }
118
116
}
119
117
120
118
void DisassemblyContextMenu::addSetBaseMenu ()
@@ -249,6 +247,65 @@ void DisassemblyContextMenu::addDebugMenu()
249
247
debugMenu->addAction (&actionSetPC);
250
248
}
251
249
250
+ QVector<DisassemblyContextMenu::ThingUsedHere> DisassemblyContextMenu::getThingUsedHere (RVA offset)
251
+ {
252
+ QVector<ThingUsedHere> result;
253
+ const QJsonArray array = Core ()->cmdj (" anj @ " + QString::number (offset)).array ();
254
+ result.reserve (array.size ());
255
+ for (const auto &thing : array) {
256
+ auto obj = thing.toObject ();
257
+ RVA offset = obj[" offset" ].toVariant ().toULongLong ();
258
+ QString name = obj[" name" ].toString ();
259
+ QString typeString = obj[" type" ].toString ();
260
+ ThingUsedHere::Type type = ThingUsedHere::Type::Address;
261
+ if (typeString == " var" ) {
262
+ type = ThingUsedHere::Type::Var;
263
+ } else if (typeString == " flag" ) {
264
+ type = ThingUsedHere::Type::Flag;
265
+ } else if (typeString == " function" ) {
266
+ type = ThingUsedHere::Type::Function;
267
+ } else if (typeString == " address" ) {
268
+ type = ThingUsedHere::Type::Address;
269
+ }
270
+ result.push_back (ThingUsedHere{name, offset, type});
271
+ }
272
+ return result;
273
+ }
274
+
275
+ void DisassemblyContextMenu::updateTargetMenuActions (const QVector<ThingUsedHere> &targets)
276
+ {
277
+ for (auto action : showTargetMenuActions) {
278
+ removeAction (action);
279
+ auto menu = action->menu ();
280
+ if (menu) {
281
+ menu->deleteLater ();
282
+ }
283
+ action->deleteLater ();
284
+ }
285
+ showTargetMenuActions.clear ();
286
+ for (auto &target : targets) {
287
+ QString name;
288
+ if (target.name .isEmpty ()) {
289
+ name = tr (" %1 (used here)" ).arg (RAddressString (target.offset ));
290
+ } else {
291
+ name = tr (" %1 (%2)" ).arg (target.name , RAddressString (target.offset ));
292
+ }
293
+ auto action = new QAction (name, this );
294
+ showTargetMenuActions.append (action);
295
+ auto menu = mainWindow->createShowInMenu (this , target.offset );
296
+ action->setMenu (menu);
297
+ QAction *copyAddress = new QAction (tr (" Copy address" ), menu);
298
+ RVA offset = target.offset ;
299
+ connect (copyAddress, &QAction::triggered, copyAddress, [offset]() {
300
+ QClipboard *clipboard = QApplication::clipboard ();
301
+ clipboard->setText (RAddressString (offset));
302
+ });
303
+ menu->addSeparator ();
304
+ menu->addAction (copyAddress);
305
+ }
306
+ insertActions (copySeparator, showTargetMenuActions);
307
+ }
308
+
252
309
void DisassemblyContextMenu::setOffset (RVA offset)
253
310
{
254
311
this ->offset = offset;
@@ -362,24 +419,22 @@ void DisassemblyContextMenu::aboutToShowSlot()
362
419
363
420
364
421
// Only show "rename X used here" if there is something to rename
365
- QJsonArray thingUsedHereArray = Core ()-> cmdj ( " anj @ " + QString::number ( offset)). array ( );
366
- if (!thingUsedHereArray .isEmpty ()) {
422
+ auto thingsUsedHere = getThingUsedHere ( offset);
423
+ if (!thingsUsedHere .isEmpty ()) {
367
424
actionRenameUsedHere.setVisible (true );
368
- QJsonObject thingUsedHere = thingUsedHereArray .first (). toObject ();
369
- if (thingUsedHere[ " type" ] == " address " ) {
370
- RVA offset = thingUsedHere[ " offset " ]. toVariant (). toULongLong () ;
425
+ auto & thingUsedHere = thingsUsedHere .first ();
426
+ if (thingUsedHere. type == ThingUsedHere::Type::Address ) {
427
+ RVA offset = thingUsedHere. offset ;
371
428
actionRenameUsedHere.setText (tr (" Add flag at %1 (used here)" ).arg (RAddressString (offset)));
372
- } else {
373
- if (thingUsedHere[" type" ] == " function" ) {
374
- actionRenameUsedHere.setText (tr (" Rename \" %1\" " ).arg (thingUsedHere[" name" ].toString ()));
375
- }
376
- else {
377
- actionRenameUsedHere.setText (tr (" Rename \" %1\" (used here)" ).arg (thingUsedHere[" name" ].toString ()));
378
- }
429
+ } else if (thingUsedHere.type == ThingUsedHere::Type::Function) {
430
+ actionRenameUsedHere.setText (tr (" Rename \" %1\" " ).arg (thingUsedHere.name ));
431
+ } else {
432
+ actionRenameUsedHere.setText (tr (" Rename \" %1\" (used here)" ).arg (thingUsedHere.name ));
379
433
}
380
434
} else {
381
435
actionRenameUsedHere.setVisible (false );
382
436
}
437
+ updateTargetMenuActions (thingsUsedHere);
383
438
384
439
// Decide to show Reverse jmp option
385
440
showReverseJmpQuery ();
@@ -686,38 +741,39 @@ void DisassemblyContextMenu::on_actionRename_triggered()
686
741
687
742
void DisassemblyContextMenu::on_actionRenameUsedHere_triggered ()
688
743
{
689
- QJsonArray array = Core ()-> cmdj ( " anj @ " + QString::number ( offset)). array ( );
744
+ auto array = getThingUsedHere ( offset);
690
745
if (array.isEmpty ()) {
691
746
return ;
692
747
}
693
748
694
- QJsonObject thingUsedHere = array.first ().toObject ();
695
- QString type = thingUsedHere.value (" type" ).toString ();
749
+ auto thingUsedHere = array.first ();
696
750
697
751
RenameDialog dialog (this );
698
752
699
753
QString oldName;
754
+ auto type = thingUsedHere.type ;
700
755
701
- if (type == " address " ) {
702
- RVA offset = thingUsedHere[ " offset " ]. toVariant (). toULongLong () ;
756
+ if (type == ThingUsedHere::Type::Address ) {
757
+ RVA offset = thingUsedHere. offset ;
703
758
dialog.setWindowTitle (tr (" Add flag at %1" ).arg (RAddressString (offset)));
704
759
dialog.setName (" label." + QString::number (offset, 16 ));
705
760
} else {
706
- oldName = thingUsedHere.value ( " name" ). toString () ;
761
+ oldName = thingUsedHere.name ;
707
762
dialog.setWindowTitle (tr (" Rename %1" ).arg (oldName));
708
763
dialog.setName (oldName);
709
764
}
710
765
766
+
711
767
if (dialog.exec ()) {
712
768
QString newName = dialog.getName ().trimmed ();
713
769
if (!newName.isEmpty ()) {
714
770
Core ()->cmd (" an " + newName + " @ " + QString::number (offset));
715
771
716
- if (type == " address " || type == " flag " ) {
772
+ if (type == ThingUsedHere::Type::Address || type == ThingUsedHere::Type::Address ) {
717
773
Core ()->triggerFlagsChanged ();
718
- } else if (type == " var " ) {
774
+ } else if (type == ThingUsedHere::Type::Var ) {
719
775
Core ()->triggerVarsChanged ();
720
- } else if (type == " function " ) {
776
+ } else if (type == ThingUsedHere::Type::Function ) {
721
777
Core ()->triggerFunctionRenamed (oldName, newName);
722
778
}
723
779
}
@@ -729,7 +785,8 @@ void DisassemblyContextMenu::on_actionSetFunctionVarTypes_triggered()
729
785
RAnalFunction *fcn = Core ()->functionAt (offset);
730
786
731
787
if (!fcn) {
732
- QMessageBox::critical (this , tr (" Re-type function local vars" ), tr (" You must be in a function to define variable types." ));
788
+ QMessageBox::critical (this , tr (" Re-type function local vars" ),
789
+ tr (" You must be in a function to define variable types." ));
733
790
return ;
734
791
}
735
792
@@ -873,7 +930,7 @@ void DisassemblyContextMenu::setToData(int size, int repeat)
873
930
QAction *DisassemblyContextMenu::addAnonymousAction (QString name, const char *slot,
874
931
QKeySequence keySequence)
875
932
{
876
- auto action = new QAction ();
933
+ auto action = new QAction (this );
877
934
addAction (action);
878
935
anonymousActions.append (action);
879
936
initAction (action, name, slot, keySequence);
0 commit comments