From 21463b5c215974f253a0100231890ed909cd19e3 Mon Sep 17 00:00:00 2001 From: Christoph Egger Date: Thu, 22 Jan 2015 19:53:27 +0100 Subject: [PATCH] Allow addition of new functions The ListWidget now displays a ContextMenu where the user can add a new function by typing the address --- CMakeLists.txt | 2 ++ src/disassembler/Disassembler.hxx | 1 + src/gui/Mainwindow.cxx | 32 +++++++++++++++++++++++++-- src/gui/Mainwindow.hxx | 3 +++ src/gui/dialogs/NewFunctionDialog.cxx | 27 ++++++++++++++++++++++ src/gui/dialogs/NewFunctionDialog.hxx | 11 +++++++++ src/gui/qt.hxx | 2 ++ 7 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 src/gui/dialogs/NewFunctionDialog.cxx create mode 100644 src/gui/dialogs/NewFunctionDialog.hxx diff --git a/CMakeLists.txt b/CMakeLists.txt index 3a14e98..dfcd885 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,6 +48,7 @@ SET(frida_SOURCES src/gui/widgets/BasicBlockWidget.cxx src/gui/widgets/CFGScene.cxx src/gui/widgets/ScriptingDock.cxx + src/gui/dialogs/NewFunctionDialog.cxx src/disassembler/Disassembler.cxx src/disassembler/llvm/LLVMDisassembler.cxx ) @@ -59,6 +60,7 @@ SET(frida_HEADERS src/gui/widgets/BasicBlockWidget.hxx src/gui/widgets/CFGScene.hxx src/gui/widgets/ScriptingDock.hxx + src/gui/dialogs/NewFunctionDialog.hxx src/disassembler/llvm/LLVMDisassembler.hxx src/disassembler/Disassembler.hxx ) diff --git a/src/disassembler/Disassembler.hxx b/src/disassembler/Disassembler.hxx index 5af2eac..dbc140e 100644 --- a/src/disassembler/Disassembler.hxx +++ b/src/disassembler/Disassembler.hxx @@ -22,6 +22,7 @@ public: virtual void printEachInstruction(uint64_t start, uint64_t end, std::function fun) = 0; + virtual Function * disassembleFunctionAt(uint64_t address, const std::string& name = "") = 0; protected: virtual bool isFunctionCall(uint64_t address) = 0; virtual bool isJump(uint64_t address) = 0; diff --git a/src/gui/Mainwindow.cxx b/src/gui/Mainwindow.cxx index 46ce2e9..764eb03 100644 --- a/src/gui/Mainwindow.cxx +++ b/src/gui/Mainwindow.cxx @@ -3,7 +3,7 @@ #include "disassembler/llvm/LLVMDisassembler.hxx" #include "widgets/CFGScene.hxx" - +#include "dialogs/NewFunctionDialog.hxx" #include #include #include @@ -41,6 +41,10 @@ Mainwindow::Mainwindow(InformationManager* mgr) addDockWidget(Qt::BottomDockWidgetArea, scripting); listWidget = new QListWidget(); + listWidget->setContextMenuPolicy(Qt::CustomContextMenu); + connect(listWidget, SIGNAL(customContextMenuRequested(const QPoint&)), + this, SLOT(showListContextMenu(const QPoint&))); + stackedWidget = new QStackedWidget(); dockWidget = new QDockWidget(tr("Functions"), this); dockWidget->setAllowedAreas(Qt::LeftDockWidgetArea | @@ -64,7 +68,7 @@ Mainwindow::Mainwindow(InformationManager* mgr) void Mainwindow::quit() { QMessageBox messageBox; - messageBox.setWindowTitle(tr("Notepad")); + messageBox.setWindowTitle(tr("Frida")); messageBox.setText(tr("Do you really want to quit?")); messageBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); messageBox.setDefaultButton(QMessageBox::No); @@ -79,6 +83,30 @@ void Mainwindow::open() { manager->reset(fileName.toStdString()); } +void Mainwindow::showListContextMenu(const QPoint& point) { + QListWidgetItem * item = listWidget->itemAt(point); + if (item) { + LOG4CXX_DEBUG(logger, "WOHO " << item->text().toStdString()); + } else { + QMenu menu(this); + QAction * act = menu.addAction("AddFunction"); + connect(act, SIGNAL(triggered()), this, SLOT(requestNewFunction())); + + menu.exec(listWidget->mapToGlobal(point)); + } +} + +void Mainwindow::requestNewFunction() { + NewFunctionDialog dialog; + int result = dialog.exec(); + if (QDialog::Accepted == result) { + LOG4CXX_DEBUG(logger, "requesting Function at " << std::hex << dialog.result()); + manager->getDisassembler()->disassembleFunctionAt(dialog.result()); + } else { + LOG4CXX_DEBUG(logger, "requestNewFunction aborted"); + } +} + void Mainwindow::addFunction(Function* fun) { if (functions.find(fun) != functions.end()) return; diff --git a/src/gui/Mainwindow.hxx b/src/gui/Mainwindow.hxx index bb2a90e..953b315 100644 --- a/src/gui/Mainwindow.hxx +++ b/src/gui/Mainwindow.hxx @@ -22,6 +22,7 @@ class Mainwindow : public QMainWindow { Q_OBJECT public: Mainwindow(InformationManager* mgr); + private: void addFunction(Function* fun); @@ -46,6 +47,8 @@ private: private Q_SLOTS: void quit(); void open(); + void showListContextMenu(const QPoint&); + void requestNewFunction(); }; #endif /* INCLUDE__Mainwindow_hxx_ */ diff --git a/src/gui/dialogs/NewFunctionDialog.cxx b/src/gui/dialogs/NewFunctionDialog.cxx new file mode 100644 index 0000000..3c605d1 --- /dev/null +++ b/src/gui/dialogs/NewFunctionDialog.cxx @@ -0,0 +1,27 @@ +#include "NewFunctionDialog.hxx" + +NewFunctionDialog::NewFunctionDialog() { + QGridLayout * layout = new QGridLayout; + + edit = new QLineEdit; + layout->addWidget(edit, 0, 0, 1, 2); + edit->setInputMask("\\0\\xhhhhhhhhhhhhhhhH"); + + QPushButton * cancelButton = new QPushButton("Cancel"); + QPushButton * okButton = new QPushButton("OK"); + layout->addWidget(okButton, 1, 1, 1, 1); + connect(okButton, SIGNAL(clicked()), + this, SLOT(accept())); + layout->addWidget(cancelButton, 1, 0, 1, 1); + connect(cancelButton, SIGNAL(clicked()), + this, SLOT(reject())); + + setLayout(layout); + setWindowTitle("Add function"); +} + +uint64_t NewFunctionDialog::result() { + bool ok; + uint64_t result = edit->text().toLongLong(&ok, 16); + return result; +} diff --git a/src/gui/dialogs/NewFunctionDialog.hxx b/src/gui/dialogs/NewFunctionDialog.hxx new file mode 100644 index 0000000..9f04ed1 --- /dev/null +++ b/src/gui/dialogs/NewFunctionDialog.hxx @@ -0,0 +1,11 @@ +#include "gui/qt.hxx" + +class NewFunctionDialog : public QDialog { + Q_OBJECT +public: + NewFunctionDialog(); + + uint64_t result(); +private: + QLineEdit * edit; +}; diff --git a/src/gui/qt.hxx b/src/gui/qt.hxx index 7397b23..64ca4c1 100644 --- a/src/gui/qt.hxx +++ b/src/gui/qt.hxx @@ -22,5 +22,7 @@ #include #include #include +#include +#include #endif /* INCLUDE__qt_hxx_ */ -- 2.39.2