diff --git a/src/gui/Src/BasicView/Disassembly.cpp b/src/gui/Src/BasicView/Disassembly.cpp index 1b795d58..026ccd55 100644 --- a/src/gui/Src/BasicView/Disassembly.cpp +++ b/src/gui/Src/BasicView/Disassembly.cpp @@ -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> 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); } diff --git a/src/gui/Src/BasicView/Disassembly.h b/src/gui/Src/BasicView/Disassembly.h index 98159bd6..935a204b 100644 --- a/src/gui/Src/BasicView/Disassembly.h +++ b/src/gui/Src/BasicView/Disassembly.h @@ -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 & wRVAs, QList* instBuffer); void prepareDataRange(dsint startRva, dsint endRva, const std::function & disassembled); + RichTextPainter::List getRichBytes(const Instruction_t & instr) const; //misc void setCodeFoldingManager(CodeFoldingHelper* CodeFoldingManager); diff --git a/src/gui/Src/Disassembler/QBeaEngine.cpp b/src/gui/Src/Disassembler/QBeaEngine.cpp index 5bd26609..898a8005 100644 --- a/src/gui/Src/Disassembler/QBeaEngine.cpp +++ b/src/gui/Src/Disassembler/QBeaEngine.cpp @@ -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> & 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); - */ } diff --git a/src/gui/Src/Disassembler/QBeaEngine.h b/src/gui/Src/Disassembler/QBeaEngine.h index 4185ee51..76a4c372 100644 --- a/src/gui/Src/Disassembler/QBeaEngine.h +++ b/src/gui/Src/Disassembler/QBeaEngine.h @@ -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> & realBytes); #endif // QBEAENGINE_H diff --git a/src/gui/Src/Gui/CPUDisassembly.cpp b/src/gui/Src/Gui/CPUDisassembly.cpp index 4453ffc4..8c933985 100644 --- a/src/gui/Src/Gui/CPUDisassembly.cpp +++ b/src/gui/Src/Gui/CPUDisassembly.cpp @@ -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)