1
0
Fork 0

Implement infobox in trace browser

This commit is contained in:
torusrxxx 2020-07-12 23:14:23 +08:00 committed by Duncan Ogilvie
parent b0c2702a10
commit e046b86901
7 changed files with 268 additions and 32 deletions

View File

@ -836,11 +836,7 @@ extern "C" DLL_EXPORT duint _dbg_getbranchdestination(duint addr)
});
if(cp.OpCount() && cp[0].type == ZYDIS_OPERAND_TYPE_MEMORY)
{
#ifdef _WIN64
auto const tebseg = ZYDIS_REGISTER_GS;
#else
auto const tebseg = ZYDIS_REGISTER_FS;
#endif //_WIN64
auto const tebseg = ArchValue(ZYDIS_REGISTER_FS, ZYDIS_REGISTER_GS);
if(cp[0].mem.segment == tebseg)
opValue += duint(GetTEBLocation(hActiveThread));
if(MemRead(opValue, &opValue, sizeof(opValue)))

View File

@ -55,6 +55,11 @@ TraceBrowser::TraceBrowser(QWidget* parent) : AbstractTableView(parent)
TraceBrowser::~TraceBrowser()
{
if(mTraceFile)
{
mTraceFile->Close();
delete mTraceFile;
}
delete mDisasm;
}
@ -741,7 +746,7 @@ void TraceBrowser::mousePressEvent(QMouseEvent* event)
setSingleSelection(index);
mHistory.addVaToHistory(index);
updateViewport();
selectionChanged();
emit selectionChanged(getInitialSelection());
return;
break;
@ -873,20 +878,16 @@ void TraceBrowser::keyPressEvent(QKeyEvent* event)
mHistory.addVaToHistory(visibleindex);
updateViewport();
selectionChanged();
emit selectionChanged(getInitialSelection());
}
else
AbstractTableView::keyPressEvent(event);
}
void TraceBrowser::selectionChanged()
void TraceBrowser::onSelectionChanged(unsigned long long selection)
{
if(mAutoDisassemblyFollowSelection)
followDisassemblySlot();
REGDUMP temp;
temp = mTraceFile->Registers(getInitialSelection());
emit updateTraceRegistersView(&temp);
}
void TraceBrowser::tokenizerConfigUpdatedSlot()
@ -1103,7 +1104,7 @@ void TraceBrowser::gotoNextSlot()
setSingleSelection(index);
makeVisible(index);
updateViewport();
selectionChanged();
emit selectionChanged(getInitialSelection());
}
}
@ -1115,7 +1116,7 @@ void TraceBrowser::gotoPreviousSlot()
setSingleSelection(index);
makeVisible(index);
updateViewport();
selectionChanged();
emit selectionChanged(getInitialSelection());
}
}
@ -1527,9 +1528,6 @@ void TraceBrowser::updateSlot()
mTraceFile->purgeLastPage();
setRowCount(mTraceFile->Length());
}
REGDUMP reg;
reg = mTraceFile->Registers(getInitialSelection());
emit updateTraceRegistersView(&reg);
}
else
setRowCount(0);

View File

@ -29,6 +29,7 @@ public:
duint getSelectionEnd();
bool isFileOpened() const;
TraceFileReader* getTraceFile() { return mTraceFile; }
private:
enum TableColumnIndex
@ -48,7 +49,6 @@ private:
void pushSelectionInto(bool copyBytes, QTextStream & stream, QTextStream* htmlStream = nullptr);
void copySelectionSlot(bool copyBytes);
void copySelectionToFileSlot(bool copyBytes);
void selectionChanged();
void contextMenuEvent(QContextMenuEvent* event) override;
void mousePressEvent(QMouseEvent* event) override;
@ -117,7 +117,7 @@ private:
signals:
void displayReferencesWidget();
void updateTraceRegistersView(void* registers);
void selectionChanged(unsigned long long selection);
public slots:
void openFileSlot();
@ -127,6 +127,7 @@ public slots:
void closeDeleteSlot();
void parseFinishedSlot();
void tokenizerConfigUpdatedSlot();
void onSelectionChanged(unsigned long long selection);
void gotoSlot();
void gotoPreviousSlot();

View File

