1
0
Fork 0

GUI: make DisassemblyPopup not use the Disassembly class directly

This commit is contained in:
mrexodia 2016-10-22 15:52:15 +02:00
parent 3951719a12
commit 5fed31b1b3
No known key found for this signature in database
GPG Key ID: FC89E0AAA0C1AAD8
2 changed files with 55 additions and 29 deletions

View File

@ -1,19 +1,19 @@
#include "DisassemblyPopup.h"
#include "Disassembly.h"
#include "CachedFontMetrics.h"
#include "Configuration.h"
#include "StringUtil.h"
#include <QPainter>
DisassemblyPopup::DisassemblyPopup(Disassembly* parent) :
DisassemblyPopup::DisassemblyPopup(QWidget* parent) :
QFrame(parent, Qt::Tool | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::WindowDoesNotAcceptFocus),
parent(parent),
mFontMetrics(nullptr)
mFontMetrics(nullptr),
mDisasm(ConfigUint("Disassembler", "MaxModuleSize"))
{
addr = 0;
addrText = nullptr;
connect(Config(), SIGNAL(fontsUpdated()), this, SLOT(updateFont()));
connect(Config(), SIGNAL(colorsUpdated()), this, SLOT(updateColors()));
connect(Config(), SIGNAL(tokenizerConfigUpdated()), this, SLOT(tokenizerConfigUpdated()));
updateFont();
updateColors();
setFrameStyle(QFrame::Panel);
@ -21,11 +21,6 @@ DisassemblyPopup::DisassemblyPopup(Disassembly* parent) :
mMaxInstructions = 20;
}
DisassemblyPopup::~DisassemblyPopup()
{
}
void DisassemblyPopup::updateColors()
{
disassemblyBackgroundColor = ConfigColor("DisassemblyBackgroundColor");
@ -41,6 +36,11 @@ void DisassemblyPopup::updateColors()
setPalette(palette);
}
void DisassemblyPopup::tokenizerConfigUpdated()
{
mDisasm.UpdateConfig();
}
void DisassemblyPopup::updateFont()
{
delete mFontMetrics;
@ -86,29 +86,55 @@ void DisassemblyPopup::paintEvent(QPaintEvent* event)
QFrame::paintEvent(event);
}
QString DisassemblyPopup::getSymbolicName(duint addr)
{
char labelText[MAX_LABEL_SIZE] = "";
char moduleText[MAX_MODULE_SIZE] = "";
bool bHasLabel = DbgGetLabelAt(addr, SEG_DEFAULT, labelText);
bool bHasModule = (DbgGetModuleAt(addr, moduleText) && !QString(labelText).startsWith("JMP.&"));
QString addrText = ToPtrString(addr);
QString finalText;
if(bHasLabel && bHasModule) //<module.label>
finalText = QString("%1 <%2.%3>").arg(addrText).arg(moduleText).arg(labelText);
else if(bHasModule) //module.addr
finalText = QString("%1.%2").arg(moduleText).arg(addrText);
else if(bHasLabel) //<label>
finalText = QString("<%1>").arg(labelText);
else
finalText = addrText;
return finalText;
}
void DisassemblyPopup::setAddress(duint Address)
{
addr = Address;
QList<Instruction_t> mInstBuffer;
QList<Instruction_t> instBuffer;
mDisassemblyToken.clear();
if(addr != 0)
{
mWidth = 1;
// Get RVA
duint base = parent->getBase();
dsint rva = Address - base;
auto addr = Address;
duint size;
duint base = DbgMemFindBaseAddr(addr, &size);
// Prepare RVA of every instruction
unsigned int i = 0;
mInstBuffer.clear();
QList<dsint> rvaList;
dsint nextRva = rva;
instBuffer.clear();
auto nextAddr = addr;
bool hadBranch = false;
duint bestBranch = 0;
byte data[64];
do
{
rvaList.append(nextRva);
Instruction_t instruction = parent->DisassembleAt(nextRva);
if(!hadBranch || bestBranch <= instruction.rva + base)
if(nextAddr >= base + size)
break;
if(!DbgMemRead(nextAddr, data, sizeof(data)))
break;
auto instruction = mDisasm.DisassembleAt(data, sizeof(data), 0, nextAddr);
if(!instruction.length)
break;
instBuffer.append(std::move(instruction));
if(!hadBranch || bestBranch <= nextAddr)
{
if(instruction.instStr.contains("ret"))
break;
@ -121,19 +147,18 @@ void DisassemblyPopup::setAddress(duint Address)
if(instruction.branchDestination > bestBranch)
bestBranch = instruction.branchDestination;
}
auto nextRva2 = nextRva + instruction.length;
if(nextRva2 == nextRva)
auto nextAddr2 = nextAddr + instruction.length;
if(nextAddr2 == nextAddr)
break;
else
nextRva = nextRva2;
if(DbgGetFunctionTypeAt(nextRva + base - 1) == FUNC_END)
nextAddr = nextAddr2;
if(DbgGetFunctionTypeAt(nextAddr - 1) == FUNC_END)
break;
i++;
}
while(i < mMaxInstructions);
// Disassemble
parent->prepareDataCount(rvaList, &mInstBuffer);
for(auto & instruction : mInstBuffer)
for(auto & instruction : instBuffer)
{
RichTextPainter::List richText;
CapstoneTokenizer::TokenToRichText(instruction.tokens, richText, nullptr);
@ -145,7 +170,7 @@ void DisassemblyPopup::setAddress(duint Address)
mDisassemblyToken.push_back(std::make_pair(std::move(richText), DbgFunctions()->GetTraceRecordHitCount(instruction.rva + base) != 0));
}
// Address
addrText = parent->getAddrText(addr, nullptr);
addrText = getSymbolicName(addr);
// Comments
GetCommentFormat(addr, addrComment, &addrCommentAuto);
if(addrComment.length())

View File

@ -1,27 +1,27 @@
#ifndef DISASSEMBLYPOPUP_H
#define DISASSEMBLYPOPUP_H
#include <QFrame>
#include "Imports.h"
#include "QBeaEngine.h"
class Disassembly;
class CachedFontMetrics;
class DisassemblyPopup : public QFrame
{
Q_OBJECT
public:
explicit DisassemblyPopup(Disassembly* parent);
~DisassemblyPopup();
explicit DisassemblyPopup(QWidget* parent);
void paintEvent(QPaintEvent* event);
void setAddress(duint Address);
duint getAddress();
QString getSymbolicName(duint addr);
public slots:
void hide();
void updateFont();
void updateColors();
void tokenizerConfigUpdated();
protected:
Disassembly* parent;
CachedFontMetrics* mFontMetrics;
duint addr;
QString addrText;
@ -40,6 +40,7 @@ protected:
QColor commentBackgroundColor;
QColor commentAutoColor;
QColor commentAutoBackgroundColor;
QBeaEngine mDisasm;
std::vector<std::pair<RichTextPainter::List, bool>> mDisassemblyToken;
};