GUI: completely overhauled the EncodeMap
This commit is contained in:
parent
2956b01962
commit
eaceadb260
|
@ -47,7 +47,6 @@ Disassembly::Disassembly(QWidget* parent) : AbstractTableView(parent)
|
|||
backgroundColor = ConfigColor("DisassemblyBackgroundColor");
|
||||
|
||||
mXrefInfo.refcount = 0;
|
||||
mTmpCodeCount = 0;
|
||||
|
||||
// Slots
|
||||
connect(Bridge::getBridge(), SIGNAL(repaintGui()), this, SLOT(reloadData()));
|
||||
|
@ -1191,7 +1190,7 @@ dsint Disassembly::getPreviousInstructionRVA(dsint rva, duint count)
|
|||
|
||||
mMemPage->read(wBuffer.data(), wBottomByteRealRVA, wBuffer.size());
|
||||
|
||||
dsint addr = mDisasm->DisassembleBack((byte_t*)wBuffer.data(), rvaToVa(wBottomByteRealRVA), wBuffer.size(), wVirtualRVA , count, mTmpCodeCount, mTmpCodeList);
|
||||
dsint addr = mDisasm->DisassembleBack((byte_t*)wBuffer.data(), rvaToVa(wBottomByteRealRVA), wBuffer.size(), wVirtualRVA , count);
|
||||
|
||||
addr += rva - wVirtualRVA;
|
||||
|
||||
|
@ -1225,7 +1224,7 @@ dsint Disassembly::getNextInstructionRVA(dsint rva, duint count)
|
|||
|
||||
mMemPage->read(wBuffer.data(), rva, wBuffer.size());
|
||||
|
||||
wNewRVA = mDisasm->DisassembleNext((byte_t*)wBuffer.data(), rvaToVa(rva), wBuffer.size(), 0, count, mTmpCodeCount, mTmpCodeList);
|
||||
wNewRVA = mDisasm->DisassembleNext((byte_t*)wBuffer.data(), rvaToVa(rva), wBuffer.size(), 0, count);
|
||||
|
||||
wNewRVA += rva;
|
||||
|
||||
|
@ -1286,7 +1285,7 @@ Instruction_t Disassembly::DisassembleAt(dsint rva)
|
|||
|
||||
mMemPage->read(wBuffer.data(), rva, wBuffer.size());
|
||||
|
||||
return mDisasm->DisassembleAt((byte_t*)wBuffer.data(), wBuffer.size(), base, rva, mTmpCodeCount, mTmpCodeList);
|
||||
return mDisasm->DisassembleAt((byte_t*)wBuffer.data(), wBuffer.size(), base, rva);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1578,8 +1577,6 @@ void Disassembly::disassembleAt(dsint parVA, dsint parCIP, bool history, dsint n
|
|||
mMemPage->setAttributes(wBase, wSize);
|
||||
mDisasm->getEncodeMap()->setMemoryRegion(wBase);
|
||||
|
||||
bool cipChanged = rvaToVa(mCipRva) != parCIP;
|
||||
|
||||
if(mRvaDisplayEnabled && mMemPage->getBase() != mRvaDisplayPageBase)
|
||||
mRvaDisplayEnabled = false;
|
||||
|
||||
|
@ -1592,20 +1589,6 @@ void Disassembly::disassembleAt(dsint parVA, dsint parCIP, bool history, dsint n
|
|||
//set CIP rva
|
||||
mCipRva = wCipRva;
|
||||
|
||||
//add CIP and its jump location to tmp code list so they will always decoded as code
|
||||
if(cipChanged)
|
||||
{
|
||||
mTmpCodeCount = 1;
|
||||
mTmpCodeList[0] = parCIP;
|
||||
Instruction_t inst = DisassembleAt(mCipRva);
|
||||
if(inst.branchType == Instruction_t::Unconditional || inst.branchType == Instruction_t::Conditional && DbgIsJumpGoingToExecute(parCIP))
|
||||
{
|
||||
mTmpCodeCount++;
|
||||
mTmpCodeList[1] = inst.branchDestination;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(newTableOffset == -1) //nothing specified
|
||||
{
|
||||
// Update table offset depending on the location of the instruction to disassemble
|
||||
|
|
|
@ -208,8 +208,6 @@ protected:
|
|||
bool mShowMnemonicBrief;
|
||||
XREF_INFO mXrefInfo;
|
||||
CodeFoldingHelper* mCodeFoldingManager;
|
||||
duint mTmpCodeCount;
|
||||
duint mTmpCodeList[3]; //ensure correct disassemble
|
||||
};
|
||||
|
||||
#endif // DISASSEMBLY_H
|
||||
|
|
|
@ -278,7 +278,7 @@ void* Bridge::processMessage(GUIMSG type, void* param1, void* param2)
|
|||
if(!DbgMemRead(parVA, wBuffer, 16))
|
||||
return 0;
|
||||
QBeaEngine disasm(-1);
|
||||
Instruction_t instr = disasm.DisassembleAt(wBuffer, 16, 0, 0, parVA);
|
||||
Instruction_t instr = disasm.DisassembleAt(wBuffer, 16, 0, parVA);
|
||||
RichTextPainter::List richText;
|
||||
CapstoneTokenizer::TokenToRichText(instr.tokens, richText, 0);
|
||||
QString finalInstruction = "";
|
||||
|
|
|
@ -26,7 +26,7 @@ QBeaEngine::~QBeaEngine()
|
|||
*
|
||||
* @return Return the RVA (Relative to the data pointer) of the nth instruction before the instruction pointed by ip
|
||||
*/
|
||||
ulong QBeaEngine::DisassembleBack(byte_t* data, duint base, duint size, duint ip, int n, duint tmpcodecount, duint* tmpcodelist)
|
||||
ulong QBeaEngine::DisassembleBack(byte_t* data, duint base, duint size, duint ip, int n)
|
||||
{
|
||||
int i;
|
||||
uint abuf[128], addr, back, cmdsize;
|
||||
|
@ -92,7 +92,7 @@ ulong QBeaEngine::DisassembleBack(byte_t* data, duint base, duint size, duint ip
|
|||
else
|
||||
cmdsize = cp.Size();
|
||||
|
||||
cmdsize = mEncodeMap->getDataSize(base + addr, cmdsize, tmpcodecount, tmpcodelist);
|
||||
cmdsize = mEncodeMap->getDataSize(base + addr, cmdsize);
|
||||
|
||||
}
|
||||
|
||||
|
@ -122,7 +122,7 @@ ulong QBeaEngine::DisassembleBack(byte_t* data, duint base, duint size, duint ip
|
|||
*
|
||||
* @return Return the RVA (Relative to the data pointer) of the nth instruction after the instruction pointed by ip
|
||||
*/
|
||||
ulong QBeaEngine::DisassembleNext(byte_t* data, duint base, duint size, duint ip, int n, duint tmpcodecount, duint* tmpcodelist)
|
||||
ulong QBeaEngine::DisassembleNext(byte_t* data, duint base, duint size, duint ip, int n)
|
||||
{
|
||||
int i;
|
||||
uint cmdsize;
|
||||
|
@ -159,7 +159,7 @@ ulong QBeaEngine::DisassembleNext(byte_t* data, duint base, duint size, duint ip
|
|||
else
|
||||
cmdsize = cp.Size();
|
||||
|
||||
cmdsize = mEncodeMap->getDataSize(base + ip, cmdsize, tmpcodecount, tmpcodelist);
|
||||
cmdsize = mEncodeMap->getDataSize(base + ip, cmdsize);
|
||||
|
||||
}
|
||||
|
||||
|
@ -183,7 +183,7 @@ ulong QBeaEngine::DisassembleNext(byte_t* data, duint base, duint size, duint ip
|
|||
* @return Return the disassembled instruction
|
||||
*/
|
||||
|
||||
Instruction_t QBeaEngine::DisassembleAt(byte_t* data, duint size, duint origBase, duint origInstRVA, duint tmpcodecount, duint* tmpcodelist)
|
||||
Instruction_t QBeaEngine::DisassembleAt(byte_t* data, duint size, duint origBase, duint origInstRVA)
|
||||
{
|
||||
//tokenize
|
||||
CapstoneTokenizer::InstructionToken cap;
|
||||
|
@ -195,7 +195,7 @@ Instruction_t QBeaEngine::DisassembleAt(byte_t* data, duint size, duint origBase
|
|||
|
||||
ENCODETYPE type = enc_code;
|
||||
|
||||
type = mEncodeMap->getDataType(origBase + origInstRVA, cp.Success() ? len : 1, tmpcodecount, tmpcodelist);
|
||||
type = mEncodeMap->getDataType(origBase + origInstRVA);
|
||||
|
||||
if(type != enc_unknown && type != enc_code && type != enc_middle)
|
||||
return DecodeDataAt(data, size, origBase, origInstRVA, type);
|
||||
|
@ -230,22 +230,17 @@ Instruction_t QBeaEngine::DisassembleAt(byte_t* data, duint size, duint origBase
|
|||
}
|
||||
|
||||
|
||||
Instruction_t QBeaEngine::DecodeDataAt(byte_t* data, duint size, duint origBase, duint origInstRVA, ENCODETYPE type, duint tmpcodecount, duint* tmpcodelist)
|
||||
Instruction_t QBeaEngine::DecodeDataAt(byte_t* data, duint size, duint origBase, duint origInstRVA, ENCODETYPE type)
|
||||
{
|
||||
//tokenize
|
||||
CapstoneTokenizer::InstructionToken cap;
|
||||
|
||||
DataInstructionInfo info;
|
||||
|
||||
auto & infoIter = dataInstMap.find(type);
|
||||
|
||||
if(infoIter == dataInstMap.end())
|
||||
{
|
||||
infoIter = dataInstMap.find(enc_byte);
|
||||
}
|
||||
|
||||
|
||||
int len = mEncodeMap->getDataSize(origBase + origInstRVA, 1, tmpcodecount, tmpcodelist);
|
||||
int len = mEncodeMap->getDataSize(origBase + origInstRVA, 1);
|
||||
|
||||
QString mnemonic = _bLongDataInst ? infoIter.value().longName : infoIter.value().shortName;
|
||||
|
||||
|
|
|
@ -39,14 +39,17 @@ class QBeaEngine
|
|||
public:
|
||||
explicit QBeaEngine(int maxModuleSize);
|
||||
~QBeaEngine();
|
||||
ulong DisassembleBack(byte_t* data, duint base, duint size, duint ip, int n, duint tmpcodecount = 0, duint* tmpcodelist = nullptr);
|
||||
ulong DisassembleNext(byte_t* data, duint base, duint size, duint ip, int n, duint tmpcodecount = 0, duint* tmpcodelist = nullptr);
|
||||
Instruction_t DisassembleAt(byte_t* data, duint size, duint origBase, duint origInstRVA, duint tmpcodecount = 0, duint* tmpcodelist = nullptr);
|
||||
Instruction_t DecodeDataAt(byte_t* data, duint size, duint origBase, duint origInstRVA, ENCODETYPE type, duint tmpcodecount = 0, duint* tmpcodelist = nullptr);
|
||||
ulong DisassembleBack(byte_t* data, duint base, duint size, duint ip, int n);
|
||||
ulong DisassembleNext(byte_t* data, duint base, duint size, duint ip, int n);
|
||||
Instruction_t DisassembleAt(byte_t* data, duint size, duint origBase, duint origInstRVA);
|
||||
Instruction_t DecodeDataAt(byte_t* data, duint size, duint origBase, duint origInstRVA, ENCODETYPE type);
|
||||
void setCodeFoldingManager(CodeFoldingHelper* CodeFoldingManager);
|
||||
void UpdateConfig();
|
||||
EncodeMap* getEncodeMap() { return mEncodeMap; }
|
||||
|
||||
EncodeMap* getEncodeMap()
|
||||
{
|
||||
return mEncodeMap;
|
||||
}
|
||||
|
||||
private:
|
||||
struct DataInstructionInfo
|
||||
|
|
|
@ -422,7 +422,7 @@ void CPUDisassembly::setupRightClickContextMenu()
|
|||
|
||||
QMenu* encodeTypeRangeMenu = makeMenu(tr("Treat selection as"));
|
||||
|
||||
const char* strTable[] = {"Command", "Byte", "Word", "Dword", "Fword", "Qword", "Tbyte", "Oword", "",
|
||||
const char* strTable[] = {"Code", "Byte", "Word", "Dword", "Fword", "Qword", "Tbyte", "Oword", "",
|
||||
"Float", "Double", "Long Double", "",
|
||||
"ASCII", "UNICODE", "",
|
||||
"MMWord", "XMMWord", "YMMWord"
|
||||
|
|
|
@ -10,10 +10,8 @@ EncodeMap::~EncodeMap()
|
|||
DbgReleaseEncodeTypeBuffer(mBuffer);
|
||||
}
|
||||
|
||||
|
||||
void EncodeMap::setMemoryRegion(duint addr)
|
||||
{
|
||||
|
||||
mBase = DbgMemFindBaseAddr(addr, &mSize);
|
||||
if(!mBase)
|
||||
return;
|
||||
|
@ -23,33 +21,6 @@ void EncodeMap::setMemoryRegion(duint addr)
|
|||
mBuffer = (byte*)DbgGetEncodeTypeBuffer(addr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool EncodeMap::isRangeConflict(duint offset, duint size, duint codesize, duint tmpcodecount, duint* tmpcodelist)
|
||||
{
|
||||
if(codesize > size)
|
||||
return true;
|
||||
size = std::min(size, codesize);
|
||||
if(size <= 0)
|
||||
return false;
|
||||
ENCODETYPE type = (ENCODETYPE)mBuffer[offset];
|
||||
if(type == enc_middle)
|
||||
return true;
|
||||
for(int i = 0; i < tmpcodecount; i++)
|
||||
{
|
||||
if(tmpcodelist[i] > offset + mBase && tmpcodelist[i] < offset + size + mBase)
|
||||
return true;
|
||||
}
|
||||
|
||||
for(int i = 1 + offset; i < size + offset; i++)
|
||||
{
|
||||
if((ENCODETYPE)mBuffer[i] != enc_unknown && (ENCODETYPE)mBuffer[i] != enc_middle)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void EncodeMap::setDataType(duint va, ENCODETYPE type)
|
||||
{
|
||||
setDataType(va, getEncodeTypeSize(type), type);
|
||||
|
@ -77,129 +48,26 @@ void EncodeMap::delSegment(duint va)
|
|||
}
|
||||
}
|
||||
|
||||
duint EncodeMap::getEncodeTypeSize(ENCODETYPE type)
|
||||
ENCODETYPE EncodeMap::getDataType(duint addr)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case enc_byte:
|
||||
return 1;
|
||||
case enc_word:
|
||||
return 2;
|
||||
case enc_dword:
|
||||
return 4;
|
||||
case enc_fword:
|
||||
return 6;
|
||||
case enc_qword:
|
||||
return 8;
|
||||
case enc_tbyte:
|
||||
return 10;
|
||||
case enc_oword:
|
||||
return 16;
|
||||
case enc_mmword:
|
||||
return 8;
|
||||
case enc_xmmword:
|
||||
return 16;
|
||||
case enc_ymmword:
|
||||
return 32;
|
||||
case enc_real4:
|
||||
return 4;
|
||||
case enc_real8:
|
||||
return 8;
|
||||
case enc_real10:
|
||||
return 10;
|
||||
case enc_ascii:
|
||||
return 1;
|
||||
case enc_unicode:
|
||||
return 2;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
if(!mBuffer || !inRange(addr))
|
||||
return enc_unknown;
|
||||
|
||||
return ENCODETYPE(mBuffer[addr - mBase]);
|
||||
}
|
||||
|
||||
bool EncodeMap::isDataType(ENCODETYPE type)
|
||||
duint EncodeMap::getDataSize(duint addr, duint codesize)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case enc_unknown:
|
||||
case enc_code:
|
||||
case enc_middle:
|
||||
case enc_junk:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ENCODETYPE EncodeMap::getDataType(duint addr, duint codesize, duint tmpcodecount, duint* tmpcodelist)
|
||||
{
|
||||
return ENCODETYPE::enc_unknown;
|
||||
if(addr - mBase >= mSize)
|
||||
return ENCODETYPE::enc_unknown;
|
||||
for(int i = 0; i < tmpcodecount; i++)
|
||||
{
|
||||
if(addr == tmpcodelist[i])
|
||||
return enc_code;
|
||||
else if(addr < tmpcodelist[i] && addr + codesize > tmpcodelist[i] && !mBuffer)
|
||||
return enc_byte;
|
||||
}
|
||||
|
||||
if(!mBuffer)
|
||||
return ENCODETYPE::enc_unknown;
|
||||
|
||||
duint offset = addr - mBase;
|
||||
ENCODETYPE type = (ENCODETYPE)mBuffer[offset];
|
||||
bool conflict = isRangeConflict(offset, mSize - offset, codesize, tmpcodecount, tmpcodelist);
|
||||
if(conflict)
|
||||
return enc_byte;
|
||||
else
|
||||
return type;
|
||||
}
|
||||
|
||||
duint EncodeMap::getDataSize(duint addr, duint codesize, duint tmpcodecount, duint* tmpcodelist)
|
||||
{
|
||||
|
||||
if(addr - mBase >= mSize)
|
||||
return codesize;
|
||||
for(int i = 0; i < tmpcodecount; i++)
|
||||
{
|
||||
if(addr == tmpcodelist[i])
|
||||
return codesize;
|
||||
else if(addr < tmpcodelist[i] && addr + codesize > tmpcodelist[i] && !mBuffer)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(!mBuffer)
|
||||
if(!mBuffer || !inRange(addr))
|
||||
return codesize;
|
||||
|
||||
duint offset = addr - mBase;
|
||||
|
||||
ENCODETYPE type = (ENCODETYPE)mBuffer[offset];
|
||||
auto type = ENCODETYPE(mBuffer[offset]);
|
||||
|
||||
duint datasize = getEncodeTypeSize(type);
|
||||
if(type == enc_unknown || type == enc_code || type == enc_junk)
|
||||
{
|
||||
if(isRangeConflict(offset, mSize - offset, codesize, tmpcodecount, tmpcodelist) || codesize == 0)
|
||||
{
|
||||
return datasize;
|
||||
}
|
||||
else
|
||||
return codesize;
|
||||
}
|
||||
else if(type == enc_ascii || type == enc_unicode)
|
||||
{
|
||||
duint totalsize = 0;
|
||||
for(int i = offset; i < mSize; i += datasize)
|
||||
{
|
||||
if(mBuffer[i] == type)
|
||||
totalsize += datasize;
|
||||
else
|
||||
break;
|
||||
}
|
||||
return totalsize;
|
||||
}
|
||||
auto datasize = getEncodeTypeSize(type);
|
||||
if(isCode(type))
|
||||
return codesize;
|
||||
else
|
||||
return datasize;
|
||||
|
||||
return codesize;
|
||||
}
|
||||
|
|
|
@ -12,16 +12,69 @@ public:
|
|||
~EncodeMap();
|
||||
|
||||
void setMemoryRegion(duint va);
|
||||
duint getDataSize(duint va, duint codesize, duint tmpcodecount = 0, duint* tmpcodelist = nullptr);
|
||||
ENCODETYPE getDataType(duint addr, duint codesize, duint tmpcodecount = 0, duint* tmpcodelist = nullptr);
|
||||
duint getDataSize(duint va, duint codesize);
|
||||
ENCODETYPE getDataType(duint addr);
|
||||
void setDataType(duint va, ENCODETYPE type);
|
||||
void setDataType(duint va, duint size, ENCODETYPE type);
|
||||
void delRange(duint start, duint size);
|
||||
void delSegment(duint va);
|
||||
bool isRangeConflict(duint offset, duint size, duint codesize, duint tmpcodecount = 0, duint* tmpcodelist = nullptr);
|
||||
bool isDataType(ENCODETYPE type);
|
||||
duint getEncodeTypeSize(ENCODETYPE type);
|
||||
bool isCode(ENCODETYPE type) {return type == enc_unknown || type == enc_code; }
|
||||
|
||||
duint getEncodeTypeSize(ENCODETYPE type)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case enc_byte:
|
||||
return 1;
|
||||
case enc_word:
|
||||
return 2;
|
||||
case enc_dword:
|
||||
return 4;
|
||||
case enc_fword:
|
||||
return 6;
|
||||
case enc_qword:
|
||||
return 8;
|
||||
case enc_tbyte:
|
||||
return 10;
|
||||
case enc_oword:
|
||||
return 16;
|
||||
case enc_mmword:
|
||||
return 8;
|
||||
case enc_xmmword:
|
||||
return 16;
|
||||
case enc_ymmword:
|
||||
return 32;
|
||||
case enc_real4:
|
||||
return 4;
|
||||
case enc_real8:
|
||||
return 8;
|
||||
case enc_real10:
|
||||
return 10;
|
||||
case enc_ascii:
|
||||
return 1;
|
||||
case enc_unicode:
|
||||
return 2;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
bool isCode(ENCODETYPE type)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case enc_unknown:
|
||||
case enc_code:
|
||||
case enc_junk:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool inRange(duint addr)
|
||||
{
|
||||
return addr >= mBase && addr < mBase + mSize;
|
||||
}
|
||||
|
||||
protected:
|
||||
duint mBase;
|
||||
|
|
|
@ -28,6 +28,15 @@ static QString ToPtrString(duint Address)
|
|||
return QString(temp);
|
||||
}
|
||||
|
||||
static QString ToLongLongHexString(unsigned long long Value)
|
||||
{
|
||||
char temp[32];
|
||||
|
||||
sprintf_s(temp, "%llX", Value);
|
||||
|
||||
return QString(temp);
|
||||
}
|
||||
|
||||
static QString ToHexString(duint Value)
|
||||
{
|
||||
char temp[32];
|
||||
|
@ -54,7 +63,6 @@ static QString ToDecString(dsint Value)
|
|||
return QString(temp);
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
static QString ToFloatingString(void* buffer)
|
||||
{
|
||||
|
@ -68,7 +76,7 @@ template<typename T>
|
|||
static QString ToIntegralString(void* buffer)
|
||||
{
|
||||
auto value = *(T*)buffer;
|
||||
return ToHexString(value);
|
||||
return ToLongLongHexString(value);
|
||||
}
|
||||
|
||||
static QString ToFloatString(void* buffer)
|
||||
|
|
Loading…
Reference in New Issue