summaryrefslogtreecommitdiff
path: root/python/highlevelil.py
diff options
context:
space:
mode:
authorRusty Wagner <rusty.wagner@gmail.com>2024-11-27 12:15:23 -0500
committerRusty Wagner <rusty.wagner@gmail.com>2025-01-24 12:52:12 -0500
commit8767400b712f12f459556844e27d9b9f5ff037bd (patch)
treebbac40ec6fb68b647e2f9bd4a0c528088072dc79 /python/highlevelil.py
parent1c81ef63a163b479d07f3182f7831fdb6548488b (diff)
Add line formatter API and a generic line formatter plugin
Diffstat (limited to 'python/highlevelil.py')
-rw-r--r--python/highlevelil.py53
1 files changed, 34 insertions, 19 deletions
diff --git a/python/highlevelil.py b/python/highlevelil.py
index 1d7feb71..85be4794 100644
--- a/python/highlevelil.py
+++ b/python/highlevelil.py
@@ -26,7 +26,10 @@ from enum import Enum
# Binary Ninja components
from . import _binaryninjacore as core
-from .enums import HighLevelILOperation, DataFlowQueryOption, FunctionGraphType, ILInstructionAttribute, StringType
+from .enums import (
+ HighLevelILOperation, DataFlowQueryOption, FunctionGraphType, ILInstructionAttribute, StringType,
+ DisassemblyOption
+)
from . import function
from . import binaryview
from . import architecture
@@ -331,7 +334,9 @@ class HighLevelILInstruction(BaseILInstruction):
return ILInstruction[instr.operation](func, expr_index, core_instr, as_ast, instr_index)
def __str__(self):
- lines = self.lines
+ settings = function.DisassemblySettings.default_settings()
+ settings.set_option(DisassemblyOption.DisableLineFormatting)
+ lines = self.get_lines(settings)
if lines is None:
return "invalid"
result = []
@@ -343,7 +348,9 @@ class HighLevelILInstruction(BaseILInstruction):
return '\n'.join(result)
def __repr__(self):
- lines = self.lines
+ settings = function.DisassemblySettings.default_settings()
+ settings.set_option(DisassemblyOption.DisableLineFormatting)
+ lines = self.get_lines(settings)
continuation = ""
if lines is None:
first_line = "<invalid>"
@@ -386,26 +393,14 @@ class HighLevelILInstruction(BaseILInstruction):
@property
def tokens(self) -> TokenList:
"""HLIL tokens taken from the HLIL text lines (read-only) -- does not include newlines or indentation, use lines for that information"""
- return [token for line in self.lines for token in line.tokens]
+ settings = function.DisassemblySettings.default_settings()
+ settings.set_option(DisassemblyOption.DisableLineFormatting)
+ return [token for line in self.get_lines(settings) for token in line.tokens]
@property
def lines(self) -> LinesType:
"""HLIL text lines (read-only)"""
- count = ctypes.c_ulonglong()
- lines = core.BNGetHighLevelILExprText(self.function.handle, self.expr_index, self.as_ast, count, None)
- assert lines is not None, "core.BNGetHighLevelILExprText returned None"
- try:
- for i in range(0, count.value):
- addr = lines[i].addr
- if lines[i].instrIndex != 0xffffffffffffffff:
- il_instr = self.function[lines[i].instrIndex]
- else:
- il_instr = None
- color = highlight.HighlightColor._from_core_struct(lines[i].highlight)
- tokens = function.InstructionTextToken._from_core_struct(lines[i].tokens, lines[i].count)
- yield function.DisassemblyTextLine(tokens, addr, il_instr, color)
- finally:
- core.BNFreeDisassemblyTextLines(lines, count.value)
+ return self.get_lines()
@property
def prefix_operands(self) -> List[Union[HighLevelILOperandType, HighLevelILOperationAndSize]]:
@@ -918,6 +913,26 @@ class HighLevelILInstruction(BaseILInstruction):
def has_side_effects(self) -> bool:
return core.BNHighLevelILHasSideEffects(self.function.handle, self.expr_index)
+ def get_lines(self, settings: Optional['function.DisassemblySettings'] = None) -> LinesType:
+ """Gets HLIL text lines with optional settings"""
+ if settings is not None:
+ settings = settings.handle
+ count = ctypes.c_ulonglong()
+ lines = core.BNGetHighLevelILExprText(self.function.handle, self.expr_index, self.as_ast, count, settings)
+ assert lines is not None, "core.BNGetHighLevelILExprText returned None"
+ try:
+ for i in range(0, count.value):
+ addr = lines[i].addr
+ if lines[i].instrIndex != 0xffffffffffffffff:
+ il_instr = self.function[lines[i].instrIndex]
+ else:
+ il_instr = None
+ color = highlight.HighlightColor._from_core_struct(lines[i].highlight)
+ tokens = function.InstructionTextToken._from_core_struct(lines[i].tokens, lines[i].count)
+ yield function.DisassemblyTextLine(tokens, addr, il_instr, color)
+ finally:
+ core.BNFreeDisassemblyTextLines(lines, count.value)
+
@dataclass(frozen=True, repr=False, eq=False)
class HighLevelILUnaryBase(HighLevelILInstruction, UnaryOperation):