diff --git a/x64_dbg_gui/Project/Src/Gui/CPUDisassembly.cpp b/x64_dbg_gui/Project/Src/Gui/CPUDisassembly.cpp index 20fb9492..789ed713 100644 --- a/x64_dbg_gui/Project/Src/Gui/CPUDisassembly.cpp +++ b/x64_dbg_gui/Project/Src/Gui/CPUDisassembly.cpp @@ -6,6 +6,7 @@ #include "LineEditDialog.h" #include "WordEditDialog.h" #include "HexEditDialog.h" +#include "YaraRuleSelectionDialog.h" CPUDisassembly::CPUDisassembly(QWidget* parent) : Disassembly(parent) { @@ -248,6 +249,7 @@ void CPUDisassembly::contextMenuEvent(QContextMenuEvent* event) wMenu->addAction(mAssemble); wMenu->addAction(mPatchesAction); + wMenu->addAction(mYaraAction); wMenu->addSeparator(); @@ -404,6 +406,11 @@ void CPUDisassembly::setupRightClickContextMenu() mPatchesAction->setShortcutContext(Qt::WidgetShortcut); connect(mPatchesAction, SIGNAL(triggered()), this, SLOT(showPatchesSlot())); + mYaraAction = new QAction(QIcon(":/icons/images/yara.png"), "&Yara...", this); + mYaraAction->setShortcutContext(Qt::WidgetShortcut); + this->addAction(mYaraAction); + connect(mYaraAction, SIGNAL(triggered()), this, SLOT(yaraSlot())); + //-------------------------------------------------------------------- //---------------------- New origin here ----------------------------- @@ -545,6 +552,7 @@ void CPUDisassembly::refreshShortcutsSlot() mAssemble->setShortcut(ConfigShortcut("ActionAssemble")); mToggleInt3BpAction->setShortcut(ConfigShortcut("ActionToggleBreakpoint")); mPatchesAction->setShortcut(ConfigShortcut("ViewPatches")); + mYaraAction->setShortcut(ConfigShortcut("ActionYara")); mSetNewOriginHere->setShortcut(ConfigShortcut("ActionSetNewOriginHere")); mGotoOrigin->setShortcut(ConfigShortcut("ActionGotoOrigin")); mGotoPrevious->setShortcut(ConfigShortcut("ActionGotoPrevious")); @@ -1143,6 +1151,17 @@ void CPUDisassembly::showPatchesSlot() emit showPatches(); } +void CPUDisassembly::yaraSlot() +{ + YaraRuleSelectionDialog yaraDialog(this); + if(yaraDialog.exec() == QDialog::Accepted) + { + QString addrText = QString("%1").arg(rvaToVa(getInitialSelection()), sizeof(int_t) * 2, 16, QChar('0')).toUpper(); + DbgCmdExec(QString("yara \"%0\",%1").arg(yaraDialog.getSelectedFile()).arg(addrText).toUtf8().constData()); + emit displayReferencesWidget(); + } +} + void CPUDisassembly::copySelection(bool copyBytes) { QList instBuffer; diff --git a/x64_dbg_gui/Project/Src/Gui/CPUDisassembly.h b/x64_dbg_gui/Project/Src/Gui/CPUDisassembly.h index b9f8f475..612b5d7d 100644 --- a/x64_dbg_gui/Project/Src/Gui/CPUDisassembly.h +++ b/x64_dbg_gui/Project/Src/Gui/CPUDisassembly.h @@ -63,6 +63,7 @@ public slots: void binaryPasteIgnoreSizeSlot(); void undoSelectionSlot(); void showPatchesSlot(); + void yaraSlot(); void copySelection(); void copySelectionNoBytes(); void copyAddress(); @@ -115,6 +116,7 @@ private: QAction* mSearchPattern; QAction* mEnableHighlightingMode; QAction* mPatchesAction; + QAction* mYaraAction; QAction* mCopySelection; QAction* mCopySelectionNoBytes; QAction* mCopyAddress; diff --git a/x64_dbg_gui/Project/Src/Gui/CPUDump.cpp b/x64_dbg_gui/Project/Src/Gui/CPUDump.cpp index 7f05567f..d9db978b 100644 --- a/x64_dbg_gui/Project/Src/Gui/CPUDump.cpp +++ b/x64_dbg_gui/Project/Src/Gui/CPUDump.cpp @@ -5,6 +5,7 @@ #include "Bridge.h" #include "LineEditDialog.h" #include "HexEditDialog.h" +#include "YaraRuleSelectionDialog.h" CPUDump::CPUDump(QWidget* parent) : HexDump(parent) { @@ -232,6 +233,12 @@ void CPUDump::setupContextMenu() this->addAction(mFindPatternAction); connect(mFindPatternAction, SIGNAL(triggered()), this, SLOT(findPattern())); + //Yara + mYaraAction = new QAction(QIcon(":/icons/images/yara.png"), "&Yara...", this); + mYaraAction->setShortcutContext(Qt::WidgetShortcut); + this->addAction(mYaraAction); + connect(mYaraAction, SIGNAL(triggered()), this, SLOT(yaraSlot())); + //Find References mFindReferencesAction = new QAction("Find &References", this); mFindReferencesAction->setShortcutContext(Qt::WidgetShortcut); @@ -362,6 +369,7 @@ void CPUDump::refreshShortcutsSlot() mFindPatternAction->setShortcut(ConfigShortcut("ActionFindPattern")); mFindReferencesAction->setShortcut(ConfigShortcut("ActionFindReferences")); mGotoExpression->setShortcut(ConfigShortcut("ActionGotoExpression")); + mYaraAction->setShortcut(ConfigShortcut("ActionYara")); } QString CPUDump::paintContent(QPainter* painter, int_t rowBase, int rowOffset, int col, int x, int y, int w, int h) @@ -464,6 +472,7 @@ void CPUDump::contextMenuEvent(QContextMenuEvent* event) wMenu->addAction(mSetLabelAction); wMenu->addMenu(mBreakpointMenu); wMenu->addAction(mFindPatternAction); + wMenu->addAction(mYaraAction); wMenu->addMenu(mGotoMenu); wMenu->addSeparator(); wMenu->addMenu(mHexMenu); @@ -1322,3 +1331,14 @@ void CPUDump::selectionUpdatedSlot() QString selEnd = QString("%1").arg(rvaToVa(getSelectionEnd()), sizeof(int_t) * 2, 16, QChar('0')).toUpper(); GuiAddStatusBarMessage(QString("Dump: " + selStart + " -> " + selEnd + QString().sprintf(" (0x%.8X bytes)\n", getSelectionEnd() - getSelectionStart() + 1)).toUtf8().constData()); } + +void CPUDump::yaraSlot() +{ + YaraRuleSelectionDialog yaraDialog(this); + if(yaraDialog.exec() == QDialog::Accepted) + { + QString addrText = QString("%1").arg(rvaToVa(getInitialSelection()), sizeof(int_t) * 2, 16, QChar('0')).toUpper(); + DbgCmdExec(QString("yara \"%0\",%1").arg(yaraDialog.getSelectedFile()).arg(addrText).toUtf8().constData()); + emit displayReferencesWidget(); + } +} diff --git a/x64_dbg_gui/Project/Src/Gui/CPUDump.h b/x64_dbg_gui/Project/Src/Gui/CPUDump.h index 99d58c0d..dc8a837c 100644 --- a/x64_dbg_gui/Project/Src/Gui/CPUDump.h +++ b/x64_dbg_gui/Project/Src/Gui/CPUDump.h @@ -78,6 +78,7 @@ public slots: void findReferencesSlot(); void selectionUpdatedSlot(); + void yaraSlot(); private: QMenu* mBreakpointMenu; @@ -158,6 +159,7 @@ private: QAction* mBinaryPasteIgnoreSizeAction; QAction* mFindPatternAction; QAction* mFindReferencesAction; + QAction* mYaraAction; QAction* mUndoSelection; QMenu* mSpecialMenu; diff --git a/x64_dbg_gui/Project/Src/Gui/MainWindow.cpp b/x64_dbg_gui/Project/Src/Gui/MainWindow.cpp index 10284053..626ebf4b 100644 --- a/x64_dbg_gui/Project/Src/Gui/MainWindow.cpp +++ b/x64_dbg_gui/Project/Src/Gui/MainWindow.cpp @@ -77,6 +77,7 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), ui(new Ui::MainWi // Memory Map View mMemMapView = new MemoryMapView(); connect(mMemMapView, SIGNAL(showCpu()), this, SLOT(displayCpuWidget())); + connect(mMemMapView, SIGNAL(showReferences()), this, SLOT(displayReferencesWidget())); mMemMapView->setWindowTitle("Memory Map"); mMemMapView->setWindowIcon(QIcon(":/icons/images/memory-map.png")); mMemMapView->hide(); @@ -168,6 +169,7 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), ui(new Ui::MainWi connect(ui->actionCpu, SIGNAL(triggered()), this, SLOT(displayCpuWidget())); connect(ui->actionSymbolInfo, SIGNAL(triggered()), this, SLOT(displaySymbolWidget())); connect(mSymbolView, SIGNAL(showCpu()), this, SLOT(displayCpuWidget())); + connect(mSymbolView, SIGNAL(showReferences()), this, SLOT(displayReferencesWidget())); connect(mReferenceManager, SIGNAL(showCpu()), this, SLOT(displayCpuWidget())); connect(ui->actionReferences, SIGNAL(triggered()), this, SLOT(displayReferencesWidget())); connect(ui->actionThreads, SIGNAL(triggered()), this, SLOT(displayThreadsWidget())); diff --git a/x64_dbg_gui/Project/Src/Gui/MemoryMapView.cpp b/x64_dbg_gui/Project/Src/Gui/MemoryMapView.cpp index 92ca43f2..d88122ac 100644 --- a/x64_dbg_gui/Project/Src/Gui/MemoryMapView.cpp +++ b/x64_dbg_gui/Project/Src/Gui/MemoryMapView.cpp @@ -2,6 +2,7 @@ #include "Configuration.h" #include "Bridge.h" #include "PageMemoryRights.h" +#include "YaraRuleSelectionDialog.h" MemoryMapView::MemoryMapView(StdTable* parent) : StdTable(parent) { @@ -37,6 +38,10 @@ void MemoryMapView::setupContextMenu() connect(mFollowDisassembly, SIGNAL(triggered()), this, SLOT(followDisassemblerSlot())); connect(this, SIGNAL(enterPressedSignal()), this, SLOT(followDisassemblerSlot())); + //Yara + mYara = new QAction(QIcon(":/icons/images/yara.png"), "&Yara...", this); + connect(mYara, SIGNAL(triggered()), this, SLOT(yaraSlot())); + //Set PageMemory Rights mPageMemoryRights = new QAction("Set Page Memory Rights", this); connect(mPageMemoryRights, SIGNAL(triggered()), this, SLOT(pageMemoryRights())); @@ -109,6 +114,7 @@ void MemoryMapView::contextMenuSlot(const QPoint & pos) QMenu* wMenu = new QMenu(this); //create context menu wMenu->addAction(mFollowDisassembly); wMenu->addAction(mFollowDump); + wMenu->addAction(mYara); wMenu->addAction(mSwitchView); wMenu->addSeparator(); wMenu->addAction(mPageMemoryRights); @@ -301,6 +307,18 @@ void MemoryMapView::followDisassemblerSlot() emit showCpu(); } +void MemoryMapView::yaraSlot() +{ + YaraRuleSelectionDialog yaraDialog(this); + if(yaraDialog.exec() == QDialog::Accepted) + { + QString addr_text = getCellContent(getInitialSelection(), 0); + QString size_text = getCellContent(getInitialSelection(), 1); + DbgCmdExec(QString("yara \"%0\",%1,%2").arg(yaraDialog.getSelectedFile()).arg(addr_text).arg(size_text).toUtf8().constData()); + emit showReferences(); + } +} + void MemoryMapView::memoryAccessSingleshootSlot() { QString addr_text = getCellContent(getInitialSelection(), 0); diff --git a/x64_dbg_gui/Project/Src/Gui/MemoryMapView.h b/x64_dbg_gui/Project/Src/Gui/MemoryMapView.h index 1d7e4e37..2e64c810 100644 --- a/x64_dbg_gui/Project/Src/Gui/MemoryMapView.h +++ b/x64_dbg_gui/Project/Src/Gui/MemoryMapView.h @@ -13,12 +13,14 @@ public: signals: void showCpu(); + void showReferences(); public slots: void refreshShortcutsSlot(); void stateChangedSlot(DBGSTATE state); void followDumpSlot(); void followDisassemblerSlot(); + void yaraSlot(); void memoryAccessSingleshootSlot(); void memoryAccessRestoreSlot(); void memoryWriteSingleshootSlot(); @@ -37,6 +39,7 @@ private: QAction* mFollowDump; QAction* mFollowDisassembly; + QAction* mYara; QAction* mSwitchView; QAction* mPageMemoryRights; diff --git a/x64_dbg_gui/Project/Src/Gui/SymbolView.cpp b/x64_dbg_gui/Project/Src/Gui/SymbolView.cpp index 8e96cb3e..0fcf3232 100644 --- a/x64_dbg_gui/Project/Src/Gui/SymbolView.cpp +++ b/x64_dbg_gui/Project/Src/Gui/SymbolView.cpp @@ -3,6 +3,7 @@ #include #include "Configuration.h" #include "Bridge.h" +#include "YaraRuleSelectionDialog.h" SymbolView::SymbolView(QWidget* parent) : QWidget(parent), ui(new Ui::SymbolView) { @@ -123,6 +124,9 @@ void SymbolView::setupContextMenu() mCopyPathAction = new QAction("Copy File &Path", this); connect(mCopyPathAction, SIGNAL(triggered()), this, SLOT(moduleCopyPath())); + mYaraAction = new QAction(QIcon(":/icons/images/yara.png"), "&Yara...", this); + connect(mYaraAction, SIGNAL(triggered()), this, SLOT(moduleYara())); + //Shortcuts refreshShortcutsSlot(); connect(Config(), SIGNAL(shortcutsUpdated()), this, SLOT(refreshShortcutsSlot())); @@ -244,6 +248,7 @@ void SymbolView::moduleContextMenu(const QPoint & pos) char szModPath[MAX_PATH] = ""; if(DbgFunctions()->ModPathFromAddr(modbase, szModPath, _countof(szModPath))) wMenu->addAction(mCopyPathAction); + wMenu->addAction(mYaraAction); QMenu wCopyMenu("&Copy", this); mModuleList->setupCopyMenu(&wCopyMenu); if(wCopyMenu.actions().length()) @@ -274,6 +279,17 @@ void SymbolView::moduleCopyPath() Bridge::CopyToClipboard(szModPath); } +void SymbolView::moduleYara() +{ + QString modname = mModuleList->getCellContent(mModuleList->getInitialSelection(), 1); + YaraRuleSelectionDialog yaraDialog(this); + if(yaraDialog.exec() == QDialog::Accepted) + { + DbgCmdExec(QString("yara \"%0\",\"%1\"").arg(yaraDialog.getSelectedFile()).arg(modname).toUtf8().constData()); + emit showReferences(); + } +} + void SymbolView::moduleDownloadSymbols() { DbgCmdExec(QString("symdownload " + mModuleList->getCellContent(mModuleList->getInitialSelection(), 1)).toUtf8().constData()); diff --git a/x64_dbg_gui/Project/Src/Gui/SymbolView.h b/x64_dbg_gui/Project/Src/Gui/SymbolView.h index b421b14a..02d45fd3 100644 --- a/x64_dbg_gui/Project/Src/Gui/SymbolView.h +++ b/x64_dbg_gui/Project/Src/Gui/SymbolView.h @@ -34,12 +34,14 @@ private slots: void moduleDownloadSymbols(); void moduleDownloadAllSymbols(); void moduleCopyPath(); + void moduleYara(); void toggleBreakpoint(); void toggleBookmark(); void refreshShortcutsSlot(); signals: void showCpu(); + void showReferences(); private: Ui::SymbolView* ui; @@ -58,6 +60,7 @@ private: QAction* mDownloadSymbolsAction; QAction* mDownloadAllSymbolsAction; QAction* mCopyPathAction; + QAction* mYaraAction; static void cbSymbolEnum(SYMBOLINFO* symbol, void* user); }; diff --git a/x64_dbg_gui/Project/Src/Gui/YaraRuleSelectionDialog.cpp b/x64_dbg_gui/Project/Src/Gui/YaraRuleSelectionDialog.cpp new file mode 100644 index 00000000..444bcd71 --- /dev/null +++ b/x64_dbg_gui/Project/Src/Gui/YaraRuleSelectionDialog.cpp @@ -0,0 +1,75 @@ +#include "YaraRuleSelectionDialog.h" +#include "ui_YaraRuleSelectionDialog.h" +#include +#include +#include +#include +#include "Imports.h" + +YaraRuleSelectionDialog::YaraRuleSelectionDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::YaraRuleSelectionDialog) +{ + ui->setupUi(this); +#if QT_VERSION < QT_VERSION_CHECK(5,0,0) + setWindowFlags(Qt::Dialog | Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::MSWindowsFixedSizeDialogHint); +#endif + setFixedSize(this->size()); //fixed size + + char setting[MAX_SETTING_SIZE]=""; + if(BridgeSettingGet("Misc", "YaraRulesDirectory", setting)) + { + rulesDirectory = QString(setting); + enumRulesDirectory(); + } +} + +YaraRuleSelectionDialog::~YaraRuleSelectionDialog() +{ + delete ui; +} + +QString YaraRuleSelectionDialog::getSelectedFile() +{ + return selectedFile; +} + +void YaraRuleSelectionDialog::on_buttonDirectory_clicked() +{ + QString dir = QFileDialog::getExistingDirectory(this, "Select Yara Rules Directory..."); + if(!dir.length()) + return; + rulesDirectory = QDir::toNativeSeparators(dir); + BridgeSettingSet("Misc", "YaraRulesDirectory", dir.toUtf8().constData()); + enumRulesDirectory(); +} + +void YaraRuleSelectionDialog::on_buttonFile_clicked() +{ + QString file = QFileDialog::getOpenFileName(this, "Select Yara Rule...", rulesDirectory); + if(!file.length()) + return; + selectedFile = QDir::toNativeSeparators(file); + this->accept(); +} + +void YaraRuleSelectionDialog::on_buttonSelect_clicked() +{ + int selectedIndex=ui->listRules->row(ui->listRules->selectedItems().at(0)); + selectedFile = ruleFiles.at(selectedIndex).first; + this->accept(); +} + +void YaraRuleSelectionDialog::enumRulesDirectory() +{ + ruleFiles.clear(); + ui->listRules->clear(); + QDirIterator it(rulesDirectory, QDir::Files, QDirIterator::Subdirectories); + while(it.hasNext()) + { + it.next(); + ruleFiles.append(QPair(QDir::toNativeSeparators(it.filePath()), it.fileName())); + ui->listRules->addItem(it.fileName()); + } + ui->listRules->setCurrentRow(0); +} diff --git a/x64_dbg_gui/Project/Src/Gui/YaraRuleSelectionDialog.h b/x64_dbg_gui/Project/Src/Gui/YaraRuleSelectionDialog.h new file mode 100644 index 00000000..7414a393 --- /dev/null +++ b/x64_dbg_gui/Project/Src/Gui/YaraRuleSelectionDialog.h @@ -0,0 +1,33 @@ +#ifndef YARARULESELECTIONDIALOG_H +#define YARARULESELECTIONDIALOG_H + +#include + +namespace Ui { +class YaraRuleSelectionDialog; +} + +class YaraRuleSelectionDialog : public QDialog +{ + Q_OBJECT + +public: + explicit YaraRuleSelectionDialog(QWidget *parent = 0); + ~YaraRuleSelectionDialog(); + QString getSelectedFile(); + +private slots: + void on_buttonDirectory_clicked(); + void on_buttonFile_clicked(); + void on_buttonSelect_clicked(); + +private: + Ui::YaraRuleSelectionDialog *ui; + QList> ruleFiles; + QString rulesDirectory; + QString selectedFile; + + void enumRulesDirectory(); +}; + +#endif // YARARULESELECTIONDIALOG_H diff --git a/x64_dbg_gui/Project/Src/Gui/YaraRuleSelectionDialog.ui b/x64_dbg_gui/Project/Src/Gui/YaraRuleSelectionDialog.ui new file mode 100644 index 00000000..6ecc259b --- /dev/null +++ b/x64_dbg_gui/Project/Src/Gui/YaraRuleSelectionDialog.ui @@ -0,0 +1,95 @@ + + + YaraRuleSelectionDialog + + + + 0 + 0 + 341 + 361 + + + + Yara + + + + :/icons/images/yara.png:/icons/images/Yara.png + + + + + 10 + 10 + 322 + 341 + + + + + + + + + + + + + 0 + 0 + + + + Directory... + + + + + + + &File... + + + + + + + &Select + + + + + + + &Cancel + + + + + + + + + + + + + + buttonCancel + clicked() + YaraRuleSelectionDialog + reject() + + + 341 + 280 + + + 361 + 246 + + + + + diff --git a/x64_dbg_gui/Project/Src/Utils/Configuration.cpp b/x64_dbg_gui/Project/Src/Utils/Configuration.cpp index 8ed1e346..c1365a7e 100644 --- a/x64_dbg_gui/Project/Src/Utils/Configuration.cpp +++ b/x64_dbg_gui/Project/Src/Utils/Configuration.cpp @@ -241,6 +241,7 @@ Configuration::Configuration() : QObject() defaultShortcuts.insert("ActionSetComment", Shortcut(tr("Actions -> Set Comment"), ";")); defaultShortcuts.insert("ActionToggleFunction", Shortcut(tr("Actions -> Toggle Function"), "Shift+F")); defaultShortcuts.insert("ActionAssemble", Shortcut(tr("Actions -> Assemble"), "Space")); + defaultShortcuts.insert("ActionYara", Shortcut(tr("Actions -> Yara"), "Ctrl+Y")); defaultShortcuts.insert("ActionSetNewOriginHere", Shortcut(tr("Actions -> Set New Origin Here"), "Ctrl+*")); defaultShortcuts.insert("ActionGotoOrigin", Shortcut(tr("Actions -> Goto Origin"), "*")); defaultShortcuts.insert("ActionGotoPrevious", Shortcut(tr("Actions -> Goto Previous"), "-")); diff --git a/x64_dbg_gui/Project/images/yara.png b/x64_dbg_gui/Project/images/yara.png new file mode 100644 index 00000000..ecac5a43 Binary files /dev/null and b/x64_dbg_gui/Project/images/yara.png differ diff --git a/x64_dbg_gui/Project/resource.qrc b/x64_dbg_gui/Project/resource.qrc index b2790047..7357e1d8 100644 --- a/x64_dbg_gui/Project/resource.qrc +++ b/x64_dbg_gui/Project/resource.qrc @@ -51,5 +51,6 @@ images/topmost.png images/close-all-tabs.png images/bug-report.png + images/yara.png diff --git a/x64_dbg_gui/Project/x64_dbg.pro b/x64_dbg_gui/Project/x64_dbg.pro index 1af66de0..e80fa89f 100644 --- a/x64_dbg_gui/Project/x64_dbg.pro +++ b/x64_dbg_gui/Project/x64_dbg.pro @@ -86,7 +86,8 @@ SOURCES += \ Src/Gui/PageMemoryRights.cpp \ Src/Gui/SelectFields.cpp \ Src/Gui/ReferenceManager.cpp \ - Src/Bridge/BridgeResult.cpp + Src/Bridge/BridgeResult.cpp \ + Src/Gui/YaraRuleSelectionDialog.cpp HEADERS += \ @@ -151,7 +152,8 @@ HEADERS += \ Src/Gui/PageMemoryRights.h \ Src/Gui/SelectFields.h \ Src/Gui/ReferenceManager.h \ - Src/Bridge/BridgeResult.h + Src/Bridge/BridgeResult.h \ + Src/Gui/YaraRuleSelectionDialog.h INCLUDEPATH += \ @@ -186,7 +188,8 @@ FORMS += \ Src/Gui/CalculatorDialog.ui \ Src/Gui/AttachDialog.ui \ Src/Gui/PageMemoryRights.ui \ - Src/Gui/SelectFields.ui + Src/Gui/SelectFields.ui \ + Src/Gui/YaraRuleSelectionDialog.ui INCLUDEPATH += $$PWD/Src/Bridge