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");
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

View File

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

View File

@ -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 = "";

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
*/
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;

View File

@ -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

View File

@ -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"

View File

@ -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;
}

View File

@ -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;

View File

@ -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)