2017-10-12 19:55:15 +00:00
|
|
|
|
|
|
|
#include "HexdumpWidget.h"
|
|
|
|
#include "ui_HexdumpWidget.h"
|
2017-09-28 21:53:59 +00:00
|
|
|
#include "DisassemblerGraphView.h"
|
2017-03-29 10:18:37 +00:00
|
|
|
|
2017-10-01 19:09:42 +00:00
|
|
|
#include "MainWindow.h"
|
|
|
|
#include "utils/Helpers.h"
|
2017-03-29 10:18:37 +00:00
|
|
|
|
|
|
|
#include <QTemporaryFile>
|
|
|
|
#include <QFontDialog>
|
|
|
|
#include <QScrollBar>
|
|
|
|
#include <QClipboard>
|
|
|
|
#include <QShortcut>
|
|
|
|
#include <QMenu>
|
|
|
|
#include <QFont>
|
|
|
|
#include <QUrl>
|
2017-04-13 15:14:02 +00:00
|
|
|
#include <QSettings>
|
|
|
|
|
|
|
|
#include <cassert>
|
2017-03-29 10:18:37 +00:00
|
|
|
|
2017-11-17 12:41:30 +00:00
|
|
|
const int HexdumpWidget::linesMarginMin = 32;
|
|
|
|
const int HexdumpWidget::linesMarginDefault = 48;
|
|
|
|
const int HexdumpWidget::linesMarginMax = 64;
|
2017-11-15 21:42:39 +00:00
|
|
|
|
2017-10-12 19:55:15 +00:00
|
|
|
HexdumpWidget::HexdumpWidget(QWidget *parent, Qt::WindowFlags flags) :
|
|
|
|
QDockWidget(parent, flags),
|
2017-11-15 21:42:39 +00:00
|
|
|
ui(new Ui::HexdumpWidget)
|
2017-03-29 10:18:37 +00:00
|
|
|
{
|
|
|
|
ui->setupUi(this);
|
2017-07-11 11:05:42 +00:00
|
|
|
|
2017-03-29 10:18:37 +00:00
|
|
|
//this->on_actionSettings_menu_1_triggered();
|
|
|
|
|
|
|
|
// Setup hex highlight
|
|
|
|
//connect(ui->hexHexText, SIGNAL(cursorPositionChanged()), this, SLOT(highlightHexCurrentLine()));
|
|
|
|
//highlightHexCurrentLine();
|
|
|
|
|
|
|
|
// Normalize fonts for other OS
|
2017-11-15 21:42:39 +00:00
|
|
|
qhelpers::normalizeFont(ui->hexOffsetText);
|
|
|
|
qhelpers::normalizeFont(ui->hexHexText);
|
|
|
|
qhelpers::normalizeFont(ui->hexASCIIText);
|
2017-03-29 10:18:37 +00:00
|
|
|
|
|
|
|
// Popup menu on Settings toolbutton
|
|
|
|
QMenu *memMenu = new QMenu();
|
|
|
|
ui->memSettingsButton_2->addAction(ui->actionSettings_menu_1);
|
|
|
|
memMenu->addAction(ui->actionSettings_menu_1);
|
|
|
|
ui->memSettingsButton_2->setMenu(memMenu);
|
|
|
|
|
|
|
|
// Set hexdump context menu
|
2017-11-15 21:42:39 +00:00
|
|
|
ui->hexHexText->setContextMenuPolicy(Qt::CustomContextMenu);
|
|
|
|
connect(ui->hexHexText, SIGNAL(customContextMenuRequested(const QPoint &)),
|
2017-03-29 10:18:37 +00:00
|
|
|
this, SLOT(showHexdumpContextMenu(const QPoint &)));
|
2017-11-15 21:42:39 +00:00
|
|
|
ui->hexASCIIText->setContextMenuPolicy(Qt::CustomContextMenu);
|
|
|
|
connect(ui->hexASCIIText, SIGNAL(customContextMenuRequested(const QPoint &)),
|
2017-03-29 10:18:37 +00:00
|
|
|
this, SLOT(showHexASCIIContextMenu(const QPoint &)));
|
|
|
|
|
2017-11-15 21:42:39 +00:00
|
|
|
// Synchronize hexdump scrolling
|
2017-11-17 12:41:30 +00:00
|
|
|
connect(ui->hexOffsetText->verticalScrollBar(), &QScrollBar::valueChanged,
|
|
|
|
ui->hexHexText->verticalScrollBar(), [this]() {
|
|
|
|
ui->hexHexText->verticalScrollBar()->setValue(ui->hexOffsetText->verticalScrollBar()->value());
|
|
|
|
});
|
|
|
|
connect(ui->hexOffsetText->verticalScrollBar(), &QScrollBar::valueChanged,
|
|
|
|
ui->hexASCIIText->verticalScrollBar(), [this]() {
|
|
|
|
ui->hexASCIIText->verticalScrollBar()->setValue(ui->hexOffsetText->verticalScrollBar()->value());
|
|
|
|
});
|
|
|
|
|
|
|
|
connect(ui->hexHexText->verticalScrollBar(), &QScrollBar::valueChanged,
|
|
|
|
ui->hexOffsetText->verticalScrollBar(), [this]() {
|
|
|
|
ui->hexOffsetText->verticalScrollBar()->setValue(ui->hexHexText->verticalScrollBar()->value());
|
|
|
|
});
|
|
|
|
connect(ui->hexHexText->verticalScrollBar(), &QScrollBar::valueChanged,
|
|
|
|
ui->hexASCIIText->verticalScrollBar(), [this]() {
|
|
|
|
ui->hexASCIIText->verticalScrollBar()->setValue(ui->hexHexText->verticalScrollBar()->value());
|
|
|
|
});
|
|
|
|
|
|
|
|
connect(ui->hexASCIIText->verticalScrollBar(), &QScrollBar::valueChanged,
|
|
|
|
ui->hexOffsetText->verticalScrollBar(), [this]() {
|
|
|
|
ui->hexOffsetText->verticalScrollBar()->setValue(ui->hexASCIIText->verticalScrollBar()->value());
|
|
|
|
});
|
|
|
|
connect(ui->hexASCIIText->verticalScrollBar(), &QScrollBar::valueChanged,
|
|
|
|
ui->hexHexText->verticalScrollBar(), [this]() {
|
|
|
|
ui->hexHexText->verticalScrollBar()->setValue(ui->hexASCIIText->verticalScrollBar()->value());
|
|
|
|
});
|
2017-03-29 10:18:37 +00:00
|
|
|
|
|
|
|
// Control Disasm and Hex scroll to add more contents
|
2017-11-17 12:41:30 +00:00
|
|
|
connectScroll(false);
|
2017-04-05 14:03:36 +00:00
|
|
|
|
2017-11-15 21:42:39 +00:00
|
|
|
connect(Core(), SIGNAL(seekChanged(RVA)), this, SLOT(on_seekChanged(RVA)));
|
2017-11-04 11:46:29 +00:00
|
|
|
connect(Core(), SIGNAL(raisePrioritizedMemoryWidget(CutterCore::MemoryWidgetType)), this, SLOT(raisePrioritizedMemoryWidget(CutterCore::MemoryWidgetType)));
|
|
|
|
|
|
|
|
connect(this, &QDockWidget::visibilityChanged, this, [](bool visibility) {
|
|
|
|
if (visibility)
|
|
|
|
{
|
|
|
|
Core()->setMemoryWidgetPriority(CutterCore::MemoryWidgetType::Hexdump);
|
|
|
|
}
|
|
|
|
});
|
2017-05-13 18:09:36 +00:00
|
|
|
|
|
|
|
fillPlugins();
|
2017-04-28 13:09:40 +00:00
|
|
|
}
|
|
|
|
|
2017-10-12 19:55:15 +00:00
|
|
|
HexdumpWidget::HexdumpWidget(const QString &title, QWidget *parent, Qt::WindowFlags flags)
|
|
|
|
: HexdumpWidget(parent, flags)
|
2017-07-11 11:05:42 +00:00
|
|
|
{
|
2017-10-12 19:55:15 +00:00
|
|
|
setWindowTitle(title);
|
2017-07-11 11:05:42 +00:00
|
|
|
}
|
2017-04-28 13:09:40 +00:00
|
|
|
|
2017-10-12 19:55:15 +00:00
|
|
|
|
|
|
|
void HexdumpWidget::on_seekChanged(RVA addr)
|
2017-04-28 13:09:40 +00:00
|
|
|
{
|
2017-10-12 19:55:15 +00:00
|
|
|
refresh(addr);
|
2017-03-29 10:18:37 +00:00
|
|
|
}
|
|
|
|
|
2017-11-04 11:46:29 +00:00
|
|
|
|
|
|
|
void HexdumpWidget::raisePrioritizedMemoryWidget(CutterCore::MemoryWidgetType type)
|
|
|
|
{
|
|
|
|
if (type == CutterCore::MemoryWidgetType::Hexdump)
|
|
|
|
{
|
|
|
|
raise();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-11-17 12:41:30 +00:00
|
|
|
void HexdumpWidget::connectScroll(bool disconnect)
|
|
|
|
{
|
|
|
|
if (disconnect)
|
|
|
|
{
|
|
|
|
this->disconnect(ui->hexASCIIText->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(hexScrolled()));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
connect(ui->hexASCIIText->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(hexScrolled()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-10-12 19:55:15 +00:00
|
|
|
HexdumpWidget::~HexdumpWidget() {}
|
|
|
|
|
2017-03-29 10:18:37 +00:00
|
|
|
/*
|
|
|
|
* Text highlight functions
|
|
|
|
*/
|
2017-10-12 19:55:15 +00:00
|
|
|
void HexdumpWidget::highlightHexCurrentLine()
|
2017-03-29 10:18:37 +00:00
|
|
|
{
|
|
|
|
QList<QTextEdit::ExtraSelection> extraSelections;
|
|
|
|
|
2017-11-15 21:42:39 +00:00
|
|
|
if (!ui->hexHexText->isReadOnly())
|
2017-04-09 19:55:06 +00:00
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
QTextEdit::ExtraSelection selection;
|
|
|
|
|
|
|
|
QColor lineColor = QColor(190, 144, 212);
|
|
|
|
|
|
|
|
selection.format.setBackground(lineColor);
|
|
|
|
selection.format.setProperty(QTextFormat::FullWidthSelection, true);
|
2017-11-15 21:42:39 +00:00
|
|
|
selection.cursor = ui->hexHexText->textCursor();
|
2017-03-29 10:18:37 +00:00
|
|
|
selection.cursor.clearSelection();
|
|
|
|
extraSelections.append(selection);
|
|
|
|
}
|
|
|
|
|
2017-11-15 21:42:39 +00:00
|
|
|
QTextCursor cursor = ui->hexHexText->textCursor();
|
2017-03-29 10:18:37 +00:00
|
|
|
cursor.select(QTextCursor::WordUnderCursor);
|
|
|
|
|
|
|
|
QTextEdit::ExtraSelection currentWord;
|
|
|
|
|
|
|
|
QColor blueColor = QColor(Qt::blue).lighter(160);
|
|
|
|
currentWord.format.setBackground(blueColor);
|
|
|
|
|
|
|
|
currentWord.cursor = cursor;
|
|
|
|
extraSelections.append(currentWord);
|
|
|
|
|
2017-11-15 21:42:39 +00:00
|
|
|
ui->hexHexText->setExtraSelections(extraSelections);
|
2017-03-29 10:18:37 +00:00
|
|
|
|
|
|
|
highlightHexWords(cursor.selectedText());
|
|
|
|
}
|
|
|
|
|
2017-10-12 19:55:15 +00:00
|
|
|
void HexdumpWidget::highlightHexWords(const QString &str)
|
2017-03-29 10:18:37 +00:00
|
|
|
{
|
|
|
|
QString searchString = str;
|
2017-11-15 21:42:39 +00:00
|
|
|
QTextDocument *document = ui->hexHexText->document();
|
2017-03-29 10:18:37 +00:00
|
|
|
|
|
|
|
document->undo();
|
|
|
|
|
|
|
|
QTextCursor highlightCursor(document);
|
|
|
|
QTextCursor cursor(document);
|
|
|
|
|
|
|
|
cursor.beginEditBlock();
|
|
|
|
|
|
|
|
QColor blueColor = QColor(Qt::blue).lighter(160);
|
|
|
|
|
|
|
|
QTextCharFormat plainFormat(highlightCursor.charFormat());
|
|
|
|
QTextCharFormat colorFormat = plainFormat;
|
|
|
|
colorFormat.setBackground(blueColor);
|
|
|
|
|
2017-04-09 19:55:06 +00:00
|
|
|
while (!highlightCursor.isNull() && !highlightCursor.atEnd())
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
highlightCursor = document->find(searchString, highlightCursor, QTextDocument::FindWholeWords);
|
|
|
|
|
2017-04-09 19:55:06 +00:00
|
|
|
if (!highlightCursor.isNull())
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
highlightCursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);
|
|
|
|
highlightCursor.mergeCharFormat(colorFormat);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
cursor.endEditBlock();
|
|
|
|
}
|
|
|
|
|
2017-11-17 12:41:30 +00:00
|
|
|
|
2017-10-12 19:55:15 +00:00
|
|
|
void HexdumpWidget::refresh(RVA addr)
|
2017-04-09 19:55:06 +00:00
|
|
|
{
|
2017-10-12 19:55:15 +00:00
|
|
|
if (addr == RVA_INVALID)
|
2017-04-09 19:55:06 +00:00
|
|
|
{
|
2017-11-15 21:42:39 +00:00
|
|
|
addr = Core()->getOffset();
|
2017-03-29 10:18:37 +00:00
|
|
|
}
|
|
|
|
|
2017-11-18 12:56:48 +00:00
|
|
|
int visibleLines = qhelpers::getMaxFullyDisplayedLines(ui->hexHexText);
|
2017-11-15 21:56:10 +00:00
|
|
|
|
2017-11-15 21:42:39 +00:00
|
|
|
RCoreLocked lcore = Core()->core();
|
2017-03-29 10:18:37 +00:00
|
|
|
|
2017-11-17 12:41:30 +00:00
|
|
|
connectScroll(true);
|
2017-03-29 10:18:37 +00:00
|
|
|
|
2017-11-16 21:12:44 +00:00
|
|
|
|
2017-04-09 17:12:36 +00:00
|
|
|
int cols = lcore->print->cols;
|
2017-11-18 12:56:48 +00:00
|
|
|
RVA marginBytes = static_cast<RVA>(linesMarginDefault) * cols;
|
|
|
|
|
|
|
|
// lower bound of 0
|
|
|
|
if (addr > marginBytes)
|
|
|
|
{
|
|
|
|
topOffset = addr - marginBytes;
|
|
|
|
topOffset = (topOffset / cols) * cols; // align
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
topOffset = 0;
|
|
|
|
}
|
2017-03-29 10:18:37 +00:00
|
|
|
|
|
|
|
|
2017-11-17 12:41:30 +00:00
|
|
|
int fetchLines = visibleLines + linesMarginDefault * 2;
|
2017-11-16 21:12:44 +00:00
|
|
|
RVA bytes = static_cast<RVA>(fetchLines) * cols;
|
2017-03-29 10:18:37 +00:00
|
|
|
|
2017-11-18 12:56:48 +00:00
|
|
|
|
|
|
|
// upper bound of UT64_MAX
|
|
|
|
RVA bytesLeft = UT64_MAX - topOffset;
|
|
|
|
if (bytes > bytesLeft)
|
|
|
|
{
|
|
|
|
bottomOffset = UT64_MAX;
|
|
|
|
topOffset = bottomOffset - bytes;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
bottomOffset = topOffset + bytes;
|
|
|
|
}
|
|
|
|
|
2017-11-16 21:12:44 +00:00
|
|
|
|
|
|
|
auto hexdump = fetchHexdump(topOffset, bytes);
|
2017-03-29 10:18:37 +00:00
|
|
|
|
2017-11-16 21:12:44 +00:00
|
|
|
ui->hexOffsetText->setPlainText(hexdump[0]);
|
|
|
|
ui->hexHexText->setPlainText(hexdump[1]);
|
|
|
|
ui->hexASCIIText->setPlainText(hexdump[2]);
|
2017-11-15 21:42:39 +00:00
|
|
|
resizeHexdump();
|
2017-03-29 10:18:37 +00:00
|
|
|
|
|
|
|
// Move cursor to desired address
|
2017-11-15 21:42:39 +00:00
|
|
|
QTextCursor cur = ui->hexOffsetText->textCursor();
|
2017-11-16 21:12:44 +00:00
|
|
|
cur.movePosition(QTextCursor::Start);
|
2017-11-17 12:41:30 +00:00
|
|
|
cur.movePosition(QTextCursor::Down, QTextCursor::MoveAnchor, linesMarginDefault);
|
2017-11-16 21:12:44 +00:00
|
|
|
ui->hexOffsetText->setTextCursor(cur);
|
2017-03-29 10:18:37 +00:00
|
|
|
|
2017-11-18 12:56:48 +00:00
|
|
|
int scroll = static_cast<int>((addr - topOffset) / cols);
|
|
|
|
ui->hexOffsetText->verticalScrollBar()->setValue(scroll);
|
|
|
|
ui->hexHexText->verticalScrollBar()->setValue(scroll);
|
|
|
|
ui->hexASCIIText->verticalScrollBar()->setValue(scroll);
|
2017-11-17 12:41:30 +00:00
|
|
|
|
2017-11-18 12:56:48 +00:00
|
|
|
connectScroll(false);
|
2017-11-17 12:41:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void HexdumpWidget::appendHexdumpLines(int lines, bool top)
|
|
|
|
{
|
|
|
|
connectScroll(true);
|
|
|
|
|
|
|
|
int cols = Core()->getConfigi("hex.cols");
|
|
|
|
RVA bytes = static_cast<RVA>(lines) * cols;
|
|
|
|
|
|
|
|
if (top)
|
|
|
|
{
|
2017-11-18 12:56:48 +00:00
|
|
|
if (bytes > topOffset)
|
|
|
|
{
|
|
|
|
bytes = topOffset;
|
|
|
|
if (bytes == 0)
|
|
|
|
{
|
|
|
|
connectScroll(false);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-17 12:41:30 +00:00
|
|
|
topOffset -= bytes;
|
|
|
|
auto hexdump = fetchHexdump(topOffset, bytes);
|
|
|
|
|
|
|
|
int scroll = ui->hexASCIIText->verticalScrollBar()->value();
|
|
|
|
|
|
|
|
QTextCursor cur = ui->hexOffsetText->textCursor();
|
|
|
|
cur.movePosition(QTextCursor::Start);
|
|
|
|
cur.insertText(hexdump[0]);
|
|
|
|
|
|
|
|
cur = ui->hexHexText->textCursor();
|
|
|
|
cur.movePosition(QTextCursor::Start);
|
|
|
|
cur.insertText(hexdump[1]);
|
|
|
|
|
|
|
|
cur = ui->hexASCIIText->textCursor();
|
|
|
|
cur.movePosition(QTextCursor::Start);
|
|
|
|
cur.insertText(hexdump[2]);
|
|
|
|
|
|
|
|
int actualLines = static_cast<int>(bytes / cols);
|
2017-11-18 12:56:48 +00:00
|
|
|
ui->hexOffsetText->verticalScrollBar()->setValue(actualLines + scroll);
|
|
|
|
ui->hexHexText->verticalScrollBar()->setValue(actualLines + scroll);
|
2017-11-17 12:41:30 +00:00
|
|
|
ui->hexASCIIText->verticalScrollBar()->setValue(actualLines + scroll);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-11-18 12:56:48 +00:00
|
|
|
if (bytes > UT64_MAX - bottomOffset)
|
|
|
|
{
|
|
|
|
bytes = UT64_MAX - bottomOffset;
|
|
|
|
|
|
|
|
if (bytes == 0)
|
|
|
|
{
|
|
|
|
connectScroll(false);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-17 12:41:30 +00:00
|
|
|
auto hexdump = fetchHexdump(bottomOffset, bytes);
|
|
|
|
bottomOffset += bytes;
|
|
|
|
|
|
|
|
QTextCursor cur = ui->hexOffsetText->textCursor();
|
|
|
|
cur.movePosition(QTextCursor::End);
|
|
|
|
cur.insertText(hexdump[0]);
|
|
|
|
|
|
|
|
cur = ui->hexHexText->textCursor();
|
|
|
|
cur.movePosition(QTextCursor::End);
|
|
|
|
cur.insertText(hexdump[1]);
|
|
|
|
|
|
|
|
cur = ui->hexASCIIText->textCursor();
|
|
|
|
cur.movePosition(QTextCursor::End);
|
|
|
|
cur.insertText(hexdump[2]);
|
|
|
|
}
|
2017-10-12 19:55:15 +00:00
|
|
|
|
2017-11-17 12:41:30 +00:00
|
|
|
connectScroll(false);
|
2017-10-12 19:55:15 +00:00
|
|
|
}
|
|
|
|
|
2017-11-17 12:41:30 +00:00
|
|
|
void HexdumpWidget::removeHexdumpLines(int lines, bool top)
|
|
|
|
{
|
|
|
|
connectScroll(true);
|
|
|
|
|
|
|
|
int cols = Core()->getConfigi("hex.cols");
|
|
|
|
|
|
|
|
std::array<QPlainTextEdit *, 3> edits = { ui->hexOffsetText, ui->hexHexText, ui->hexASCIIText };
|
|
|
|
|
|
|
|
int scroll = ui->hexASCIIText->verticalScrollBar()->value();
|
|
|
|
|
2017-11-18 12:56:48 +00:00
|
|
|
if (top)
|
2017-11-17 12:41:30 +00:00
|
|
|
{
|
2017-11-18 12:56:48 +00:00
|
|
|
for (QPlainTextEdit *edit : edits)
|
2017-11-17 12:41:30 +00:00
|
|
|
{
|
2017-11-18 12:56:48 +00:00
|
|
|
QTextCursor cur = edit->textCursor();
|
2017-11-17 12:41:30 +00:00
|
|
|
cur.movePosition(QTextCursor::Start);
|
|
|
|
cur.movePosition(QTextCursor::Down, QTextCursor::KeepAnchor, lines + 1);
|
2017-11-18 12:56:48 +00:00
|
|
|
cur.removeSelectedText();
|
2017-11-17 12:41:30 +00:00
|
|
|
}
|
2017-11-18 12:56:48 +00:00
|
|
|
|
|
|
|
topOffset += lines * cols;
|
|
|
|
|
|
|
|
ui->hexOffsetText->verticalScrollBar()->setValue(scroll - lines);
|
|
|
|
ui->hexHexText->verticalScrollBar()->setValue(scroll - lines);
|
|
|
|
ui->hexASCIIText->verticalScrollBar()->setValue(scroll - lines);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for (QPlainTextEdit *edit : edits)
|
2017-11-17 12:41:30 +00:00
|
|
|
{
|
2017-11-18 12:56:48 +00:00
|
|
|
QTextCursor cur = edit->textCursor();
|
2017-11-17 12:41:30 +00:00
|
|
|
cur.movePosition(QTextCursor::End);
|
|
|
|
cur.movePosition(QTextCursor::Up, QTextCursor::KeepAnchor, lines);
|
|
|
|
cur.movePosition(QTextCursor::StartOfLine, QTextCursor::KeepAnchor);
|
|
|
|
cur.removeSelectedText();
|
|
|
|
}
|
|
|
|
|
2017-11-18 12:56:48 +00:00
|
|
|
bottomOffset -= lines * cols;
|
2017-11-17 12:41:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
connectScroll(false);
|
|
|
|
}
|
2017-11-15 21:56:10 +00:00
|
|
|
|
2017-10-12 19:55:15 +00:00
|
|
|
/*
|
|
|
|
* Content management functions
|
|
|
|
*/
|
|
|
|
|
|
|
|
void HexdumpWidget::fillPlugins()
|
|
|
|
{
|
|
|
|
// Fill the plugins combo for the hexdump sidebar
|
2017-11-15 21:42:39 +00:00
|
|
|
ui->hexArchComboBox_2->insertItems(0, Core()->getAsmPluginNames());
|
2017-03-29 10:18:37 +00:00
|
|
|
}
|
|
|
|
|
2017-11-16 21:12:44 +00:00
|
|
|
std::array<QString, 3> HexdumpWidget::fetchHexdump(RVA offset, RVA bytes)
|
2017-04-09 19:55:06 +00:00
|
|
|
{
|
2017-11-16 21:12:44 +00:00
|
|
|
QString hexdump = Core()->cmd(QString("px %1 @ %2").arg(QString::number(bytes), QString::number(offset)));
|
2017-03-29 10:18:37 +00:00
|
|
|
|
2017-04-12 20:44:05 +00:00
|
|
|
QString offsets;
|
|
|
|
QString hex;
|
|
|
|
QString ascii;
|
2017-03-29 10:18:37 +00:00
|
|
|
int ln = 0;
|
|
|
|
|
2017-11-16 21:12:44 +00:00
|
|
|
for (const QString &line : hexdump.split("\n"))
|
2017-03-29 10:18:37 +00:00
|
|
|
{
|
2017-11-17 12:41:30 +00:00
|
|
|
if (ln++ == 0 || line.trimmed().isEmpty())
|
2017-03-29 10:18:37 +00:00
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
2017-11-17 12:41:30 +00:00
|
|
|
|
2017-03-29 10:18:37 +00:00
|
|
|
int wc = 0;
|
|
|
|
for (const QString a : line.split(" "))
|
|
|
|
{
|
|
|
|
switch (wc++)
|
|
|
|
{
|
2017-10-12 19:55:15 +00:00
|
|
|
case 0:
|
|
|
|
offsets += a + "\n";
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
hex += a.trimmed() + "\n";
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
ascii += a + "\n";
|
|
|
|
break;
|
2017-03-29 10:18:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-16 21:12:44 +00:00
|
|
|
return { offsets, hex, ascii };
|
2017-03-29 10:18:37 +00:00
|
|
|
}
|
|
|
|
|
2017-10-12 19:55:15 +00:00
|
|
|
void HexdumpWidget::resizeHexdump()
|
2017-04-09 19:55:06 +00:00
|
|
|
{
|
2017-11-15 21:42:39 +00:00
|
|
|
ui->hexOffsetText->setMinimumWidth(static_cast<int>(ui->hexOffsetText->document()->size().width()));
|
|
|
|
ui->hexHexText->setMinimumWidth(static_cast<int>(ui->hexHexText->document()->size().width()));
|
2017-11-17 12:41:30 +00:00
|
|
|
|
2017-11-02 06:48:32 +00:00
|
|
|
//this->hexASCIIText->setMinimumWidth(this->hexASCIIText->document()->size().width());
|
2017-03-29 10:18:37 +00:00
|
|
|
}
|
|
|
|
|
2017-10-12 19:55:15 +00:00
|
|
|
void HexdumpWidget::hexScrolled()
|
2017-03-29 10:18:37 +00:00
|
|
|
{
|
2017-11-15 21:42:39 +00:00
|
|
|
QScrollBar *sb = ui->hexASCIIText->verticalScrollBar();
|
2017-11-18 12:56:48 +00:00
|
|
|
int topMargin = sb->value() - sb->minimum();
|
|
|
|
int bottomMargin = sb->maximum() - sb->value();
|
2017-03-29 10:18:37 +00:00
|
|
|
|
2017-11-17 12:41:30 +00:00
|
|
|
if (topMargin < linesMarginMin)
|
|
|
|
{
|
|
|
|
int loadLines = linesMarginDefault - topMargin;
|
|
|
|
appendHexdumpLines(loadLines, true);
|
|
|
|
}
|
2017-03-29 10:18:37 +00:00
|
|
|
|
2017-11-17 12:41:30 +00:00
|
|
|
if(bottomMargin < linesMarginMin)
|
|
|
|
{
|
|
|
|
int loadLines = linesMarginDefault - bottomMargin;
|
|
|
|
appendHexdumpLines(loadLines, false);
|
|
|
|
}
|
2017-03-29 10:18:37 +00:00
|
|
|
|
2017-11-17 12:41:30 +00:00
|
|
|
if(topMargin > linesMarginMax)
|
|
|
|
{
|
|
|
|
int removeLines = topMargin - linesMarginDefault;
|
|
|
|
removeHexdumpLines(removeLines, true);
|
2017-04-09 19:55:06 +00:00
|
|
|
}
|
2017-11-17 12:41:30 +00:00
|
|
|
|
|
|
|
if(bottomMargin > linesMarginMax)
|
2017-04-09 19:55:06 +00:00
|
|
|
{
|
2017-11-17 12:41:30 +00:00
|
|
|
int removeLines = bottomMargin - linesMarginDefault;
|
|
|
|
removeHexdumpLines(removeLines, false);
|
|
|
|
}
|
2017-03-29 10:18:37 +00:00
|
|
|
}
|
|
|
|
|
2017-11-16 21:12:44 +00:00
|
|
|
void HexdumpWidget::on_hexHexText_selectionChanged()
|
2017-03-29 10:18:37 +00:00
|
|
|
{
|
|
|
|
// Get selected partsing type
|
|
|
|
QString parsing = ui->codeCombo_2->currentText();
|
|
|
|
// Get selected text
|
2017-11-15 21:42:39 +00:00
|
|
|
QTextCursor cursor(ui->hexHexText->textCursor());
|
2017-03-29 10:18:37 +00:00
|
|
|
QString sel_text = cursor.selectedText();
|
|
|
|
|
|
|
|
sel_text = sel_text.simplified().remove(" ");
|
|
|
|
//eprintf ("-- (((%s))) --\n", sel_text.toUtf8().constData());
|
|
|
|
|
2017-04-09 19:55:06 +00:00
|
|
|
if (sel_text == "")
|
|
|
|
{
|
2017-11-15 21:42:39 +00:00
|
|
|
ui->hexDisasTextEdit->setPlainText("");
|
2017-03-29 10:18:37 +00:00
|
|
|
ui->bytesEntropy->setText("");
|
|
|
|
ui->bytesMD5->setText("");
|
|
|
|
ui->bytesSHA1->setText("");
|
2017-04-09 19:55:06 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (parsing == "Dissasembly")
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
// Get selected combos
|
|
|
|
QString arch = ui->hexArchComboBox_2->currentText();
|
|
|
|
QString bits = ui->hexBitsComboBox_2->currentText();
|
|
|
|
|
2017-11-15 21:42:39 +00:00
|
|
|
QString oarch = Core()->getConfig("asm.arch");
|
|
|
|
QString obits = Core()->getConfig("asm.bits");
|
2017-03-29 10:18:37 +00:00
|
|
|
|
2017-11-15 21:42:39 +00:00
|
|
|
Core()->setConfig("asm.arch", arch);
|
|
|
|
Core()->setConfig("asm.bits", bits);
|
|
|
|
QString str = Core()->cmd("pad " + sel_text);
|
|
|
|
ui->hexDisasTextEdit->setPlainText(str);
|
|
|
|
Core()->setConfig("asm.arch", oarch);
|
|
|
|
Core()->setConfig("asm.bits", obits);
|
2017-03-29 10:18:37 +00:00
|
|
|
//qDebug() << "Selected Arch: " << arch;
|
|
|
|
//qDebug() << "Selected Bits: " << bits;
|
|
|
|
//qDebug() << "Selected Text: " << sel_text;
|
|
|
|
}
|
2017-10-12 19:55:15 +00:00
|
|
|
// TODO: update on selection changes.. use cmd("pc "+len+"@"+off)
|
2017-04-09 19:55:06 +00:00
|
|
|
else if (parsing == "C byte array")
|
|
|
|
{
|
2017-11-15 21:42:39 +00:00
|
|
|
ui->hexDisasTextEdit->setPlainText(Core()->cmd("pc@x:" + sel_text));
|
2017-04-09 19:55:06 +00:00
|
|
|
}
|
|
|
|
else if (parsing == "C dword array")
|
|
|
|
{
|
2017-11-15 21:42:39 +00:00
|
|
|
ui->hexDisasTextEdit->setPlainText(Core()->cmd("pcw@x:" + sel_text));
|
2017-04-09 19:55:06 +00:00
|
|
|
}
|
|
|
|
else if (parsing == "C qword array")
|
|
|
|
{
|
2017-11-15 21:42:39 +00:00
|
|
|
ui->hexDisasTextEdit->setPlainText(Core()->cmd("pcq@x:" + sel_text));
|
2017-04-09 19:55:06 +00:00
|
|
|
}
|
|
|
|
else if (parsing == "Assembler")
|
|
|
|
{
|
2017-11-15 21:42:39 +00:00
|
|
|
ui->hexDisasTextEdit->setPlainText(Core()->cmd("pca@x:" + sel_text));
|
2017-04-09 19:55:06 +00:00
|
|
|
}
|
|
|
|
else if (parsing == "String")
|
|
|
|
{
|
2017-11-15 21:42:39 +00:00
|
|
|
ui->hexDisasTextEdit->setPlainText(Core()->cmd("pcs@x:" + sel_text));
|
2017-04-09 19:55:06 +00:00
|
|
|
}
|
|
|
|
else if (parsing == "JSON")
|
|
|
|
{
|
2017-11-15 21:42:39 +00:00
|
|
|
ui->hexDisasTextEdit->setPlainText(Core()->cmd("pcj@x:" + sel_text));
|
2017-04-09 19:55:06 +00:00
|
|
|
}
|
|
|
|
else if (parsing == "Javascript")
|
|
|
|
{
|
2017-11-15 21:42:39 +00:00
|
|
|
ui->hexDisasTextEdit->setPlainText(Core()->cmd("pcJ@x:" + sel_text));
|
2017-04-09 19:55:06 +00:00
|
|
|
}
|
|
|
|
else if (parsing == "Python")
|
|
|
|
{
|
2017-11-15 21:42:39 +00:00
|
|
|
ui->hexDisasTextEdit->setPlainText(Core()->cmd("pcp@x:" + sel_text));
|
2017-03-29 10:18:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Fill the information tab hashes and entropy
|
2017-11-15 21:42:39 +00:00
|
|
|
ui->bytesMD5->setText(Core()->cmd("ph md5@x:" + sel_text).trimmed());
|
|
|
|
ui->bytesSHA1->setText(Core()->cmd("ph sha1@x:" + sel_text).trimmed());
|
|
|
|
ui->bytesEntropy->setText(Core()->cmd("ph entropy@x:" + sel_text).trimmed());
|
2017-03-29 10:18:37 +00:00
|
|
|
ui->bytesMD5->setCursorPosition(0);
|
|
|
|
ui->bytesSHA1->setCursorPosition(0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-10-12 19:55:15 +00:00
|
|
|
void HexdumpWidget::on_hexArchComboBox_2_currentTextChanged(const QString &/*arg1*/)
|
2017-03-29 10:18:37 +00:00
|
|
|
{
|
2017-11-16 21:12:44 +00:00
|
|
|
on_hexHexText_selectionChanged();
|
2017-03-29 10:18:37 +00:00
|
|
|
}
|
|
|
|
|
2017-10-12 19:55:15 +00:00
|
|
|
void HexdumpWidget::on_hexBitsComboBox_2_currentTextChanged(const QString &/*arg1*/)
|
2017-03-29 10:18:37 +00:00
|
|
|
{
|
2017-11-16 21:12:44 +00:00
|
|
|
on_hexHexText_selectionChanged();
|
2017-03-29 10:18:37 +00:00
|
|
|
}
|
|
|
|
/*
|
|
|
|
* Context menu functions
|
|
|
|
*/
|
|
|
|
|
2017-10-12 19:55:15 +00:00
|
|
|
void HexdumpWidget::showHexdumpContextMenu(const QPoint &pt)
|
2017-03-29 10:18:37 +00:00
|
|
|
{
|
|
|
|
// Set Hexdump popup menu
|
2017-11-15 21:42:39 +00:00
|
|
|
QMenu *menu = ui->hexHexText->createStandardContextMenu();
|
2017-03-29 10:18:37 +00:00
|
|
|
menu->clear();
|
|
|
|
menu->addAction(ui->actionHexCopy_Hexpair);
|
|
|
|
menu->addAction(ui->actionHexCopy_ASCII);
|
|
|
|
menu->addAction(ui->actionHexCopy_Text);
|
|
|
|
menu->addSeparator();
|
2017-04-09 19:55:06 +00:00
|
|
|
QMenu *colSubmenu = menu->addMenu("Columns");
|
2017-03-29 10:18:37 +00:00
|
|
|
colSubmenu->addAction(ui->action4columns);
|
|
|
|
colSubmenu->addAction(ui->action8columns);
|
|
|
|
colSubmenu->addAction(ui->action16columns);
|
|
|
|
colSubmenu->addAction(ui->action32columns);
|
|
|
|
menu->addSeparator();
|
|
|
|
menu->addAction(ui->actionHexEdit);
|
|
|
|
menu->addAction(ui->actionHexPaste);
|
|
|
|
menu->addSeparator();
|
|
|
|
menu->addAction(ui->actionHexInsert_Hex);
|
|
|
|
menu->addAction(ui->actionHexInsert_String);
|
|
|
|
|
2017-11-15 21:42:39 +00:00
|
|
|
ui->hexHexText->setContextMenuPolicy(Qt::CustomContextMenu);
|
2017-03-29 10:18:37 +00:00
|
|
|
|
2017-11-15 21:42:39 +00:00
|
|
|
menu->exec(ui->hexHexText->mapToGlobal(pt));
|
2017-03-29 10:18:37 +00:00
|
|
|
delete menu;
|
|
|
|
}
|
|
|
|
|
2017-10-12 19:55:15 +00:00
|
|
|
void HexdumpWidget::showHexASCIIContextMenu(const QPoint &pt)
|
2017-03-29 10:18:37 +00:00
|
|
|
{
|
|
|
|
// Set Hex ASCII popup menu
|
2017-11-15 21:42:39 +00:00
|
|
|
QMenu *menu = ui->hexASCIIText->createStandardContextMenu();
|
2017-03-29 10:18:37 +00:00
|
|
|
menu->clear();
|
|
|
|
menu->addAction(ui->actionHexCopy_Hexpair);
|
|
|
|
menu->addAction(ui->actionHexCopy_ASCII);
|
|
|
|
menu->addAction(ui->actionHexCopy_Text);
|
|
|
|
menu->addSeparator();
|
2017-04-09 19:55:06 +00:00
|
|
|
QMenu *colSubmenu = menu->addMenu("Columns");
|
2017-03-29 10:18:37 +00:00
|
|
|
colSubmenu->addAction(ui->action4columns);
|
|
|
|
colSubmenu->addAction(ui->action8columns);
|
|
|
|
colSubmenu->addAction(ui->action16columns);
|
|
|
|
colSubmenu->addAction(ui->action32columns);
|
|
|
|
menu->addSeparator();
|
|
|
|
menu->addAction(ui->actionHexEdit);
|
|
|
|
menu->addAction(ui->actionHexPaste);
|
|
|
|
menu->addSeparator();
|
|
|
|
menu->addAction(ui->actionHexInsert_Hex);
|
|
|
|
menu->addAction(ui->actionHexInsert_String);
|
|
|
|
|
2017-11-15 21:42:39 +00:00
|
|
|
ui->hexASCIIText->setContextMenuPolicy(Qt::CustomContextMenu);
|
2017-03-29 10:18:37 +00:00
|
|
|
|
2017-11-15 21:42:39 +00:00
|
|
|
menu->exec(ui->hexASCIIText->mapToGlobal(pt));
|
2017-03-29 10:18:37 +00:00
|
|
|
delete menu;
|
|
|
|
}
|
2017-11-17 12:41:30 +00:00
|
|
|
|
2017-03-29 10:18:37 +00:00
|
|
|
/*
|
|
|
|
* Actions callback functions
|
|
|
|
*/
|
|
|
|
|
2017-10-12 19:55:15 +00:00
|
|
|
void HexdumpWidget::on_actionSettings_menu_1_triggered()
|
2017-03-29 10:18:37 +00:00
|
|
|
{
|
|
|
|
bool ok = true;
|
|
|
|
|
2017-10-11 21:07:32 +00:00
|
|
|
QFont font = QFont("Monospace", 8);
|
2017-09-28 21:53:59 +00:00
|
|
|
// TODO Use global configuration
|
2017-10-11 21:07:32 +00:00
|
|
|
//QFont font = QFontDialog::getFont(&ok, ui->disasTextEdit_2->font(), this);
|
2017-04-13 15:14:02 +00:00
|
|
|
|
|
|
|
if (ok)
|
|
|
|
{
|
|
|
|
setFonts(font);
|
|
|
|
|
|
|
|
emit fontChanged(font);
|
|
|
|
}
|
2017-03-29 10:18:37 +00:00
|
|
|
}
|
2017-10-11 21:07:32 +00:00
|
|
|
|
2017-11-17 12:41:30 +00:00
|
|
|
|
2017-10-12 19:55:15 +00:00
|
|
|
void HexdumpWidget::setFonts(QFont font)
|
2017-04-09 19:55:06 +00:00
|
|
|
{
|
2017-10-11 21:07:32 +00:00
|
|
|
//ui->disasTextEdit_2->setFont(font);
|
2017-03-29 10:18:37 +00:00
|
|
|
// the user clicked OK and font is set to the font the user selected
|
2017-10-11 21:07:32 +00:00
|
|
|
//ui->disasTextEdit_2->setFont(font);
|
2017-11-15 21:42:39 +00:00
|
|
|
ui->hexOffsetText->setFont(font);
|
|
|
|
ui->hexHexText->setFont(font);
|
|
|
|
ui->hexASCIIText->setFont(font);
|
2017-03-29 10:18:37 +00:00
|
|
|
}
|
|
|
|
|
2017-10-12 19:55:15 +00:00
|
|
|
void HexdumpWidget::on_actionHideHexdump_side_panel_triggered()
|
2017-03-29 10:18:37 +00:00
|
|
|
{
|
2017-04-09 19:55:06 +00:00
|
|
|
if (ui->hexSideTab_2->isVisible())
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
ui->hexSideTab_2->hide();
|
2017-04-09 19:55:06 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
ui->hexSideTab_2->show();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-10-12 19:55:15 +00:00
|
|
|
/*void HexdumpWidget::on_actionSend_to_Notepad_triggered()
|
2017-03-29 10:18:37 +00:00
|
|
|
{
|
|
|
|
QTextCursor cursor = ui->disasTextEdit_2->textCursor();
|
|
|
|
QString text = cursor.selectedText();
|
2017-10-09 18:08:35 +00:00
|
|
|
// TODO
|
|
|
|
// this->main->sendToNotepad(text);
|
2017-10-11 21:07:32 +00:00
|
|
|
}*/
|
2017-03-29 10:18:37 +00:00
|
|
|
|
2017-10-12 19:55:15 +00:00
|
|
|
void HexdumpWidget::on_action8columns_triggered()
|
2017-03-29 10:18:37 +00:00
|
|
|
{
|
2017-11-15 21:42:39 +00:00
|
|
|
Core()->setConfig("hex.cols", 8);
|
|
|
|
refresh();
|
2017-03-29 10:18:37 +00:00
|
|
|
}
|
|
|
|
|
2017-10-12 19:55:15 +00:00
|
|
|
void HexdumpWidget::on_action16columns_triggered()
|
2017-03-29 10:18:37 +00:00
|
|
|
{
|
2017-11-15 21:42:39 +00:00
|
|
|
Core()->setConfig("hex.cols", 16);
|
|
|
|
refresh();
|
2017-03-29 10:18:37 +00:00
|
|
|
}
|
|
|
|
|
2017-10-12 19:55:15 +00:00
|
|
|
void HexdumpWidget::on_action4columns_triggered()
|
2017-03-29 10:18:37 +00:00
|
|
|
{
|
2017-11-15 21:42:39 +00:00
|
|
|
Core()->setConfig("hex.cols", 4);
|
|
|
|
refresh();
|
2017-03-29 10:18:37 +00:00
|
|
|
}
|
|
|
|
|
2017-10-12 19:55:15 +00:00
|
|
|
void HexdumpWidget::on_action32columns_triggered()
|
2017-03-29 10:18:37 +00:00
|
|
|
{
|
2017-11-15 21:42:39 +00:00
|
|
|
Core()->setConfig("hex.cols", 32);
|
|
|
|
refresh();
|
2017-03-29 10:18:37 +00:00
|
|
|
}
|
|
|
|
|
2017-10-12 19:55:15 +00:00
|
|
|
void HexdumpWidget::on_action64columns_triggered()
|
2017-03-29 10:18:37 +00:00
|
|
|
{
|
2017-11-15 21:42:39 +00:00
|
|
|
Core()->setConfig("hex.cols", 64);
|
|
|
|
refresh();
|
2017-03-29 10:18:37 +00:00
|
|
|
}
|
|
|
|
|
2017-10-12 19:55:15 +00:00
|
|
|
void HexdumpWidget::on_action2columns_triggered()
|
2017-03-29 10:18:37 +00:00
|
|
|
{
|
2017-11-15 21:42:39 +00:00
|
|
|
Core()->setConfig("hex.cols", 2);
|
|
|
|
refresh();
|
2017-03-29 10:18:37 +00:00
|
|
|
}
|
|
|
|
|
2017-10-12 19:55:15 +00:00
|
|
|
void HexdumpWidget::on_action1column_triggered()
|
2017-03-29 10:18:37 +00:00
|
|
|
{
|
2017-11-15 21:42:39 +00:00
|
|
|
Core()->setConfig("hex.cols", 1);
|
|
|
|
refresh();
|
2017-03-29 10:18:37 +00:00
|
|
|
}
|
|
|
|
|
2017-10-12 19:55:15 +00:00
|
|
|
void HexdumpWidget::on_codeCombo_2_currentTextChanged(const QString &arg1)
|
2017-03-29 10:18:37 +00:00
|
|
|
{
|
2017-04-09 19:55:06 +00:00
|
|
|
if (arg1 == "Dissasembly")
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
ui->hexSideFrame_2->show();
|
2017-11-15 21:42:39 +00:00
|
|
|
ui->hexDisasTextEdit->setPlainText(";; Select some bytes on the left\n;; to see them disassembled");
|
2017-04-09 19:55:06 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
ui->hexSideFrame_2->hide();
|
2017-11-15 21:42:39 +00:00
|
|
|
ui->hexDisasTextEdit->setPlainText(";; Select some bytes on the left\n;; to see them parsed here");
|
2017-03-29 10:18:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-10-12 19:55:15 +00:00
|
|
|
QString HexdumpWidget::normalize_addr(QString addr)
|
2017-04-09 19:55:06 +00:00
|
|
|
{
|
2017-11-15 21:42:39 +00:00
|
|
|
QString base = Core()->cmd("s").split("0x")[1].trimmed();
|
2017-03-29 10:18:37 +00:00
|
|
|
int len = base.length();
|
2017-04-09 19:55:06 +00:00
|
|
|
if (len < 8)
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
int padding = 8 - len;
|
|
|
|
QString zero = "0";
|
|
|
|
QString zeroes = zero.repeated(padding);
|
|
|
|
QString s = "0x" + zeroes + base;
|
|
|
|
return s;
|
2017-04-09 19:55:06 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-04-24 06:49:35 +00:00
|
|
|
return addr.trimmed();
|
2017-03-29 10:18:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-10-12 19:55:15 +00:00
|
|
|
QString HexdumpWidget::normalizeAddr(QString addr)
|
2017-04-09 19:55:06 +00:00
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
QString base = addr.split("0x")[1].trimmed();
|
|
|
|
int len = base.length();
|
2017-04-09 19:55:06 +00:00
|
|
|
if (len < 8)
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
int padding = 8 - len;
|
|
|
|
QString zero = "0";
|
|
|
|
QString zeroes = zero.repeated(padding);
|
|
|
|
QString s = "0x" + zeroes + base;
|
|
|
|
return s;
|
2017-04-09 19:55:06 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
return addr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-10-12 19:55:15 +00:00
|
|
|
void HexdumpWidget::on_hexSideTab_2_currentChanged(int /*index*/)
|
2017-03-29 10:18:37 +00:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
if (index == 2) {
|
|
|
|
// Add data to HTML Polar functions graph
|
|
|
|
QFile html(":/html/bar.html");
|
|
|
|
if(!html.open(QIODevice::ReadOnly)) {
|
|
|
|
QMessageBox::information(0,"error",html.errorString());
|
|
|
|
}
|
|
|
|
QString code = html.readAll();
|
|
|
|
html.close();
|
|
|
|
this->histoWebView->setHtml(code);
|
|
|
|
this->histoWebView->show();
|
|
|
|
} else {
|
|
|
|
this->histoWebView->hide();
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
|
2017-10-12 19:55:15 +00:00
|
|
|
void HexdumpWidget::on_memSideToolButton_clicked()
|
2017-03-29 10:18:37 +00:00
|
|
|
{
|
2017-04-09 19:55:06 +00:00
|
|
|
if (ui->memSideToolButton->isChecked())
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
ui->hexSideTab_2->hide();
|
2017-06-15 09:53:10 +00:00
|
|
|
ui->memSideToolButton->setIcon(QIcon(":/img/icons/left_light.svg"));
|
2017-04-09 19:55:06 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-03-29 10:18:37 +00:00
|
|
|
ui->hexSideTab_2->show();
|
2017-06-15 09:53:10 +00:00
|
|
|
ui->memSideToolButton->setIcon(QIcon(":/img/icons/right_light.svg"));
|
2017-03-29 10:18:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-10-12 19:55:15 +00:00
|
|
|
void HexdumpWidget::resizeEvent(QResizeEvent *event)
|
2017-04-09 19:55:06 +00:00
|
|
|
{
|
2017-10-09 18:08:35 +00:00
|
|
|
// FIXME
|
|
|
|
/*
|
2017-04-13 15:51:58 +00:00
|
|
|
if (main->responsive && isVisible())
|
2017-04-09 19:55:06 +00:00
|
|
|
{
|
2017-04-10 10:25:33 +00:00
|
|
|
if (event->size().width() <= 1150)
|
2017-04-09 19:55:06 +00:00
|
|
|
{
|
2017-04-10 10:25:33 +00:00
|
|
|
ui->frame_3->setVisible(false);
|
|
|
|
ui->memPreviewTab->setVisible(false);
|
|
|
|
ui->previewToolButton_2->setChecked(false);
|
|
|
|
if (event->size().width() <= 950)
|
2017-04-09 19:55:06 +00:00
|
|
|
{
|
2017-04-10 10:25:33 +00:00
|
|
|
ui->memSideTabWidget_2->hide();
|
|
|
|
ui->hexSideTab_2->hide();
|
|
|
|
ui->memSideToolButton->setChecked(true);
|
2017-04-09 19:55:06 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-04-10 10:25:33 +00:00
|
|
|
ui->memSideTabWidget_2->show();
|
|
|
|
ui->hexSideTab_2->show();
|
|
|
|
ui->memSideToolButton->setChecked(false);
|
2017-04-09 17:09:52 +00:00
|
|
|
}
|
|
|
|
}
|
2017-04-10 10:25:33 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
ui->frame_3->setVisible(true);
|
|
|
|
ui->memPreviewTab->setVisible(true);
|
|
|
|
ui->previewToolButton_2->setChecked(true);
|
|
|
|
}
|
2017-04-09 19:55:06 +00:00
|
|
|
}
|
2017-10-09 18:08:35 +00:00
|
|
|
*/
|
2017-04-10 10:25:33 +00:00
|
|
|
QDockWidget::resizeEvent(event);
|
|
|
|
}
|
|
|
|
|
2017-11-08 13:17:24 +00:00
|
|
|
void HexdumpWidget::wheelEvent(QWheelEvent* event)
|
|
|
|
{
|
|
|
|
if( Qt::ControlModifier == event->modifiers() )
|
|
|
|
{
|
|
|
|
const QPoint numDegrees = event->angleDelta() / 8;
|
|
|
|
if(!numDegrees.isNull())
|
|
|
|
{
|
|
|
|
const QPoint numSteps = numDegrees / 15;
|
|
|
|
if( 0 != numSteps.y() )
|
|
|
|
{
|
|
|
|
if(numSteps.y() > 0)
|
|
|
|
{
|
|
|
|
zoomIn(1);
|
|
|
|
}
|
|
|
|
else if( numSteps.y() < 0 )
|
|
|
|
{
|
|
|
|
zoomOut(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
event->accept();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
event->ignore();
|
|
|
|
}
|
|
|
|
|
2017-10-12 19:55:15 +00:00
|
|
|
void HexdumpWidget::on_copyMD5_clicked()
|
2017-03-29 10:18:37 +00:00
|
|
|
{
|
|
|
|
QString md5 = ui->bytesMD5->text();
|
|
|
|
QClipboard *clipboard = QApplication::clipboard();
|
|
|
|
clipboard->setText(md5);
|
2017-10-09 18:08:35 +00:00
|
|
|
// FIXME
|
|
|
|
// this->main->addOutput("MD5 copied to clipboard: " + md5);
|
2017-03-29 10:18:37 +00:00
|
|
|
}
|
|
|
|
|
2017-10-12 19:55:15 +00:00
|
|
|
void HexdumpWidget::on_copySHA1_clicked()
|
2017-03-29 10:18:37 +00:00
|
|
|
{
|
|
|
|
QString sha1 = ui->bytesSHA1->text();
|
|
|
|
QClipboard *clipboard = QApplication::clipboard();
|
|
|
|
clipboard->setText(sha1);
|
2017-10-09 18:08:35 +00:00
|
|
|
// FIXME
|
|
|
|
// this->main->addOutput("SHA1 copied to clipboard: " + sha1);
|
2017-03-29 10:18:37 +00:00
|
|
|
}
|
|
|
|
|
2017-10-12 19:55:15 +00:00
|
|
|
void HexdumpWidget::selectHexPreview()
|
2017-04-09 19:55:06 +00:00
|
|
|
{
|
2017-03-30 09:27:43 +00:00
|
|
|
// Pre-select arch and bits in the hexdump sidebar
|
2017-11-15 21:42:39 +00:00
|
|
|
QString arch = Core()->cmd("e asm.arch").trimmed();
|
|
|
|
QString bits = Core()->cmd("e asm.bits").trimmed();
|
2017-03-30 09:27:43 +00:00
|
|
|
|
|
|
|
//int arch_index = ui->hexArchComboBox_2->findText(arch);
|
2017-04-09 19:55:06 +00:00
|
|
|
if (ui->hexArchComboBox_2->findText(arch) != -1)
|
|
|
|
{
|
2017-03-30 09:27:43 +00:00
|
|
|
ui->hexArchComboBox_2->setCurrentIndex(ui->hexArchComboBox_2->findText(arch));
|
|
|
|
}
|
|
|
|
|
|
|
|
//int bits_index = ui->hexBitsComboBox_2->findText(bits);
|
2017-04-09 19:55:06 +00:00
|
|
|
if (ui->hexBitsComboBox_2->findText(bits) != -1)
|
|
|
|
{
|
2017-03-30 09:27:43 +00:00
|
|
|
ui->hexBitsComboBox_2->setCurrentIndex(ui->hexBitsComboBox_2->findText(bits));
|
|
|
|
}
|
|
|
|
}
|
2017-04-05 09:35:19 +00:00
|
|
|
|
2017-10-12 19:55:15 +00:00
|
|
|
void HexdumpWidget::showOffsets(bool show)
|
2017-09-27 20:23:18 +00:00
|
|
|
{
|
|
|
|
if (show)
|
|
|
|
{
|
2017-11-15 21:42:39 +00:00
|
|
|
ui->hexOffsetText->show();
|
|
|
|
Core()->setConfig("asm.offset", 1);
|
2017-09-27 20:23:18 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-11-15 21:42:39 +00:00
|
|
|
ui->hexOffsetText->hide();
|
|
|
|
Core()->setConfig("asm.offset", 0);
|
2017-09-01 13:03:35 +00:00
|
|
|
}
|
|
|
|
}
|
2017-11-08 13:17:24 +00:00
|
|
|
|
|
|
|
void HexdumpWidget::zoomIn(int range)
|
|
|
|
{
|
2017-11-15 21:42:39 +00:00
|
|
|
ui->hexOffsetText->zoomIn(range);
|
|
|
|
ui->hexASCIIText->zoomIn(range);
|
|
|
|
ui->hexHexText->zoomIn(range);
|
2017-11-08 13:17:24 +00:00
|
|
|
resizeHexdump();
|
|
|
|
}
|
|
|
|
|
|
|
|
void HexdumpWidget::zoomOut(int range)
|
|
|
|
{
|
2017-11-15 21:42:39 +00:00
|
|
|
ui->hexOffsetText->zoomOut(range);
|
|
|
|
ui->hexASCIIText->zoomOut(range);
|
|
|
|
ui->hexHexText->zoomOut(range);
|
2017-11-08 13:17:24 +00:00
|
|
|
resizeHexdump();
|
|
|
|
}
|