diff options
| author | Rusty Wagner <rusty.wagner@gmail.com> | 2025-10-27 17:38:54 -0400 |
|---|---|---|
| committer | Rusty Wagner <rusty.wagner@gmail.com> | 2025-10-27 19:58:27 -0400 |
| commit | 8d91951e428ed7e1878a2e3a362552f0da79d6df (patch) | |
| tree | fb4839ef692b692ff2f239b75b68d822c932006c /python | |
| parent | 24ec8c9044f62b9a4de4a1dec8f9abc8cd159862 (diff) | |
Add documentation to the constant renderer and string recognizer APIs
Diffstat (limited to 'python')
| -rw-r--r-- | python/binaryview.py | 9 | ||||
| -rw-r--r-- | python/constantrenderer.py | 48 | ||||
| -rw-r--r-- | python/stringrecognizer.py | 77 |
3 files changed, 134 insertions, 0 deletions
diff --git a/python/binaryview.py b/python/binaryview.py index a3ef2b57..5c10eaf5 100644 --- a/python/binaryview.py +++ b/python/binaryview.py @@ -528,6 +528,8 @@ class StringReference: class StringRef: + """Deduplicated reference to a string owned by the Binary Ninja core. Use `str` or `bytes` to convert + this to a standard Python string or sequence of bytes.""" def __init__(self, handle): self.handle = core.handle_of_type(handle, core.BNStringRef) @@ -589,6 +591,7 @@ class StringRef: @dataclass(frozen=True) class DerivedStringLocation: + """Location associated with a derived string. Locations are optional.""" location_type: 'DerivedStringLocationType' address: int length: int @@ -596,6 +599,12 @@ class DerivedStringLocation: @dataclass(frozen=True) class DerivedString: + """ + Contains a string derived from code or data. The string does not need to be directly present in + the binary in its raw form. Derived strings can have optional locations to data or code. When + creating new derived strings, a custom type should be registered with + :py:func:`~binaryninja.stringrecognizer.CustomStringType.register` on :py:class:`~binaryninja.stringrecognizer.CustomStringType`. + """ value: 'StringRef' location: Optional[DerivedStringLocation] custom_type: Optional[stringrecognizer.CustomStringType] diff --git a/python/constantrenderer.py b/python/constantrenderer.py index abd98be7..7f4c251c 100644 --- a/python/constantrenderer.py +++ b/python/constantrenderer.py @@ -53,6 +53,14 @@ class _ConstantRendererMetaClass(type): class ConstantRenderer(metaclass=_ConstantRendererMetaClass): + """ + ``class ConstantRenderer`` allows custom rendering of constants in high level representations. + + The :py:func:`render_constant` method will be called when rendering constants that aren't pointers, while the + :py:func:`render_constant_pointer` method will be called when rendering constant pointers. The + :py:func:`is_valid_for_type` method can be optionally overridden to call the rendering methods only when + the expression type matches a custom filter. + """ _registered_renderers = [] renderer_name = None @@ -61,6 +69,7 @@ class ConstantRenderer(metaclass=_ConstantRendererMetaClass): self.handle = core.handle_of_type(handle, core.BNConstantRenderer) def register(self): + """Registers the constant renderer.""" if self.__class__.renderer_name is None: raise ValueError("Renderer name is missing") self._cb = core.BNCustomConstantRenderer() @@ -117,6 +126,15 @@ class ConstantRenderer(metaclass=_ConstantRendererMetaClass): return self.__class__.renderer_name def is_valid_for_type(self, func: 'highlevelil.HighLevelILFunction', type: 'types.Type') -> bool: + """ + Determines if the rendering methods should be called for the given expression type. It is optional + to override this method. If the method isn't overridden, all expression types are passed to the + rendering methods. + + :param func: `HighLevelILFunction` representing the high level function to be rendered + :param type: Type of the expression + :return: `True` if the constant should be passed to the rendering methods, `False` otherwise + """ return True def render_constant( @@ -124,6 +142,21 @@ class ConstantRenderer(metaclass=_ConstantRendererMetaClass): tokens: 'languagerepresentation.HighLevelILTokenEmitter', settings: Optional['function.DisassemblySettings'], precedence: 'enums.OperatorPrecedence' ) -> bool: + """ + Can be overridden to render a constant that is not a pointer. The expression type and value of the + expression are given. If the expression is not handled by this constant renderer, this method should + return `False`. + + To render a constant, emit the tokens to the `tokens` object and return `True`. + + :param instr: High level expression + :param type: Type of the expression + :param val: Value of the expression + :param tokens: Token emitter for adding the rendered tokens + :param settings: Settings for rendering + :param precedence: Operator precedence of the expression + :return: `True` if the constant was rendered, `False` otherwise + """ return False def render_constant_pointer( @@ -132,6 +165,21 @@ class ConstantRenderer(metaclass=_ConstantRendererMetaClass): settings: Optional['function.DisassemblySettings'], symbol_display: 'enums.SymbolDisplayType', precedence: 'enums.OperatorPrecedence' ) -> bool: + """ + Can be overridden to render a constant pointer. The expression type and value of the expression are given. + If the expression is not handled by this constant renderer, this method should return `False`. + + To render a constant pointer, emit the tokens to the `tokens` object and return `True`. + + :param instr: High level expression + :param type: Type of the expression + :param val: Value of the expression + :param tokens: Token emitter for adding the rendered tokens + :param settings: Settings for rendering + :param symbol_display: Type of symbol to display + :param precedence: Operator precedence of the expression + :return: `True` if the constant was rendered, `False` otherwise + """ return False diff --git a/python/stringrecognizer.py b/python/stringrecognizer.py index 8f503d8b..004a58c4 100644 --- a/python/stringrecognizer.py +++ b/python/stringrecognizer.py @@ -51,6 +51,10 @@ class _CustomStringTypeMetaClass(type): class CustomStringType(metaclass=_CustomStringTypeMetaClass): + """ + Represents a custom string type. String types contain the name of the string type and the prefix + and postfix used to render them in code. + """ def __init__(self, handle): self.handle = core.handle_of_type(handle, core.BNCustomStringType) @@ -75,6 +79,10 @@ class CustomStringType(metaclass=_CustomStringTypeMetaClass): @staticmethod def register(name: str, string_prefix="", string_postfix="") -> 'CustomStringType': + """ + Registers a new custom string type. This can be used when creating new + :py:class:`~binaryninja.binaryview.DerivedString` objects. + """ info = core.BNCustomStringTypeInfo() info.name = name info.stringPrefix = string_prefix @@ -84,14 +92,17 @@ class CustomStringType(metaclass=_CustomStringTypeMetaClass): @property def name(self) -> str: + """Name of the custom string type.""" return core.BNGetCustomStringTypeName(self.handle) @property def string_prefix(self) -> str: + """Prefix added before the opening quote in a custom string.""" return core.BNGetCustomStringTypePrefix(self.handle) @property def string_postfix(self) -> str: + """Postfix added after the closing quote in a custom string.""" return core.BNGetCustomStringTypePostfix(self.handle) @@ -116,6 +127,16 @@ class _StringRecognizerMetaClass(type): class StringRecognizer(metaclass=_StringRecognizerMetaClass): + """ + ``class StringRecognizer`` recognizes custom strings found in high level expressions. + + The :py:func:`recognize_constant`, :py:func:`recognize_constant_pointer`, + :py:func:`recognize_extern_pointer`, and :py:func:`recognize_import` methods will be called for + the respective expression types. These methods can return a :py:class:`~binaryninja.binaryview.DerivedString` + containing the string information if a custom string is found for the expression. The + :py:func:`is_valid_for_type` method can be optionally overridden to call the recognizer methods + only when the expression type matches a custom filter. + """ _registered_recognizers = [] recognizer_name = None @@ -124,6 +145,7 @@ class StringRecognizer(metaclass=_StringRecognizerMetaClass): self.handle = core.handle_of_type(handle, core.BNStringRecognizer) def register(self): + """Registers the string recognizer.""" if self.__class__.recognizer_name is None: raise ValueError("Recognizer name is missing") self._cb = core.BNCustomStringRecognizer() @@ -214,26 +236,81 @@ class StringRecognizer(metaclass=_StringRecognizerMetaClass): return self.__class__.recognizer_name def is_valid_for_type(self, func: 'highlevelil.HighLevelILFunction', type: 'types.Type') -> bool: + """ + Determines if the string recognizer should be called for the given expression type. It is optional + to override this method. If the method isn't overridden, all expression types are passed to the + string recognizer. + + :param func: `HighLevelILFunction` representing the high level function to be queried + :param type: Type of the expression + :return: `True` if the expression should be passed to the string recognizer, `False` otherwise + """ return True def recognize_constant( self, instr: 'highlevelil.HighLevelILInstruction', type: 'types.Type', val: int ) -> Optional['binaryview.DerivedString']: + """ + Can be overridden to recognize strings for a constant that is not a pointer. The expression type and + value of the expression are given. If no string is found for this expression, this method should + return `None`. + + If a string is found, return a :py:class:`~binaryninja.binaryview.DerivedString` with the string information. + + :param instr: High level expression + :param type: Type of the expression + :param val: Value of the expression + :return: Optional :py:class:`~binaryninja.binaryview.DerivedString` for any string that is found. + """ return None def recognize_constant_pointer( self, instr: 'highlevelil.HighLevelILInstruction', type: 'types.Type', val: int ) -> Optional['binaryview.DerivedString']: + """ + Can be overridden to recognize strings for a constant pointer. The expression type and value of the + expression are given. If no string is found for this expression, this method should return `None`. + + If a string is found, return a :py:class:`~binaryninja.binaryview.DerivedString` with the string information. + + :param instr: High level expression + :param type: Type of the expression + :param val: Value of the expression + :return: Optional :py:class:`~binaryninja.binaryview.DerivedString` for any string that is found. + """ return None def recognize_extern_pointer( self, instr: 'highlevelil.HighLevelILInstruction', type: 'types.Type', val: int, offset: int ) -> Optional['binaryview.DerivedString']: + """ + Can be overridden to recognize strings for an external symbol. The expression type and value of the + expression are given. If no string is found for this expression, this method should return `None`. + + If a string is found, return a :py:class:`~binaryninja.binaryview.DerivedString` with the string information. + + :param instr: High level expression + :param type: Type of the expression + :param val: Value of the expression + :param offset: Offset into the external symbol + :return: Optional :py:class:`~binaryninja.binaryview.DerivedString` for any string that is found. + """ return None def recognize_import( self, instr: 'highlevelil.HighLevelILInstruction', type: 'types.Type', val: int ) -> Optional['binaryview.DerivedString']: + """ + Can be overridden to recognize strings for an imported symbol. The expression type and value of the + expression are given. If no string is found for this expression, this method should return `None`. + + If a string is found, return a :py:class:`~binaryninja.binaryview.DerivedString` with the string information. + + :param instr: High level expression + :param type: Type of the expression + :param val: Value of the expression + :return: Optional :py:class:`~binaryninja.binaryview.DerivedString` for any string that is found. + """ return None |
