summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRusty Wagner <rusty.wagner@gmail.com>2025-10-27 17:38:54 -0400
committerRusty Wagner <rusty.wagner@gmail.com>2025-10-27 19:58:27 -0400
commit8d91951e428ed7e1878a2e3a362552f0da79d6df (patch)
treefb4839ef692b692ff2f239b75b68d822c932006c
parent24ec8c9044f62b9a4de4a1dec8f9abc8cd159862 (diff)
Add documentation to the constant renderer and string recognizer APIs
-rw-r--r--binaryninjaapi.h118
-rw-r--r--python/binaryview.py9
-rw-r--r--python/constantrenderer.py48
-rw-r--r--python/stringrecognizer.py77
4 files changed, 252 insertions, 0 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h
index 4a270cda..375fb227 100644
--- a/binaryninjaapi.h
+++ b/binaryninjaapi.h
@@ -5372,6 +5372,11 @@ namespace BinaryNinja {
std::vector<TypeReferenceSource> typeRefs;
};
+ /*! 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.
+
+ \ingroup stringrecognizer
+ */
class CustomStringType: public StaticCoreRefCountObject<BNCustomStringType>
{
public:
@@ -5384,6 +5389,10 @@ namespace BinaryNinja {
const std::string& name, const std::string& stringPrefix = "", const std::string& stringPostfix = "");
};
+ /*! Location associated with a derived string. Locations are optional.
+
+ \ingroup stringrecognizer
+ */
struct DerivedStringLocation
{
BNDerivedStringLocationType locationType;
@@ -5418,6 +5427,12 @@ namespace BinaryNinja {
}
};
+ /*! 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 \c CustomStringType::register.
+
+ \ingroup stringrecognizer
+ */
struct DerivedString
{
StringRef value;
@@ -21425,6 +21440,10 @@ namespace BinaryNinja {
) override;
};
+ /*! \c ConstantRenderer allows custom rendering of constants in high level representations.
+
+ \ingroup constantrenderer
+ */
class ConstantRenderer : public StaticCoreRefCountObject<BNConstantRenderer>
{
std::string m_nameForRegister;
@@ -21435,9 +21454,47 @@ namespace BinaryNinja {
std::string GetName() const;
+ /*! 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 \c HighLevelILFunction representing the high level function to be queried
+ \param type Type of the expression
+ \return \c true if the constant should be passed to the rendering methods, \c false otherwise
+ */
virtual bool IsValidForType(HighLevelILFunction* func, Type* type);
+
+ /*! 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 \c false
+
+ To render a constant, emit the tokens to the tokens object and return \c 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 \c true if the constant was rendered, \c false otherwise
+ */
virtual bool RenderConstant(const HighLevelILInstruction& instr, Type* type, int64_t val,
HighLevelILTokenEmitter& tokens, DisassemblySettings* settings, BNOperatorPrecedence precedence);
+
+ /*! 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 \c false
+
+ To render a constant, emit the tokens to the tokens object and return \c 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 \c true if the constant was rendered, \c false otherwise
+ */
virtual bool RenderConstantPointer(const HighLevelILInstruction& instr, Type* type, int64_t val,
HighLevelILTokenEmitter& tokens, DisassemblySettings* settings, BNSymbolDisplayType symbolDisplay,
BNOperatorPrecedence precedence);
@@ -21473,6 +21530,10 @@ namespace BinaryNinja {
BNOperatorPrecedence precedence) override;
};
+ /*! \c StringRecognizer recognizes custom strings found in high level expressions.
+
+ \ingroup stringrecognizer
+ */
class StringRecognizer : public StaticCoreRefCountObject<BNStringRecognizer>
{
std::string m_nameForRegister;
@@ -21483,13 +21544,70 @@ namespace BinaryNinja {
std::string GetName() const;
+ /*! 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 \c HighLevelILFunction representing the high level function to be queried
+ \param type Type of the expression
+ \return \c true if the expression should be passed to the string recognizer, \c false otherwise
+ */
virtual bool IsValidForType(HighLevelILFunction* func, Type* type);
+
+ /*! 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 \c std::nullopt
+
+ If a string is found, return a \c DerivedString with the string information.
+
+ \param instr High level expression
+ \param type Type of the expression
+ \param val Value of the expression
+ \return Optional \c DerivedString for any string that is found
+ */
virtual std::optional<DerivedString> RecognizeConstant(
const HighLevelILInstruction& instr, Type* type, int64_t val);
+
+ /*! 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 \c std::nullopt
+
+ If a string is found, return a \c DerivedString with the string information.
+
+ \param instr High level expression
+ \param type Type of the expression
+ \param val Value of the expression
+ \return Optional \c DerivedString for any string that is found
+ */
virtual std::optional<DerivedString> RecognizeConstantPointer(
const HighLevelILInstruction& instr, Type* type, int64_t val);
+
+ /*! 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 \c std::nullopt
+
+ If a string is found, return a \c 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 \c DerivedString for any string that is found
+ */
virtual std::optional<DerivedString> RecognizeExternPointer(
const HighLevelILInstruction& instr, Type* type, int64_t val, uint64_t offset);
+
+ /*! 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 \c std::nullopt
+
+ If a string is found, return a \c DerivedString with the string information.
+
+ \param instr High level expression
+ \param type Type of the expression
+ \param val Value of the expression
+ \return Optional \c DerivedString for any string that is found
+ */
virtual std::optional<DerivedString> RecognizeImport(
const HighLevelILInstruction& instr, Type* type, int64_t val);
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