1
0
Fork 0

Using QBeaEngine to pass vector element type info

This commit is contained in:
torusrxxx 2020-05-25 00:19:16 +08:00 committed by Duncan Ogilvie
parent b058db685c
commit 6348cb5728
7 changed files with 91 additions and 46 deletions

View File

@ -421,7 +421,9 @@ typedef enum
size_byte = 1,
size_word = 2,
size_dword = 4,
size_qword = 8
size_qword = 8,
size_xmmword = 16,
size_ymmword = 32
} MEMORY_SIZE;
typedef enum

View File

@ -223,6 +223,8 @@ Instruction_t QBeaEngine::DisassembleAt(byte_t* data, duint size, duint origBase
wInst.branchType = branchType;
wInst.tokens = cap;
cp.BytesGroup(&wInst.prefixSize, &wInst.opcodeSize, &wInst.group1Size, &wInst.group2Size, &wInst.group3Size);
for(uint8_t i = 0; i < _countof(wInst.vectorElementType); ++i)
wInst.vectorElementType[i] = cp.getVectorElementType(i);
if(!success)
return wInst;
@ -299,6 +301,10 @@ Instruction_t QBeaEngine::DecodeDataAt(byte_t* data, duint size, duint origBase,
wInst.group1Size = 0;
wInst.group2Size = 0;
wInst.group3Size = 0;
wInst.vectorElementType[0] = Zydis::VETDefault;
wInst.vectorElementType[1] = Zydis::VETDefault;
wInst.vectorElementType[2] = Zydis::VETDefault;
wInst.vectorElementType[3] = Zydis::VETDefault;
return wInst;
}

View File

@ -35,6 +35,7 @@ struct Instruction_t
BranchType branchType;
ZydisTokenizer::InstructionToken tokens;
std::vector<std::pair<const char*, uint8_t>> regsReferenced;
uint8_t vectorElementType[4];
};
class QBeaEngine

View File

