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:
parent
b49740c482
commit
af9481d980
|
@ -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()));
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue