From bfd306437f34ebc4d4170c5fb8170261585f6038 Mon Sep 17 00:00:00 2001 From: Brian Potchik Date: Fri, 17 Apr 2026 12:10:07 -0400 Subject: Add RecognizeConstantData to StringRecognizer API Adds a new recognize_constant_data method to the StringRecognizer API, enabling plugins to decode constant data expressions (HLIL_CONST_DATA) recovered by the outline resolver. The recognizer receives the full instruction, giving access to the data buffer and builtin type via the constant_data accessor. Also fixes a pre-existing ctypes mismatch in get_constant_data_and_builtin where BNBuiltinType (uint8_t) was incorrectly passed as c_int. --- python/stringrecognizer.py | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'python/stringrecognizer.py') diff --git a/python/stringrecognizer.py b/python/stringrecognizer.py index 055e236d..bdf9423a 100644 --- a/python/stringrecognizer.py +++ b/python/stringrecognizer.py @@ -195,6 +195,9 @@ class StringRecognizer(metaclass=_StringRecognizerMetaClass): self._cb.recognizeExternPointer = self._cb.recognizeExternPointer.__class__(self._recognize_extern_pointer) if self.recognize_import.__func__ != StringRecognizer.recognize_import: self._cb.recognizeImport = self._cb.recognizeImport.__class__(self._recognize_import) + if self.recognize_constant_data.__func__ != StringRecognizer.recognize_constant_data: + self._cb.recognizeConstantData = self._cb.recognizeConstantData.__class__( + self._recognize_constant_data) self.handle = core.BNRegisterStringRecognizer(self.__class__.recognizer_name, self._cb) self.__class__._registered_recognizers.append(self) @@ -263,6 +266,19 @@ class StringRecognizer(metaclass=_StringRecognizerMetaClass): log_error_for_exception("Unhandled Python exception in StringRecognizer._recognize_import") return False + def _recognize_constant_data(self, ctxt, hlil, expr, result): + try: + hlil = highlevelil.HighLevelILFunction(handle=core.BNNewHighLevelILFunctionReference(hlil)) + instr = hlil.get_expr(highlevelil.ExpressionIndex(expr)) + ref = self.recognize_constant_data(instr) + if ref is None: + return False + result[0] = ref._to_core_struct(True) + return True + except Exception: + log_error_for_exception("Unhandled Python exception in StringRecognizer._recognize_constant_data") + return False + @property def name(self) -> str: if hasattr(self, 'handle'): @@ -347,6 +363,22 @@ class StringRecognizer(metaclass=_StringRecognizerMetaClass): """ return None + def recognize_constant_data( + self, instr: 'highlevelil.HighLevelILInstruction' + ) -> Optional['binaryview.DerivedString']: + """ + Can be overridden to recognize strings for constant data expressions (HLIL_CONST_DATA). + These expressions are generated by the outline resolver when it recovers constant data + streams from scattered stores. The instruction provides access to the data buffer and + builtin type via its ``constant_data`` accessor. + + If a string is found, return a :py:class:`~binaryninja.binaryview.DerivedString` with the string information. + + :param instr: High level expression containing the constant data + :return: Optional :py:class:`~binaryninja.binaryview.DerivedString` for any string that is found. + """ + return None + _recognizer_cache = {} @@ -402,3 +434,11 @@ class CoreStringRecognizer(StringRecognizer): if not core.BNStringRecognizerRecognizeImport(self.handle, instr.function.handle, instr.expr_index, type.handle, val, string): return None return binaryview.DerivedString._from_core_struct(string, True) + + def recognize_constant_data( + self, instr: 'highlevelil.HighLevelILInstruction' + ) -> Optional['binaryview.DerivedString']: + string = core.BNDerivedString() + if not core.BNStringRecognizerRecognizeConstantData(self.handle, instr.function.handle, instr.expr_index, string): + return None + return binaryview.DerivedString._from_core_struct(string, True) -- cgit v1.3.1