@ -1,8 +1,9 @@
#include "TraceWidget.h"
#include "ui_TraceWidget.h"
#include "TraceBrowser.h"
#include "TraceFileReader.h"
#include "TraceRegisters.h"
#include "CPUInfoBox.h"
#include "StdTable.h"
TraceWidget::TraceWidget(QWidget* parent) :
QWidget(parent),
@ -12,7 +13,7 @@ TraceWidget::TraceWidget(QWidget* parent) :
mTraceWidget = new TraceBrowser(this);
mOverview = new StdTable(this);
mInfo = new CPUInfoBox(this);
mInfo = new StdTable(this);
mGeneralRegs = new TraceRegisters(this);
//disasm
ui->mTopLeftUpperRightFrameLayout->addWidget(mTraceWidget);
@ -30,7 +31,7 @@ TraceWidget::TraceWidget(QWidget* parent) :
QPushButton* button_changeview = new QPushButton("", this);
button_changeview->setStyleSheet("Text-align:left;padding: 4px;padding-left: 10px;");
connect(button_changeview, SIGNAL(clicked()), mGeneralRegs, SLOT(onChangeFPUViewAction()));
connect(mTraceWidget, SIGNAL(updateTraceRegistersView(void*)), this, SLOT(updateTraceRegistersView(void*)));
connect(mTraceWidget, SIGNAL(selectionChanged(unsigned long long)), this, SLOT(traceSelectionChanged(unsigned long long)));
connect(Bridge::getBridge(), SIGNAL(updateTraceBrowser()), this, SLOT(updateSlot()));
mGeneralRegs->SetChangeButton(button_changeview);
@ -39,13 +40,22 @@ TraceWidget::TraceWidget(QWidget* parent) :
ui->mTopRightUpperFrameLayout->addWidget(upperScrollArea);
//info
ui->mTopLeftLowerFrameLayout->addWidget(mInfo);
int height = mInfo->getHeight();
int height = (mInfo->getRowHeight() + 1) * 4;
ui->mTopLeftLowerFrame->setMinimumHeight(height + 2);
mInfo->addColumnAt(0, "", true);
mInfo->setShowHeader(false);
mInfo->setRowCount(4);
mInfo->setCellContent(0, 0, QString());
mInfo->setCellContent(1, 0, QString());
mInfo->setCellContent(2, 0, QString());
mInfo->setCellContent(3, 0, QString());
//overview
ui->mTopRightLowerFrameLayout->addWidget(mOverview);
//set up overview
mOverview->addColumnAt(500, tr("Overview"), true);
mOverview->addColumnAt(0, "", true);
mOverview->setShowHeader(false);
mOverview->setRowCount(4);
mOverview->setCellContent(0, 0, "hello");
mOverview->setCellContent(1, 0, "world");
@ -58,9 +68,22 @@ TraceWidget::~TraceWidget()
delete ui;
}
void TraceWidget::updateTraceRegistersView(void* registers)
void TraceWidget::traceSelectionChanged(unsigned long long selection)
{
mGeneralRegs->setRegisters((REGDUMP*)registers);
REGDUMP registers;
TraceFileReader* traceFile;
traceFile = mTraceWidget->getTraceFile();
if(traceFile != nullptr && traceFile->Progress() == 100)
{
if(selection < traceFile->Length())
{
registers = traceFile->Registers(selection);
updateInfobox(selection, traceFile, registers);
}
else
memset(&registers, 0, sizeof(registers));
}
mGeneralRegs->setRegisters(&registers);
}
void TraceWidget::updateSlot()
@ -72,3 +95,198 @@ TraceBrowser* TraceWidget::getTraceBrowser()
{
return mTraceWidget;
}
void TraceWidget::updateInfobox(unsigned long long selection, TraceFileReader* traceFile, const REGDUMP & registers)
{
int infoline = 0;
Zydis zydis;
unsigned char opcode[16];
QString line;
int opsize;
traceFile->OpCode(selection, opcode, &opsize);
mInfo->setRowCount(4);
mInfo->setCellContent(0, 0, QString());
mInfo->setCellContent(1, 0, QString());
mInfo->setCellContent(2, 0, QString());
mInfo->setCellContent(3, 0, QString());
auto resolveRegValue = [registers](ZydisRegister regname)
{
switch(regname)
{
#ifdef _WIN64
case ZYDIS_REGISTER_RAX:
return registers.regcontext.cax;
case ZYDIS_REGISTER_RCX:
return registers.regcontext.ccx;
case ZYDIS_REGISTER_RDX:
return registers.regcontext.cdx;
case ZYDIS_REGISTER_RBX:
return registers.regcontext.cbx;
case ZYDIS_REGISTER_RSP:
return registers.regcontext.csp;
case ZYDIS_REGISTER_RBP:
return registers.regcontext.cbp;
case ZYDIS_REGISTER_RSI:
return registers.regcontext.csi;
case ZYDIS_REGISTER_RDI:
return registers.regcontext.cdi;
case ZYDIS_REGISTER_R8:
return registers.regcontext.r8;
case ZYDIS_REGISTER_R9:
return registers.regcontext.r9;
case ZYDIS_REGISTER_R10:
return registers.regcontext.r10;
case ZYDIS_REGISTER_R11:
return registers.regcontext.r11;
case ZYDIS_REGISTER_R12:
return registers.regcontext.r12;
case ZYDIS_REGISTER_R13:
return registers.regcontext.r13;
case ZYDIS_REGISTER_R14:
return registers.regcontext.r14;
case ZYDIS_REGISTER_R15:
return registers.regcontext.r15;
case ZYDIS_REGISTER_R8D:
return registers.regcontext.r8 & 0xFFFFFFFF;
case ZYDIS_REGISTER_R9D:
return registers.regcontext.r9 & 0xFFFFFFFF;
case ZYDIS_REGISTER_R10D:
return registers.regcontext.r10 & 0xFFFFFFFF;
case ZYDIS_REGISTER_R11D:
return registers.regcontext.r11 & 0xFFFFFFFF;
case ZYDIS_REGISTER_R12D:
return registers.regcontext.r12 & 0xFFFFFFFF;
case ZYDIS_REGISTER_R13D:
return registers.regcontext.r13 & 0xFFFFFFFF;
case ZYDIS_REGISTER_R15D:
return registers.regcontext.r15 & 0xFFFFFFFF;
case ZYDIS_REGISTER_R8W:
return registers.regcontext.r8 & 0xFFFF;
case ZYDIS_REGISTER_R9W:
return registers.regcontext.r9 & 0xFFFF;
case ZYDIS_REGISTER_R10W:
return registers.regcontext.r10 & 0xFFFF;
case ZYDIS_REGISTER_R11W:
return registers.regcontext.r11 & 0xFFFF;
case ZYDIS_REGISTER_R12W:
return registers.regcontext.r12 & 0xFFFF;
case ZYDIS_REGISTER_R13W:
return registers.regcontext.r13 & 0xFFFF;
case ZYDIS_REGISTER_R15W:
return registers.regcontext.r15 & 0xFFFF;
case ZYDIS_REGISTER_R8B:
return registers.regcontext.r8 & 0xFF;
case ZYDIS_REGISTER_R9B:
return registers.regcontext.r9 & 0xFF;
case ZYDIS_REGISTER_R10B:
return registers.regcontext.r10 & 0xFF;
case ZYDIS_REGISTER_R11B:
return registers.regcontext.r11 & 0xFF;
case ZYDIS_REGISTER_R12B:
return registers.regcontext.r12 & 0xFF;
case ZYDIS_REGISTER_R13B:
return registers.regcontext.r13 & 0xFF;
case ZYDIS_REGISTER_R15B:
return registers.regcontext.r15 & 0xFF;
#endif //_WIN64
case ZYDIS_REGISTER_EAX:
return registers.regcontext.cax & 0xFFFFFFFF;
case ZYDIS_REGISTER_ECX:
return registers.regcontext.ccx & 0xFFFFFFFF;
case ZYDIS_REGISTER_EDX:
return registers.regcontext.cdx & 0xFFFFFFFF;
case ZYDIS_REGISTER_EBX:
return registers.regcontext.cbx & 0xFFFFFFFF;
case ZYDIS_REGISTER_ESP:
return registers.regcontext.csp & 0xFFFFFFFF;
case ZYDIS_REGISTER_EBP:
return registers.regcontext.cbp & 0xFFFFFFFF;
case ZYDIS_REGISTER_ESI:
return registers.regcontext.csi & 0xFFFFFFFF;
case ZYDIS_REGISTER_EDI:
return registers.regcontext.cdi & 0xFFFFFFFF;
case ZYDIS_REGISTER_AX:
return registers.regcontext.cax & 0xFFFF;
case ZYDIS_REGISTER_CX:
return registers.regcontext.ccx & 0xFFFF;
case ZYDIS_REGISTER_DX:
return registers.regcontext.cdx & 0xFFFF;
case ZYDIS_REGISTER_BX:
return registers.regcontext.cbx & 0xFFFF;
case ZYDIS_REGISTER_SP:
return registers.regcontext.csp & 0xFFFF;
case ZYDIS_REGISTER_BP:
return registers.regcontext.cbp & 0xFFFF;
case ZYDIS_REGISTER_SI:
return registers.regcontext.csi & 0xFFFF;
case ZYDIS_REGISTER_DI:
return registers.regcontext.cdi & 0xFFFF;
case ZYDIS_REGISTER_AL:
return registers.regcontext.cax & 0xFF;
case ZYDIS_REGISTER_CL:
return registers.regcontext.ccx & 0xFF;
case ZYDIS_REGISTER_DL:
return registers.regcontext.cdx & 0xFF;
case ZYDIS_REGISTER_BL:
return registers.regcontext.cbx & 0xFF;
case ZYDIS_REGISTER_AH:
return (registers.regcontext.cax & 0xFF00) >> 8;
case ZYDIS_REGISTER_CH:
return (registers.regcontext.ccx & 0xFF00) >> 8;
case ZYDIS_REGISTER_DH:
return (registers.regcontext.cdx & 0xFF00) >> 8;
case ZYDIS_REGISTER_BH:
return (registers.regcontext.cbx & 0xFF00) >> 8;
default:
return static_cast<size_t>(0);
}
};
if(zydis.Disassemble(registers.regcontext.cip, opcode, opsize))
{
int opindex;
//Jumps
if(zydis.IsBranchType(Zydis::BTCondJmp))
{
if(zydis.IsBranchGoingToExecute(registers.regcontext.eflags, registers.regcontext.ccx))
{
line = tr("Jump is taken");
}
else
{
line = tr("Jump is not taken");
}
mInfo->setCellContent(infoline, 0, line);
infoline++;
}
//Operands
for(opindex = 0; opindex < zydis.OpCount(); opindex++)
{
line.clear();
size_t value = zydis.ResolveOpValue(opindex, resolveRegValue);
if(zydis[opindex].type == ZYDIS_OPERAND_TYPE_MEMORY)
{
const char* memsize = zydis.MemSizeName(zydis[opindex].size / 8);
if(memsize != nullptr)
{
line += memsize;
}
line += " ptr ";
line += zydis.RegName(zydis[opindex].mem.segment);
line += ":[";
line += ToPtrString(value);
line += "]";
mInfo->setCellContent(infoline, 0, line);
infoline++;
}
else if(zydis[opindex].type == ZYDIS_OPERAND_TYPE_REGISTER)
{
line += zydis.RegName(zydis[opindex].reg.value);
line += " = ";
line += ToPtrString(value);
mInfo->setCellContent(infoline, 0, line);
infoline++;
}
}
}
mInfo->reloadData();
}

