From 30cc864ed8ac2a59c1b0d8d672741e2809e2c478 Mon Sep 17 00:00:00 2001 From: torusrxxx Date: Wed, 26 Aug 2020 16:15:24 +0800 Subject: [PATCH] Export trace CSV --- src/gui/Src/BasicView/AbstractStdTable.cpp | 2 +- src/gui/Src/Tracer/TraceBrowser.cpp | 76 ++++++++++++++++++++++ src/gui/Src/Tracer/TraceBrowser.h | 3 +- src/gui/Src/Utils/MiscUtil.cpp | 4 +- 4 files changed, 82 insertions(+), 3 deletions(-) diff --git a/src/gui/Src/BasicView/AbstractStdTable.cpp b/src/gui/Src/BasicView/AbstractStdTable.cpp index 0bb980b8..2bc9daef 100644 --- a/src/gui/Src/BasicView/AbstractStdTable.cpp +++ b/src/gui/Src/BasicView/AbstractStdTable.cpp @@ -19,7 +19,7 @@ AbstractStdTable::AbstractStdTable(QWidget* parent) : AbstractTableView(parent) mCopyLineToLog = makeShortcutAction(DIcon("copy_table_line.png"), tr("Line, To Log"), SLOT(copyLineToLogSlot()), "ActionCopyLineToLog"); mCopyTableToLog = makeShortcutAction(DIcon("copy_cropped_table.png"), tr("Cropped Table, To Log"), SLOT(copyTableToLogSlot()), "ActionCopyCroppedTableToLog"); mCopyTableResizeToLog = makeShortcutAction(DIcon("copy_full_table.png"), tr("Full Table, To Log"), SLOT(copyTableResizeToLogSlot()), "ActionCopyTableToLog"); - mExportTableCSV = makeShortcutAction(DIcon("copy_full_table.png"), tr("Export Table"), SLOT(exportTableSlot()), "ActionExport"); + mExportTableCSV = makeShortcutAction(DIcon("database-export.png"), tr("&Export Table"), SLOT(exportTableSlot()), "ActionExport"); } QString AbstractStdTable::paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h) diff --git a/src/gui/Src/Tracer/TraceBrowser.cpp b/src/gui/Src/Tracer/TraceBrowser.cpp index 901d3757..9eed3394 100644 --- a/src/gui/Src/Tracer/TraceBrowser.cpp +++ b/src/gui/Src/Tracer/TraceBrowser.cpp @@ -808,6 +808,7 @@ void TraceBrowser::setupRightClickContextMenu() copyMenu->addAction(makeAction(DIcon("copy_selection.png"), tr("Selection to &File"), SLOT(copySelectionToFileSlot()))); copyMenu->addAction(makeAction(DIcon("copy_selection_no_bytes.png"), tr("Selection (&No Bytes)"), SLOT(copySelectionNoBytesSlot()))); copyMenu->addAction(makeAction(DIcon("copy_selection_no_bytes.png"), tr("Selection to File (No Bytes)"), SLOT(copySelectionToFileNoBytesSlot()))); + copyMenu->addAction(makeShortcutAction(DIcon("database-export.png"), tr("&Export Table"), SLOT(exportSlot()), "ActionExport")); copyMenu->addAction(makeShortcutAction(DIcon("copy_address.png"), tr("Address"), SLOT(copyCipSlot()), "ActionCopyAddress")); copyMenu->addAction(makeShortcutAction(DIcon("copy_address.png"), tr("&RVA"), SLOT(copyRvaSlot()), "ActionCopyRva"), isDebugging); copyMenu->addAction(makeShortcutAction(DIcon("fileoffset.png"), tr("&File Offset"), SLOT(copyFileOffsetSlot()), "ActionCopyFileOffset"), isDebugging); @@ -1627,6 +1628,81 @@ void TraceBrowser::copyFileOffsetSlot() Bridge::CopyToClipboard(text); } +void TraceBrowser::exportSlot() +{ + if(mTraceFile == nullptr || mTraceFile->Progress() < 100) + return; + std::vector headers; + headers.reserve(getColumnCount()); + for(int i = 0; i < getColumnCount(); i++) + headers.push_back(getColTitle(i)); + ExportCSV(getRowCount(), getColumnCount(), headers, [this](dsint row, dsint col) + { + QString temp; + switch(col) + { + case Index: + return mTraceFile->getIndexText(row); + + case Address: + { + if(!DbgIsDebugging()) + return ToPtrString(mTraceFile->Registers(row).regcontext.cip); + else + return getAddrText(mTraceFile->Registers(row).regcontext.cip, 0, true); + } + + case Opcode: + { + for(auto i : getRichBytes(mTraceFile->Instruction(row))) + temp += i.text; + return temp; + } + + case Disassembly: + { + for(auto i : mTraceFile->Instruction(row).tokens.tokens) + temp += i.text; + return temp; + } + + case Registers: + { + for(auto i : registersTokens(row).tokens) + temp += i.text; + return temp; + } + case Memory: + { + for(auto i : memoryTokens(row).tokens) + temp += i.text; + return temp; + } + case Comments: + { + if(DbgIsDebugging()) + { + //TODO: draw arguments + QString comment; + bool autoComment = false; + char label[MAX_LABEL_SIZE] = ""; + if(GetCommentFormat(mTraceFile->Registers(row).regcontext.cip, comment, &autoComment)) + { + return QString(comment); + } + else if(DbgGetLabelAt(mTraceFile->Registers(row).regcontext.cip, SEG_DEFAULT, label)) // label but no comment + { + return QString(label); + } + } + return QString(); + } + default: + return QString(); + } + }); +} + void TraceBrowser::setCommentSlot() { if(!DbgIsDebugging() || mTraceFile == nullptr || mTraceFile->Progress() < 100) diff --git a/src/gui/Src/Tracer/TraceBrowser.h b/src/gui/Src/Tracer/TraceBrowser.h index add8d7b6..b5be0323 100644 --- a/src/gui/Src/Tracer/TraceBrowser.h +++ b/src/gui/Src/Tracer/TraceBrowser.h @@ -169,11 +169,12 @@ public slots: void copySelectionToFileNoBytesSlot(); void copyFileOffsetSlot(); void copyRvaSlot(); + void exportSlot(); void searchConstantSlot(); void searchMemRefSlot(); - void updateSlot(); //debug + void updateSlot(); void toggleAutoDisassemblyFollowSelectionSlot(); }; diff --git a/src/gui/Src/Utils/MiscUtil.cpp b/src/gui/Src/Utils/MiscUtil.cpp index b99d68f1..e56ccc66 100644 --- a/src/gui/Src/Utils/MiscUtil.cpp +++ b/src/gui/Src/Utils/MiscUtil.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include "LineEditDialog.h" #include "ComboBoxDialog.h" #include "StringUtil.h" @@ -160,7 +161,8 @@ QString getSymbolicNameStr(duint addr) bool ExportCSV(dsint rows, dsint columns, std::vector headers, std::function getCellContent) { - BrowseDialog browse(nullptr, QApplication::translate("ExportCSV", "Export data in CSV format"), QApplication::translate("ExportCSV", "Enter the CSV file name to export"), QApplication::translate("ExportCSV", "CSV files (*.csv);;All files (*.*)"), QCoreApplication::applicationDirPath(), true); + BrowseDialog browse(nullptr, QApplication::translate("ExportCSV", "Export data in CSV format"), QApplication::translate("ExportCSV", "Enter the CSV file name to export"), QApplication::translate("ExportCSV", "CSV files (*.csv);;All files (*.*)"), QApplication::applicationDirPath() + QDir::separator() + "db", true); + browse.setWindowIcon(DIcon("database-export.png")); if(browse.exec() == QDialog::Accepted) { FILE* csv;