diff options
| author | Rusty Wagner <rusty.wagner@gmail.com> | 2024-08-22 12:55:49 -0600 |
|---|---|---|
| committer | Rusty Wagner <rusty.wagner@gmail.com> | 2024-10-21 13:56:55 -0400 |
| commit | d8e3001e535fad178c621ff07418f81f25123dc4 (patch) | |
| tree | 54c03cef2f0bdfd9a3b6df4334c81becb63e4993 /python/function.py | |
| parent | 0e281a30d73c0f31ef9442fef0346779164231ad (diff) | |
Allow multiple high level representations for display, add Pseudo Rust and a Pseudo Python example plugin
Diffstat (limited to 'python/function.py')
| -rw-r--r-- | python/function.py | 77 |
1 files changed, 73 insertions, 4 deletions
diff --git a/python/function.py b/python/function.py index 5ed61603..c8acf287 100644 --- a/python/function.py +++ b/python/function.py @@ -27,8 +27,9 @@ from dataclasses import dataclass # Binary Ninja components from . import _binaryninjacore as core from .enums import ( - AnalysisSkipReason, FunctionGraphType, SymbolType, InstructionTextTokenType, HighlightStandardColor, - HighlightColorStyle, DisassemblyOption, IntegerDisplayType, FunctionAnalysisSkipOverride, FunctionUpdateType + AnalysisSkipReason, FunctionGraphType, SymbolType, InstructionTextTokenType, HighlightStandardColor, + HighlightColorStyle, DisassemblyOption, IntegerDisplayType, FunctionAnalysisSkipOverride, FunctionUpdateType, + BuiltinType ) from .exceptions import ILException @@ -45,6 +46,7 @@ from . import variable from . import flowgraph from . import callingconvention from . import workflow +from . import languagerepresentation from . import deprecation from . import __version__ @@ -76,6 +78,7 @@ ILFunctionType = Union['lowlevelil.LowLevelILFunction', 'mediumlevelil.MediumLev ILInstructionType = Union['lowlevelil.LowLevelILInstruction', 'mediumlevelil.MediumLevelILInstruction', 'highlevelil.HighLevelILInstruction'] StringOrType = Union[str, 'types.Type', 'types.TypeBuilder'] +FunctionViewTypeOrName = Union['FunctionViewType', FunctionGraphType, str] def _function_name_(): @@ -181,6 +184,39 @@ class VariableReferenceSource: return f"<var: {repr(self.var)}, src: {repr(self.src)}>" +@dataclass +class FunctionViewType: + view_type: FunctionGraphType + name: Optional[str] + + def __init__(self, view_type: FunctionViewTypeOrName): + if isinstance(view_type, FunctionViewType): + self.view_type = view_type.view_type + self.name = view_type.name + if isinstance(view_type, FunctionGraphType): + self.view_type = view_type + self.name = None + else: + self.view_type = FunctionGraphType.HighLevelLanguageRepresentationFunctionGraph + self.name = str(view_type) + + @staticmethod + def _from_core_struct(view_type: core.BNFunctionViewType) -> 'FunctionViewType': + if view_type.type == FunctionGraphType.HighLevelLanguageRepresentationFunctionGraph: + if view_type.name is None: + return FunctionViewType("Pseudo C") + else: + return FunctionViewType(view_type.name) + else: + return FunctionViewType(view_type.type) + + def _to_core_struct(self) -> core.BNFunctionViewType: + result = core.BNFunctionViewType() + result.type = self.view_type + result.name = self.name + return result + + class BasicBlockList: def __init__( self, function: Union['Function', 'lowlevelil.LowLevelILFunction', 'mediumlevelil.MediumLevelILFunction', @@ -1069,6 +1105,30 @@ class Function: return highlevelil.HighLevelILFunction(self.arch, result, self) @property + def pseudo_c(self) -> Optional['languagerepresentation.LanguageRepresentationFunction']: + return self.language_representation("Pseudo C") + + @property + def pseudo_c_if_available(self) -> Optional['languagerepresentation.LanguageRepresentationFunction']: + return self.language_representation_if_available("Pseudo C") + + def language_representation( + self, language: str + ) -> Optional['languagerepresentation.LanguageRepresentationFunction']: + result = core.BNGetFunctionLanguageRepresentation(self.handle, language) + if result is None: + return None + return languagerepresentation.LanguageRepresentationFunction(handle=result) + + def language_representation_if_available( + self, language: str + ) -> Optional['languagerepresentation.LanguageRepresentationFunction']: + result = core.BNGetFunctionLanguageRepresentationIfAvailable(self.handle, language) + if result is None: + return None + return languagerepresentation.LanguageRepresentationFunction(handle=result) + + @property def type(self) -> 'types.FunctionType': """ Function type object, can be set with either a string representing the function prototype @@ -1787,7 +1847,15 @@ class Function: core.BNFreeILInstructionList(exits) def get_constant_data(self, state: RegisterValueType, value: int, size: int = 0) -> databuffer.DataBuffer: - return databuffer.DataBuffer(handle=core.BNGetConstantData(self.handle, state, value, size)) + return databuffer.DataBuffer(handle=core.BNGetConstantData(self.handle, state, value, size, None)) + + def get_constant_data_and_builtin( + self, state: RegisterValueType, value: int, size: int = 0 + ) -> Tuple[databuffer.DataBuffer, BuiltinType]: + builtin = ctypes.c_int() + db = databuffer.DataBuffer( + handle=core.BNGetConstantData(self.handle, state, value, size, ctypes.byref(builtin))) + return db, BuiltinType(builtin.value) def get_reg_value_at( self, addr: int, reg: 'architecture.RegisterType', arch: Optional['architecture.Architecture'] = None @@ -2078,13 +2146,14 @@ class Function: return result def create_graph( - self, graph_type: FunctionGraphType = FunctionGraphType.NormalFunctionGraph, + self, graph_type: FunctionViewTypeOrName = FunctionGraphType.NormalFunctionGraph, settings: Optional['DisassemblySettings'] = None ) -> flowgraph.CoreFlowGraph: if settings is not None: settings_obj = settings.handle else: settings_obj = None + graph_type = FunctionViewType(graph_type)._to_core_struct() return flowgraph.CoreFlowGraph(core.BNCreateFunctionGraph(self.handle, graph_type, settings_obj)) def apply_imported_types(self, sym: 'types.CoreSymbol', type: Optional[StringOrType] = None) -> None: |
