1
0
Fork 0

GUI: refactor formatOpcodeString + fix underline of relocations

This commit is contained in:
Duncan Ogilvie 2018-07-01 19:03:56 +02:00
parent 67e095efb5
commit 607c5a94e6
5 changed files with 100 additions and 124 deletions

View File

@ -394,12 +394,13 @@ QString Disassembly::paintContent(QPainter* painter, dsint rowBase, int rowOffse
}
break;
case 1: //draw bytes (TODO: some spaces between bytes)
case 1: //draw bytes
{
const Instruction_t & instr = mInstBuffer.at(rowOffset);
//draw functions
Function_t funcType;
FUNCTYPE funcFirst = DbgGetFunctionTypeAt(cur_addr);
FUNCTYPE funcLast = DbgGetFunctionTypeAt(cur_addr + mInstBuffer.at(rowOffset).length - 1);
FUNCTYPE funcLast = DbgGetFunctionTypeAt(cur_addr + instr.length - 1);
if(funcLast == FUNC_END && funcFirst != FUNC_SINGLE)
funcFirst = funcLast;
switch(funcFirst)
@ -452,60 +453,7 @@ QString Disassembly::paintContent(QPainter* painter, dsint rowBase, int rowOffse
int jumpsize = paintJumpsGraphic(painter, x + funcsize, y - 1, wRVA, branchType != Instruction_t::None && branchType != Instruction_t::Call); //jump line
//draw bytes
RichTextPainter::List richBytes;
formatOpcodeString(mInstBuffer.at(rowOffset), richBytes);
for(int i = 0; i < richBytes.size(); i++)
{
RichTextPainter::CustomRichText_t & curByte = richBytes.at(i);
DBGRELOCATIONINFO relocInfo;
curByte.highlightColor = mDisassemblyRelocationUnderlineColor;
if(DbgFunctions()->ModRelocationAtAddr(cur_addr + i, &relocInfo))
{
bool prevInSameReloc = relocInfo.rva < cur_addr + i - DbgFunctions()->ModBaseFromAddr(cur_addr + i);
curByte.highlight = true;
curByte.highlightConnectPrev = prevInSameReloc;
}
else
{
curByte.highlight = false;
curByte.highlightConnectPrev = false;
}
DBGPATCHINFO patchInfo;
if(DbgFunctions()->PatchGetEx(cur_addr + i, &patchInfo))
{
if((unsigned char)(mInstBuffer.at(rowOffset).dump.at(i)) == patchInfo.newbyte)
{
curByte.textColor = mModifiedBytesColor;
curByte.textBackground = mModifiedBytesBackgroundColor;
}
else
{
curByte.textColor = mRestoredBytesColor;
curByte.textBackground = mRestoredBytesBackgroundColor;
}
}
else
{
curByte.textColor = mBytesColor;
curByte.textBackground = mBytesBackgroundColor;
}
}
if(mCodeFoldingManager && mCodeFoldingManager->isFolded(cur_addr))
{
RichTextPainter::CustomRichText_t curByte;
curByte.textColor = mBytesColor;
curByte.textBackground = mBytesBackgroundColor;
curByte.highlightColor = mDisassemblyRelocationUnderlineColor;
curByte.highlightWidth = 1;
curByte.flags = RichTextPainter::FlagAll;
curByte.highlight = false;
curByte.textColor = mBytesColor;
curByte.textBackground = mBytesBackgroundColor;
curByte.text = "...";
richBytes.push_back(curByte);
}
auto richBytes = getRichBytes(instr);
RichTextPainter::paintRichText(painter, x, y, getColumnWidth(col), getRowHeight(), jumpsize + funcsize, richBytes, mFontMetrics);
}
break;
@ -1781,6 +1729,73 @@ void Disassembly::prepareDataRange(dsint startRva, dsint endRva, const std::func
}
}
RichTextPainter::List Disassembly::getRichBytes(const Instruction_t & instr) const
{
RichTextPainter::List richBytes;
std::vector<std::pair<size_t, bool>> realBytes;
formatOpcodeString(instr, richBytes, realBytes);
dsint cur_addr = rvaToVa(instr.rva);
if(!richBytes.empty() && richBytes.back().text.endsWith(' '))
richBytes.back().text.chop(1); //remove trailing space if exists
for(size_t i = 0; i < richBytes.size(); i++)
{
auto byteIdx = realBytes[i].first;
auto isReal = realBytes[i].second;
RichTextPainter::CustomRichText_t & curByte = richBytes.at(i);
DBGRELOCATIONINFO relocInfo;
curByte.highlightColor = mDisassemblyRelocationUnderlineColor;
if(DbgFunctions()->ModRelocationAtAddr(cur_addr + byteIdx, &relocInfo))
{
bool prevInSameReloc = relocInfo.rva < cur_addr + byteIdx - DbgFunctions()->ModBaseFromAddr(cur_addr + byteIdx);
curByte.highlight = isReal;
curByte.highlightConnectPrev = i > 0 && prevInSameReloc;
}
else
{
curByte.highlight = false;
curByte.highlightConnectPrev = false;
}
DBGPATCHINFO patchInfo;
if(isReal && DbgFunctions()->PatchGetEx(cur_addr + byteIdx, &patchInfo))
{
if((unsigned char)(instr.dump.at(byteIdx)) == patchInfo.newbyte)
{
curByte.textColor = mModifiedBytesColor;
curByte.textBackground = mModifiedBytesBackgroundColor;
}
else
{
curByte.textColor = mRestoredBytesColor;
curByte.textBackground = mRestoredBytesBackgroundColor;
}
}
else
{
curByte.textColor = mBytesColor;
curByte.textBackground = mBytesBackgroundColor;
}
}
if(mCodeFoldingManager && mCodeFoldingManager->isFolded(cur_addr))
{
RichTextPainter::CustomRichText_t curByte;
curByte.textColor = mBytesColor;
curByte.textBackground = mBytesBackgroundColor;
curByte.highlightColor = mDisassemblyRelocationUnderlineColor;
curByte.highlightWidth = 1;
curByte.flags = RichTextPainter::FlagAll;
curByte.highlight = false;
curByte.textColor = mBytesColor;
curByte.textBackground = mBytesBackgroundColor;
curByte.text = "...";
richBytes.push_back(curByte);
}
return richBytes;
}
void Disassembly::prepareData()
{
dsint wViewableRowsCount = getViewableRowsCount();
@ -1817,7 +1832,7 @@ void Disassembly::reloadData()
/************************************************************************************
Public Methods
************************************************************************************/
duint Disassembly::rvaToVa(dsint rva)
duint Disassembly::rvaToVa(dsint rva) const
{
return mMemPage->va(rva);
}

View File

@ -76,7 +76,7 @@ public:
void reloadData();
// Public Methods
duint rvaToVa(dsint rva);
duint rvaToVa(dsint rva) const;
void disassembleClear();
const duint getBase() const;
duint getSize();
@ -99,6 +99,7 @@ public:
QString getAddrText(dsint cur_addr, char label[MAX_LABEL_SIZE], bool getLabel = true);
void prepareDataCount(const QList<dsint> & wRVAs, QList<Instruction_t>* instBuffer);
void prepareDataRange(dsint startRva, dsint endRva, const std::function<bool(int, const Instruction_t &)> & disassembled);
RichTextPainter::List getRichBytes(const Instruction_t & instr) const;
//misc
void setCodeFoldingManager(CodeFoldingHelper* CodeFoldingManager);

View File

@ -329,7 +329,7 @@ void QBeaEngine::UpdateConfig()
_tokenizer.UpdateConfig();
}
void formatOpcodeString(const Instruction_t & inst, RichTextPainter::List & list)
void formatOpcodeString(const Instruction_t & inst, RichTextPainter::List & list, std::vector<std::pair<size_t, bool>> & realBytes)
{
RichTextPainter::CustomRichText_t curByte;
size_t size = inst.dump.size();
@ -337,31 +337,31 @@ void formatOpcodeString(const Instruction_t & inst, RichTextPainter::List & list
curByte.highlightWidth = 1;
curByte.flags = RichTextPainter::FlagAll;
curByte.highlight = false;
for(int i = 0; i < size; i++)
list.reserve(size + 5);
realBytes.reserve(size + 5);
for(size_t i = 0; i < size; i++)
{
curByte.text = ToByteString(inst.dump.at(i));
list.push_back(curByte);
realBytes.push_back({i, true});
auto addCh = [&](char ch)
{
curByte.text = QString(ch);
list.push_back(curByte);
realBytes.push_back({i, false});
};
if(inst.prefixSize && i + 1 == inst.prefixSize)
addCh(':');
else if(inst.opcodeSize && i + 1 == inst.prefixSize + inst.opcodeSize)
addCh(' ');
else if(inst.group1Size && i + 1 == inst.prefixSize + inst.opcodeSize + inst.group1Size)
addCh(' ');
else if(inst.group2Size && i + 1 == inst.prefixSize + inst.opcodeSize + inst.group1Size + inst.group2Size)
addCh(' ');
else if(inst.group3Size && i + 1 == inst.prefixSize + inst.opcodeSize + inst.group1Size + inst.group2Size + inst.group3Size)
addCh(' ');
}
if(inst.prefixSize > 0)
{
list.at(inst.prefixSize - 1).text.append(':');
}
if(inst.opcodeSize + inst.prefixSize < size)
list.at(inst.opcodeSize + inst.prefixSize - 1).text.append(' ');
if(inst.group1Size > 0)
{
if(inst.opcodeSize + inst.prefixSize + inst.group1Size < size)
list.at(inst.opcodeSize + inst.prefixSize + inst.group1Size - 1).text.append(' ');
}
if(inst.group2Size > 0)
{
if(inst.opcodeSize + inst.prefixSize + inst.group1Size + inst.group2Size < size)
list.at(inst.opcodeSize + inst.prefixSize + inst.group1Size + inst.group2Size - 1).text.append(' ');
}
/*if(inst.group3Size > 0)
{
output.insert((inst.opcodeSize + inst.prefixSize + inst.group1Size + inst.group2Size) * 2 + offset, '?');
}
output += QString("|%1.%2.%3.%4").arg(inst.opcodeSize).arg(inst.group1Size).arg(inst.group2Size).arg(inst.group3Size);
*/
}

View File

@ -72,6 +72,6 @@ private:
uint8_t flaginfo[ZYDIS_CPUFLAG_MAX_VALUE + 1];
};
void formatOpcodeString(const Instruction_t & inst, RichTextPainter::List & list);
void formatOpcodeString(const Instruction_t & inst, RichTextPainter::List & list, std::vector<std::pair<size_t, bool>> & realBytes);
#endif // QBEAENGINE_H