View File

@ -2,12 +2,13 @@
#define TRACEWIDGET_H
#include <QWidget>
#include "Bridge.h"
class QVBoxLayout;
class CPUWidget;
class TraceRegisters;
class TraceBrowser;
class CPUInfoBox;
class TraceFileReader;
class StdTable;
namespace Ui
@ -26,15 +27,17 @@ public:
TraceBrowser* getTraceBrowser();
protected slots:
void updateTraceRegistersView(void* registers);
void traceSelectionChanged(unsigned long long selection);
void updateSlot();
protected:
TraceBrowser* mTraceWidget;
TraceRegisters* mGeneralRegs;
CPUInfoBox* mInfo;
StdTable* mInfo;
StdTable* mOverview;
void updateInfobox(unsigned long long selection, TraceFileReader* traceFile, const REGDUMP & registers);
private:
Ui::TraceWidget* ui;
};

View File

@ -67,7 +67,7 @@
<number>1</number>
</property>
<property name="childrenCollapsible">
<bool>false</bool>
<bool>true</bool>
</property>
<widget class="QFrame" name="mTopLeftUpperRightFrame">
<property name="frameShape">
@ -95,6 +95,12 @@
</layout>
</widget>
<widget class="QFrame" name="mTopLeftLowerFrame">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
@ -137,6 +143,12 @@
<bool>false</bool>
</property>
<widget class="QFrame" name="mTopRightUpperFrame">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
@ -162,6 +174,12 @@
</layout>
</widget>
<widget class="QFrame" name="mTopRightLowerFrame">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>

View File

@ -560,7 +560,7 @@ bool Zydis::IsNop() const
case ZYDIS_MNEMONIC_JRCXZ:
case ZYDIS_MNEMONIC_JS:
case ZYDIS_MNEMONIC_JZ:
// jmp 0
// jmp $0
return ops[0].type == ZYDIS_OPERAND_TYPE_IMMEDIATE
&& ops[0].imm.value.u == this->Address() + this->Size();
case ZYDIS_MNEMONIC_SHL:
@ -615,7 +615,9 @@ bool Zydis::IsUnusual() const
|| id == ZYDIS_MNEMONIC_RDRAND
|| id == ZYDIS_MNEMONIC_RDSEED
|| id == ZYDIS_MNEMONIC_UD1
|| id == ZYDIS_MNEMONIC_UD2;
|| id == ZYDIS_MNEMONIC_UD2
|| id == ZYDIS_MNEMONIC_VMCALL
|| id == ZYDIS_MNEMONIC_VMFUNC;
}
std::string Zydis::Mnemonic() const