diff options
| -rw-r--r-- | architecture.cpp | 53 | ||||
| -rw-r--r-- | binaryninjaapi.h | 5 | ||||
| -rw-r--r-- | binaryninjacore.h | 4 | ||||
| -rw-r--r-- | python/function.py | 69 |
4 files changed, 117 insertions, 14 deletions
diff --git a/architecture.cpp b/architecture.cpp index 5ce21e99..ae665e08 100644 --- a/architecture.cpp +++ b/architecture.cpp @@ -2252,17 +2252,62 @@ void DisassemblyTextRenderer::GetInstructionAnnotations(vector<InstructionTextTo bool DisassemblyTextRenderer::GetInstructionText(uint64_t addr, size_t& len, - vector<InstructionTextToken>& tokens, uint64_t& displayAddr) + vector<DisassemblyTextLine>& lines) { - BNInstructionTextToken* outTokens = nullptr; + BNDisassemblyTextLine* result = nullptr; size_t count = 0; - if (!BNGetDisassemblyTextRendererInstructionText(m_object, addr, &len, &outTokens, &count, &displayAddr)) + if (!BNGetDisassemblyTextRendererInstructionText(m_object, addr, &len, &result, &count)) return false; - tokens = InstructionTextToken::ConvertAndFreeInstructionTextTokenList(outTokens, count); + + for (size_t i = 0; i < count; i++) + { + DisassemblyTextLine line; + line.addr = result[i].addr; + line.instrIndex = result[i].instrIndex; + line.highlight = result[i].highlight; + line.tokens = InstructionTextToken::ConvertAndFreeInstructionTextTokenList(result[i].tokens, result[i].count); + lines.push_back(line); + } + + BNFreeDisassemblyTextLines(result, count); return true; } +vector<DisassemblyTextLine> DisassemblyTextRenderer::PostProcessInstructionTextLines(uint64_t addr, + size_t len, const vector<DisassemblyTextLine>& lines) +{ + BNDisassemblyTextLine* inLines = new BNDisassemblyTextLine[lines.size()]; + for (size_t i = 0; i < lines.size(); i++) + { + inLines[i].addr = lines[i].addr; + inLines[i].instrIndex = lines[i].instrIndex; + inLines[i].highlight = lines[i].highlight; + inLines[i].tokens = InstructionTextToken::CreateInstructionTextTokenList(lines[i].tokens); + inLines[i].count = lines[i].tokens.size(); + } + + BNDisassemblyTextLine* result = nullptr; + size_t count = 0; + result = BNPostProcessDisassemblyTextRendererLines(m_object, addr, len, inLines, lines.size(), &count); + BNFreeDisassemblyTextLines(inLines, lines.size()); + + vector<DisassemblyTextLine> outLines; + for (size_t i = 0; i < count; i++) + { + DisassemblyTextLine line; + line.addr = result[i].addr; + line.instrIndex = result[i].instrIndex; + line.highlight = result[i].highlight; + line.tokens = InstructionTextToken::ConvertAndFreeInstructionTextTokenList(result[i].tokens, result[i].count); + outLines.push_back(line); + } + + BNFreeDisassemblyTextLines(result, count); + return outLines; +} + + bool DisassemblyTextRenderer::GetDisassemblyText(uint64_t addr, size_t& len, vector<DisassemblyTextLine>& lines) { BNDisassemblyTextLine* result = nullptr; diff --git a/binaryninjaapi.h b/binaryninjaapi.h index dacb5a84..6b8d5fc2 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -4520,8 +4520,9 @@ namespace BinaryNinja virtual bool HasDataFlow() const; virtual void GetInstructionAnnotations(std::vector<InstructionTextToken>& tokens, uint64_t addr); - virtual bool GetInstructionText(uint64_t addr, size_t& len, - std::vector<InstructionTextToken>& tokens, uint64_t& displayAddr); + virtual bool GetInstructionText(uint64_t addr, size_t& len, std::vector<DisassemblyTextLine>& lines); + std::vector<DisassemblyTextLine> PostProcessInstructionTextLines(uint64_t addr, + size_t len, const std::vector<DisassemblyTextLine>& lines); virtual bool GetDisassemblyText(uint64_t addr, size_t& len, std::vector<DisassemblyTextLine>& lines); void ResetDeduplicatedComments(); diff --git a/binaryninjacore.h b/binaryninjacore.h index a15ecd3a..441e36b7 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -2698,9 +2698,11 @@ extern "C" BINARYNINJACOREAPI BNInstructionTextToken* BNGetDisassemblyTextRendererInstructionAnnotations( BNDisassemblyTextRenderer* renderer, uint64_t addr, size_t* count); BINARYNINJACOREAPI bool BNGetDisassemblyTextRendererInstructionText(BNDisassemblyTextRenderer* renderer, - uint64_t addr, size_t* len, BNInstructionTextToken** result, size_t* count, uint64_t* displayAddr); + uint64_t addr, size_t* len, BNDisassemblyTextLine** result, size_t* count); BINARYNINJACOREAPI bool BNGetDisassemblyTextRendererLines(BNDisassemblyTextRenderer* renderer, uint64_t addr, size_t* len, BNDisassemblyTextLine** result, size_t* count); + BINARYNINJACOREAPI BNDisassemblyTextLine* BNPostProcessDisassemblyTextRendererLines(BNDisassemblyTextRenderer* renderer, + uint64_t addr, size_t len, BNDisassemblyTextLine* inLines, size_t inCount, size_t* outCount); BINARYNINJACOREAPI void BNResetDisassemblyTextRendererDeduplicatedComments(BNDisassemblyTextRenderer* renderer); BINARYNINJACOREAPI bool BNGetDisassemblyTextRendererSymbolTokens(BNDisassemblyTextRenderer* renderer, uint64_t addr, size_t size, size_t operand, BNInstructionTextToken** result, size_t* count); diff --git a/python/function.py b/python/function.py index 26d60b0f..94379d19 100644 --- a/python/function.py +++ b/python/function.py @@ -2718,13 +2718,22 @@ class DisassemblyTextRenderer(object): def get_instruction_text(self, addr): count = ctypes.c_ulonglong() length = ctypes.c_ulonglong() - display_addr = ctypes.c_ulonglong() - tokens = ctypes.POINTER(core.BNInstructionTextToken)() - if not core.BNGetDisassemblyTextRendererInstructionText(self.handle, addr, length, tokens, count, display_addr): - return None, 0, 0 - result = InstructionTextToken.get_instruction_lines(tokens, count.value) - core.BNFreeInstructionText(tokens, count.value) - return result, length.value, display_addr.value + lines = ctypes.POINTER(core.BNDisassemblyTextLine)() + if not core.BNGetDisassemblyTextRendererInstructionText(self.handle, addr, length, lines, count): + return None, 0 + il_function = self.il_function + result = [] + for i in range(0, count.value): + addr = lines[i].addr + if (lines[i].instrIndex != 0xffffffffffffffff) and (il_function is not None): + il_instr = il_function[lines[i].instrIndex] + else: + il_instr = None + color = highlight.HighlightColor._from_core_struct(lines[i].highlight) + tokens = InstructionTextToken.get_instruction_lines(lines[i].tokens, lines[i].count) + result.append(DisassemblyTextLine(tokens, addr, il_instr, color)) + core.BNFreeDisassemblyTextLines(lines, count.value) + return (result, length.value) def get_disassembly_text(self, addr): count = ctypes.c_ulonglong() @@ -2748,6 +2757,52 @@ class DisassemblyTextRenderer(object): core.BNFreeDisassemblyTextLines(lines, count.value) return (result, length.value) + def post_process_lines(self, addr, length, in_lines): + if isinstance(in_lines, str): + in_lines = in_lines.split('\n') + line_buf = (core.BNDisassemblyTextLine * len(in_lines))() + for i in range(0, len(in_lines)): + line = in_lines[i] + if isinstance(line, str): + line = DisassemblyTextLine([InstructionTextToken(InstructionTextTokenType.TextToken, line)]) + if not isinstance(line, DisassemblyTextLine): + line = DisassemblyTextLine(line) + if line.address is None: + if len(line.tokens) > 0: + line_buf[i].addr = line.tokens[0].address + else: + line_buf[i].addr = 0 + else: + line_buf[i].addr = line.address + if line.il_instruction is not None: + line_buf[i].instrIndex = line.il_instruction.instr_index + else: + line_buf[i].instrIndex = 0xffffffffffffffff + color = line.highlight + if not isinstance(color, HighlightStandardColor) and not isinstance(color, highlight.HighlightColor): + raise ValueError("Specified color is not one of HighlightStandardColor, highlight.HighlightColor") + if isinstance(color, HighlightStandardColor): + color = highlight.HighlightColor(color) + line_buf[i].highlight = color._get_core_struct() + line_buf[i].count = len(line.tokens) + line_buf[i].tokens = InstructionTextToken.get_instruction_lines(line.tokens) + count = ctypes.c_ulonglong() + lines = ctypes.POINTER(core.BNDisassemblyTextLine)() + lines = core.BNPostProcessDisassemblyTextRendererLines(self.handle, addr, length, line_buf, len(in_lines), count) + il_function = self.il_function + result = [] + for i in range(0, count.value): + addr = lines[i].addr + if (lines[i].instrIndex != 0xffffffffffffffff) and (il_function is not None): + il_instr = il_function[lines[i].instrIndex] + else: + il_instr = None + color = highlight.HighlightColor._from_core_struct(lines[i].highlight) + tokens = InstructionTextToken.get_instruction_lines(lines[i].tokens, lines[i].count) + result.append(DisassemblyTextLine(tokens, addr, il_instr, color)) + core.BNFreeDisassemblyTextLines(lines, count.value) + return result + def reset_deduplicated_comments(self): core.BNResetDisassemblyTextRendererDeduplicatedComments(self.handle) |