View File

@ -1497,47 +1497,7 @@ void CPUDisassembly::pushSelectionInto(bool copyBytes, QTextStream & stream, QTe
QString bytes;
QString bytesHtml;
if(copyBytes)
{
RichTextPainter::List richText;
formatOpcodeString(inst, richText);
for(int i = 0; i < richText.size(); i++)
{
RichTextPainter::CustomRichText_t & curByte1 = richText.at(i);
DBGRELOCATIONINFO relocInfo;
curByte1.highlightColor = mDisassemblyRelocationUnderlineColor;
if(DbgFunctions()->ModRelocationAtAddr(cur_addr + i, &relocInfo))
{
bool prevInSameReloc = relocInfo.rva < cur_addr + i - DbgFunctions()->ModBaseFromAddr(cur_addr + i);
curByte1.highlight = true;
curByte1.highlightConnectPrev = prevInSameReloc;
}
else
{
curByte1.highlight = false;
}
DBGPATCHINFO patchInfo;
if(DbgFunctions()->PatchGetEx(cur_addr + i, &patchInfo))
{
if(inst.dump.at(i) == patchInfo.newbyte)
{
curByte1.textColor = mModifiedBytesColor;
curByte1.textBackground = mModifiedBytesBackgroundColor;
}
else
{
curByte1.textColor = mRestoredBytesColor;
curByte1.textBackground = mRestoredBytesBackgroundColor;
}
}
else
{
curByte1.textColor = mBytesColor;
curByte1.textBackground = mBytesBackgroundColor;
}
}
RichTextPainter::htmlRichText(richText, bytesHtml, bytes);
}
RichTextPainter::htmlRichText(getRichBytes(inst), bytesHtml, bytes);
QString disassembly;
QString htmlDisassembly;
if(htmlStream)