summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--architecture.cpp53
-rw-r--r--binaryninjaapi.h5
-rw-r--r--binaryninjacore.h4
-rw-r--r--python/function.py69
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)