1
0
Fork 0

GUI: completely overhauled the EncodeMap

This commit is contained in:
mrexodia 2016-06-24 02:47:05 +02:00
parent 2956b01962
commit eaceadb260
No known key found for this signature in database
GPG Key ID: D72F9A4FAA0073B4
9 changed files with 101 additions and 193 deletions

View File

@ -47,7 +47,6 @@ Disassembly::Disassembly(QWidget* parent) : AbstractTableView(parent)
backgroundColor = ConfigColor("DisassemblyBackgroundColor"); backgroundColor = ConfigColor("DisassemblyBackgroundColor");
mXrefInfo.refcount = 0; mXrefInfo.refcount = 0;
mTmpCodeCount = 0;
// Slots // Slots
connect(Bridge::getBridge(), SIGNAL(repaintGui()), this, SLOT(reloadData())); 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()); 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; addr += rva - wVirtualRVA;
@ -1225,7 +1224,7 @@ dsint Disassembly::getNextInstructionRVA(dsint rva, duint count)
mMemPage->read(wBuffer.data(), rva, wBuffer.size()); 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; wNewRVA += rva;
@ -1286,7 +1285,7 @@ Instruction_t Disassembly::DisassembleAt(dsint rva)
mMemPage->read(wBuffer.data(), rva, wBuffer.size()); 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); mMemPage->setAttributes(wBase, wSize);
mDisasm->getEncodeMap()->setMemoryRegion(wBase); mDisasm->getEncodeMap()->setMemoryRegion(wBase);
bool cipChanged = rvaToVa(mCipRva) != parCIP;
if(mRvaDisplayEnabled && mMemPage->getBase() != mRvaDisplayPageBase) if(mRvaDisplayEnabled && mMemPage->getBase() != mRvaDisplayPageBase)
mRvaDisplayEnabled = false; mRvaDisplayEnabled = false;
@ -1592,20 +1589,6 @@ void Disassembly::disassembleAt(dsint parVA, dsint parCIP, bool history, dsint n
//set CIP rva //set CIP rva
mCipRva = wCipRva; 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 if(newTableOffset == -1) //nothing specified
{ {
// Update table offset depending on the location of the instruction to disassemble // Update table offset depending on the location of the instruction to disassemble

View File

@ -208,8 +208,6 @@ protected:
bool mShowMnemonicBrief; bool mShowMnemonicBrief;
XREF_INFO mXrefInfo; XREF_INFO mXrefInfo;
CodeFoldingHelper* mCodeFoldingManager; CodeFoldingHelper* mCodeFoldingManager;
duint mTmpCodeCount;
duint mTmpCodeList[3]; //ensure correct disassemble
}; };
#endif // DISASSEMBLY_H #endif // DISASSEMBLY_H

View File

@ -278,7 +278,7 @@ void* Bridge::processMessage(GUIMSG type, void* param1, void* param2)
if(!DbgMemRead(parVA, wBuffer, 16)) if(!DbgMemRead(parVA, wBuffer, 16))
return 0; return 0;
QBeaEngine disasm(-1); 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; RichTextPainter::List richText;
CapstoneTokenizer::TokenToRichText(instr.tokens, richText, 0); CapstoneTokenizer::TokenToRichText(instr.tokens, richText, 0);
QString finalInstruction = ""; QString finalInstruction = "";

View File

@ -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 * @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; int i;
uint abuf[128], addr, back, cmdsize; uint abuf[128], addr, back, cmdsize;
@ -92,7 +92,7 @@ ulong QBeaEngine::DisassembleBack(byte_t* data, duint base, duint size, duint ip
else else
cmdsize = cp.Size(); 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 * @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; int i;
uint cmdsize; uint cmdsize;
@ -159,7 +159,7 @@ ulong QBeaEngine::DisassembleNext(byte_t* data, duint base, duint size, duint ip
else else
cmdsize = cp.Size(); 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 * @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 //tokenize
CapstoneTokenizer::InstructionToken cap; CapstoneTokenizer::InstructionToken cap;
@ -195,7 +195,7 @@ Instruction_t QBeaEngine::DisassembleAt(byte_t* data, duint size, duint origBase
ENCODETYPE type = enc_code; 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) if(type != enc_unknown && type != enc_code && type != enc_middle)
return DecodeDataAt(data, size, origBase, origInstRVA, type); 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 //tokenize
CapstoneTokenizer::InstructionToken cap; CapstoneTokenizer::InstructionToken cap;
DataInstructionInfo info;
auto & infoIter = dataInstMap.find(type); auto & infoIter = dataInstMap.find(type);
if(infoIter == dataInstMap.end()) if(infoIter == dataInstMap.end())
{
infoIter = dataInstMap.find(enc_byte); 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; QString mnemonic = _bLongDataInst ? infoIter.value().longName : infoIter.value().shortName;

View File

@ -39,14 +39,17 @@ class QBeaEngine
public: public:
explicit QBeaEngine(int maxModuleSize); explicit QBeaEngine(int maxModuleSize);
~QBeaEngine(); ~QBeaEngine();
ulong DisassembleBack(byte_t* data, duint base, duint size, duint ip, int n, 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, duint tmpcodecount = 0, duint* tmpcodelist = nullptr); 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, duint tmpcodecount = 0, duint* tmpcodelist = nullptr); 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, duint tmpcodecount = 0, duint* tmpcodelist = nullptr); Instruction_t DecodeDataAt(byte_t* data, duint size, duint origBase, duint origInstRVA, ENCODETYPE type);
void setCodeFoldingManager(CodeFoldingHelper* CodeFoldingManager); void setCodeFoldingManager(CodeFoldingHelper* CodeFoldingManager);
void UpdateConfig(); void UpdateConfig();
EncodeMap* getEncodeMap() { return mEncodeMap; }
EncodeMap* getEncodeMap()
{
return mEncodeMap;
}
private: private:
struct DataInstructionInfo struct DataInstructionInfo

View File

@ -422,7 +422,7 @@ void CPUDisassembly::setupRightClickContextMenu()
QMenu* encodeTypeRangeMenu = makeMenu(tr("Treat selection as")); 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", "", "Float", "Double", "Long Double", "",
"ASCII", "UNICODE", "", "ASCII", "UNICODE", "",
"MMWord", "XMMWord", "YMMWord" "MMWord", "XMMWord", "YMMWord"

View File

@ -10,10 +10,8 @@ EncodeMap::~EncodeMap()
DbgReleaseEncodeTypeBuffer(mBuffer); DbgReleaseEncodeTypeBuffer(mBuffer);
} }
void EncodeMap::setMemoryRegion(duint addr) void EncodeMap::setMemoryRegion(duint addr)
{ {
mBase = DbgMemFindBaseAddr(addr, &mSize); mBase = DbgMemFindBaseAddr(addr, &mSize);
if(!mBase) if(!mBase)
return; return;
@ -23,33 +21,6 @@ void EncodeMap::setMemoryRegion(duint addr)
mBuffer = (byte*)DbgGetEncodeTypeBuffer(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) void EncodeMap::setDataType(duint va, ENCODETYPE type)
{ {
setDataType(va, getEncodeTypeSize(type), 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) if(!mBuffer || !inRange(addr))
{ return enc_unknown;
case enc_byte:
return 1; return ENCODETYPE(mBuffer[addr - mBase]);
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 EncodeMap::isDataType(ENCODETYPE type) duint EncodeMap::getDataSize(duint addr, duint codesize)
{ {
switch(type) if(!mBuffer || !inRange(addr))
{
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)
return codesize; return codesize;
duint offset = addr - mBase; duint offset = addr - mBase;
ENCODETYPE type = (ENCODETYPE)mBuffer[offset]; auto type = ENCODETYPE(mBuffer[offset]);
duint datasize = getEncodeTypeSize(type); auto datasize = getEncodeTypeSize(type);
if(type == enc_unknown || type == enc_code || type == enc_junk) if(isCode(type))
{ return codesize;
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;
}
else else
return datasize; return datasize;
return codesize;
} }

View File

@ -12,16 +12,69 @@ public:
~EncodeMap(); ~EncodeMap();
void setMemoryRegion(duint va); void setMemoryRegion(duint va);
duint getDataSize(duint va, duint codesize, duint tmpcodecount = 0, duint* tmpcodelist = nullptr); duint getDataSize(duint va, duint codesize);
ENCODETYPE getDataType(duint addr, duint codesize, duint tmpcodecount = 0, duint* tmpcodelist = nullptr); ENCODETYPE getDataType(duint addr);
void setDataType(duint va, ENCODETYPE type); void setDataType(duint va, ENCODETYPE type);
void setDataType(duint va, duint size, ENCODETYPE type); void setDataType(duint va, duint size, ENCODETYPE type);
void delRange(duint start, duint size); void delRange(duint start, duint size);
void delSegment(duint va); 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)
duint getEncodeTypeSize(ENCODETYPE type); {
bool isCode(ENCODETYPE type) {return type == enc_unknown || type == enc_code; } 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: protected:
duint mBase; duint mBase;

View File

@ -28,6 +28,15 @@ static QString ToPtrString(duint Address)
return QString(temp); 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) static QString ToHexString(duint Value)
{ {
char temp[32]; char temp[32];
@ -54,7 +63,6 @@ static QString ToDecString(dsint Value)
return QString(temp); return QString(temp);
} }
template<typename T> template<typename T>
static QString ToFloatingString(void* buffer) static QString ToFloatingString(void* buffer)
{ {
@ -68,7 +76,7 @@ template<typename T>
static QString ToIntegralString(void* buffer) static QString ToIntegralString(void* buffer)
{ {
auto value = *(T*)buffer; auto value = *(T*)buffer;
return ToHexString(value); return ToLongLongHexString(value);
} }
static QString ToFloatString(void* buffer) static QString ToFloatString(void* buffer)