@ -3,7 +3,7 @@
#include "WordEditDialog.h"
#include "XrefBrowseDialog.h"
#include "Bridge.h"
#include "zydis_wrapper.h"
#include "QBeaEngine.h"
CPUInfoBox::CPUInfoBox(StdTable* parent) : StdTable(parent)
{
@ -32,9 +32,17 @@ CPUInfoBox::CPUInfoBox(StdTable* parent) : StdTable(parent)
// Deselect any row (visual reasons only)
setSingleSelection(-1);
int maxModuleSize = (int)ConfigUint("Disassembler", "MaxModuleSize");
mDisasm = new QBeaEngine(maxModuleSize);
setupContextMenu();
}
CPUInfoBox::~CPUInfoBox()
{
delete mDisasm;
}
void CPUInfoBox::setupContextMenu()
{
mCopyAddressAction = makeAction(tr("Address"), SLOT(copyAddress()));
@ -84,6 +92,55 @@ void CPUInfoBox::clear()
setInfoLine(3, "");
}
static QString formatSSEOperand(QVector<unsigned char> data, uint8_t vectorType)
{
QString hex;
bool isXMMdecoded = false;
switch(vectorType)
{
case Zydis::VETFloat32:
if(data.size() == 16)
{
hex = "%1 %2 %3 %4";
hex = hex.arg(((const float*)data.data())[0]).arg(((const float*)data.data())[1]).arg(((const float*)data.data())[2]).arg(((const float*)data.data())[3]);
isXMMdecoded = true;
}
else if(data.size() == 4)
{
hex = QString::number(((const float*)data.data())[0]);
isXMMdecoded = true;
}
break;
case Zydis::VETFloat64:
if(data.size() == 16)
{
hex = "%1 %2";
hex = hex.arg(((const double*)data.data())[0]).arg(((const double*)data.data())[1]);
isXMMdecoded = true;
}
else if(data.size() == 8)
{
hex = QString::number(((const double*)data.data())[0]);
isXMMdecoded = true;
}
break;
default:
isXMMdecoded = false;
break;
}
if(!isXMMdecoded)
{
hex.reserve(data.size() * 3);
for(int k = 0; k < data.size(); k++)
{
if(k)
hex.append(' ');
hex.append(ToByteString(data[k]));
}
}
return hex;
}
void CPUInfoBox::disasmSelectionChanged(dsint parVA)
{
curAddr = parVA;
@ -99,15 +156,18 @@ void CPUInfoBox::disasmSelectionChanged(dsint parVA)
setCellContent(1, 0, "");
setCellContent(2, 0, "");
DISASM_INSTR instr;
memset(&instr, 0, sizeof(instr));
Instruction_t wInst;
unsigned char instructiondata[MAX_DISASM_BUFFER];
DbgMemRead(parVA, &instructiondata, MAX_DISASM_BUFFER);
wInst = mDisasm->DisassembleAt(instructiondata, MAX_DISASM_BUFFER, 0, parVA);
DISASM_INSTR instr; //Fix me: these disasm methods are so messy
DbgDisasmAt(parVA, &instr);
BASIC_INSTRUCTION_INFO basicinfo;
memset(&basicinfo, 0, sizeof(basicinfo));
DbgDisasmFastAt(parVA, &basicinfo);
int start = 0;
if(basicinfo.branch && !basicinfo.call && (!ConfigBool("Disassembler", "OnlyCipAutoComments") || parVA == DbgValFromString("cip"))) //jump
duint cip = DbgValFromString("cip");
if(wInst.branchType == Instruction_t::Conditional && (!ConfigBool("Disassembler", "OnlyCipAutoComments") || parVA == cip)) //jump
{
bool taken = DbgIsJumpGoingToExecute(parVA);
if(taken)
@ -154,6 +214,14 @@ void CPUInfoBox::disasmSelectionChanged(dsint parVA)
sizeName = "qword ptr ";
break;
#endif //_WIN64
case size_xmmword:
knownsize = false;
sizeName = "xmmword ptr ";
break;
case size_ymmword:
knownsize = false;
sizeName = "ymmword ptr ";
break;
default:
knownsize = false;
break;
@ -187,7 +255,7 @@ void CPUInfoBox::disasmSelectionChanged(dsint parVA)
{
setInfoLine(j, sizeName + "[" + argMnemonic + "]=???");
}
else if(knownsize)
else if(knownsize && wInst.vectorElementType[i] == Zydis::VETDefault) // MOVSD/MOVSS instruction
{
QString addrText = getSymbolicNameStr(arg.memvalue);
setInfoLine(j, sizeName + "[" + argMnemonic + "]=" + addrText);
@ -200,44 +268,7 @@ void CPUInfoBox::disasmSelectionChanged(dsint parVA)
memset(data.data(), 0, data.size());
if(DbgMemRead(arg.value, data.data(), data.size()))
{
QString hex;
Zydis myinstruction;
bool isXMMdecoded = false;
unsigned char instructiondata[MAX_DISASM_BUFFER];
if(basicinfo.memory.size == 16 && DbgMemRead(parVA, &instructiondata, MAX_DISASM_BUFFER))
{
myinstruction.Disassemble(parVA, instructiondata);
if(myinstruction.Success())
{
switch(myinstruction.getVectorElementType(i))
{
case Zydis::VETFloat32:
hex = "%1 %2 %3 %4";
hex = hex.arg(((const float*)data.data())[0]).arg(((const float*)data.data())[1]).arg(((const float*)data.data())[2]).arg(((const float*)data.data())[3]);
isXMMdecoded = true;
break;
case Zydis::VETFloat64:
hex = "%1 %2";
hex = hex.arg(((const double*)data.data())[0]).arg(((const double*)data.data())[1]);
isXMMdecoded = true;
break;
default:
isXMMdecoded = false;
}
}
}
if(!isXMMdecoded)
{
hex.reserve(data.size() * 3);
for(int k = 0; k < data.size(); k++)
{
if(k)
hex.append(' ');
hex.append(ToByteString(data[k]));
}
}
setInfoLine(j, sizeName + "[" + argMnemonic + "]=" + hex);
setInfoLine(j, sizeName + "[" + argMnemonic + "]=" + formatSSEOperand(data, wInst.vectorElementType[i]));
}
else
{

View File

@ -5,12 +5,14 @@
class WordEditDialog;
class XrefBrowseDialog;
class QBeaEngine;
class CPUInfoBox : public StdTable
{
Q_OBJECT
public:
explicit CPUInfoBox(StdTable* parent = 0);
~CPUInfoBox();
int getHeight();
void addFollowMenuItem(QMenu* menu, QString name, duint value);
void setupFollowMenu(QMenu* menu, duint wVA);
@ -43,6 +45,7 @@ private:
void setupContextMenu();
void setupShortcuts();
XrefBrowseDialog* mXrefDlg = nullptr;
QBeaEngine* mDisasm;
QAction* mCopyAddressAction;
QAction* mCopyRvaAction;

View File

@ -695,6 +695,8 @@ Zydis::VectorElementType Zydis::getVectorElementType(int opindex) const
{
if(!Success())
return Zydis::VETDefault;
if(opindex >= mInstr.operandCount)
return Zydis::VETDefault;
const auto & op = mInstr.operands[opindex];
switch(op.elementType)
{

View File

@ -91,7 +91,7 @@ public:
bool IsBranchType(std::underlying_type_t<BranchType> bt) const;
enum VectorElementType
enum VectorElementType : uint8_t
{
VETDefault,
VETFloat32,