1
0
Fork 0

Added copy selection to file options for CPUDisassembly. (#1177)

* Added copy selection to file options for CPUDisassembly

* Copying CPU disassembly now streams output into target instead of constructing a huge string
This commit is contained in:
Alexandros Naskos 2016-10-21 17:39:41 +03:00 committed by Duncan Ogilvie
parent b49740c482
commit af9481d980
2 changed files with 53 additions and 6 deletions

View File

@ -1,4 +1,6 @@
#include <QMessageBox> #include <QMessageBox>
#include <QFileDialog>
#include <QFile>
#include <QDesktopServices> #include <QDesktopServices>
#include <QClipboard> #include <QClipboard>
#include "CPUDisassembly.h" #include "CPUDisassembly.h"
@ -236,7 +238,9 @@ void CPUDisassembly::setupRightClickContextMenu()
MenuBuilder* copyMenu = new MenuBuilder(this); MenuBuilder* copyMenu = new MenuBuilder(this);
copyMenu->addAction(makeShortcutAction(DIcon("copy_selection.png"), tr("&Selection"), SLOT(copySelectionSlot()), "ActionCopy")); copyMenu->addAction(makeShortcutAction(DIcon("copy_selection.png"), tr("&Selection"), SLOT(copySelectionSlot()), "ActionCopy"));
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 (&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("copy_address.png"), tr("&Address"), SLOT(copyAddressSlot()), "ActionCopyAddress")); copyMenu->addAction(makeShortcutAction(DIcon("copy_address.png"), tr("&Address"), SLOT(copyAddressSlot()), "ActionCopyAddress"));
copyMenu->addAction(makeAction(DIcon("copy_address.png"), tr("&RVA"), SLOT(copyRvaSlot()))); copyMenu->addAction(makeAction(DIcon("copy_address.png"), tr("&RVA"), SLOT(copyRvaSlot())));
copyMenu->addAction(makeAction(DIcon("copy_disassembly.png"), tr("Disassembly"), SLOT(copyDisassemblySlot()))); copyMenu->addAction(makeAction(DIcon("copy_disassembly.png"), tr("Disassembly"), SLOT(copyDisassemblySlot())));
@ -1394,17 +1398,44 @@ void CPUDisassembly::yaraSlot()
} }
void CPUDisassembly::copySelectionSlot(bool copyBytes) void CPUDisassembly::copySelectionSlot(bool copyBytes)
{
QString selectionString = "";
QTextStream stream(&selectionString);
pushSelectionInto(copyBytes, stream);
Bridge::CopyToClipboard(selectionString);
}
void CPUDisassembly::copySelectionToFileSlot(bool copyBytes)
{
QString fileName = QFileDialog::getSaveFileName(this, tr("Open File"), "", tr("Text Files (*.txt)"));
if(fileName != "")
{
QFile file(fileName);
if(!file.open(QIODevice::WriteOnly))
{
QMessageBox::critical(this, tr("Error"), tr("Could not open file"));
return;
}
QTextStream stream(&file);
pushSelectionInto(copyBytes, stream);
file.close();
}
}
void CPUDisassembly::pushSelectionInto(bool copyBytes, QTextStream & stream)
{ {
QList<Instruction_t> instBuffer; QList<Instruction_t> instBuffer;
prepareDataRange(getSelectionStart(), getSelectionEnd(), &instBuffer); prepareDataRange(getSelectionStart(), getSelectionEnd(), &instBuffer);
QString clipboard = "";
const int addressLen = getColumnWidth(0) / getCharWidth() - 1; const int addressLen = getColumnWidth(0) / getCharWidth() - 1;
const int bytesLen = getColumnWidth(1) / getCharWidth() - 1; const int bytesLen = getColumnWidth(1) / getCharWidth() - 1;
const int disassemblyLen = getColumnWidth(2) / getCharWidth() - 1; const int disassemblyLen = getColumnWidth(2) / getCharWidth() - 1;
for(int i = 0; i < instBuffer.size(); i++) for(int i = 0; i < instBuffer.size(); i++)
{ {
if(i) if(i)
clipboard += "\r\n"; stream << "\r\n";
dsint cur_addr = rvaToVa(instBuffer.at(i).rva); dsint cur_addr = rvaToVa(instBuffer.at(i).rva);
QString address = getAddrText(cur_addr, 0); QString address = getAddrText(cur_addr, 0);
QString bytes; QString bytes;
@ -1421,12 +1452,13 @@ void CPUDisassembly::copySelectionSlot(bool copyBytes)
QString comment; QString comment;
if(GetCommentFormat(cur_addr, comment)) if(GetCommentFormat(cur_addr, comment))
fullComment = " " + comment; fullComment = " " + comment;
clipboard += address.leftJustified(addressLen, QChar(' '), true); stream << address.leftJustified(addressLen, QChar(' '), true);
if(copyBytes) if(copyBytes)
clipboard += " | " + bytes.leftJustified(bytesLen, QChar(' '), true); stream << " | " + bytes.leftJustified(bytesLen, QChar(' '), true);
clipboard += " | " + disassembly.leftJustified(disassemblyLen, QChar(' '), true) + " |" + fullComment; stream << " | " + disassembly.leftJustified(disassemblyLen, QChar(' '), true) + " |" + fullComment;
stream.flush();
} }
Bridge::CopyToClipboard(clipboard);
} }
void CPUDisassembly::copySelectionSlot() void CPUDisassembly::copySelectionSlot()
@ -1434,11 +1466,21 @@ void CPUDisassembly::copySelectionSlot()
copySelectionSlot(true); copySelectionSlot(true);
} }
void CPUDisassembly::copySelectionToFileSlot()
{
copySelectionToFileSlot(true);
}
void CPUDisassembly::copySelectionNoBytesSlot() void CPUDisassembly::copySelectionNoBytesSlot()
{ {
copySelectionSlot(false); copySelectionSlot(false);
} }
void CPUDisassembly::copySelectionToFileNoBytesSlot()
{
copySelectionToFileSlot(false);
}
void CPUDisassembly::copyAddressSlot() void CPUDisassembly::copyAddressSlot()
{ {
QString addrText = ToPtrString(rvaToVa(getInitialSelection())); QString addrText = ToPtrString(rvaToVa(getInitialSelection()));

View File

@ -26,6 +26,7 @@ public:
void setupFollowReferenceMenu(dsint wVA, QMenu* menu, bool isReferences, bool isFollowInCPU); void setupFollowReferenceMenu(dsint wVA, QMenu* menu, bool isReferences, bool isFollowInCPU);
void setHwBpAt(duint va, int slot); void setHwBpAt(duint va, int slot);
void copySelectionSlot(bool copyBytes); void copySelectionSlot(bool copyBytes);
void copySelectionToFileSlot(bool copyBytes);
signals: signals:
void displayReferencesWidget(); void displayReferencesWidget();
@ -81,7 +82,9 @@ public slots:
void showPatchesSlot(); void showPatchesSlot();
void yaraSlot(); void yaraSlot();
void copySelectionSlot(); void copySelectionSlot();
void copySelectionToFileSlot();
void copySelectionNoBytesSlot(); void copySelectionNoBytesSlot();
void copySelectionToFileNoBytesSlot();
void copyAddressSlot(); void copyAddressSlot();
void copyRvaSlot(); void copyRvaSlot();
void copyDisassemblySlot(); void copyDisassemblySlot();
@ -119,6 +122,8 @@ private:
bool getLabelsFromInstruction(duint addr, QSet<QString> & labels); bool getLabelsFromInstruction(duint addr, QSet<QString> & labels);
bool getTokenValueText(QString & text); bool getTokenValueText(QString & text);
void pushSelectionInto(bool copyBytes, QTextStream & stream);
// Menus // Menus
QMenu* mHwSlotSelectMenu; QMenu* mHwSlotSelectMenu;
QMenu* mPluginMenu; QMenu* mPluginMenu;