Using QBeaEngine to pass vector element type info
This commit is contained in:
parent
b058db685c
commit
6348cb5728
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -91,7 +91,7 @@ public:
|
|||
|
||||
bool IsBranchType(std::underlying_type_t<BranchType> bt) const;
|
||||
|
||||
enum VectorElementType
|
||||
enum VectorElementType : uint8_t
|
||||
{
|
||||
VETDefault,
|
||||
VETFloat32,
|
||||
|
|
Loading…
Reference in New Issue