diff options
| author | Brian Potchik <brian@vector35.com> | 2026-04-17 12:10:07 -0400 |
|---|---|---|
| committer | Brian Potchik <brian@vector35.com> | 2026-04-17 12:10:07 -0400 |
| commit | bfd306437f34ebc4d4170c5fb8170261585f6038 (patch) | |
| tree | 36dd320d130fa23239213dd94546abb9a5ab4114 /python | |
| parent | 424dc721f5f2a3a7ffd5a6ccbcc7320b5ae7496d (diff) | |
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.
Diffstat (limited to 'python')
| -rw-r--r-- | python/function.py | 2 | ||||
| -rw-r--r-- | python/stringrecognizer.py | 40 |
2 files changed, 41 insertions, 1 deletions
diff --git a/python/function.py b/python/function.py index 93eb7d15..bc8def47 100644 --- a/python/function.py +++ b/python/function.py @@ -1938,7 +1938,7 @@ class Function: def get_constant_data_and_builtin( self, state: RegisterValueType, value: int, size: int = 0 ) -> Tuple[databuffer.DataBuffer, BuiltinType]: - builtin = ctypes.c_int() + builtin = ctypes.c_ubyte() db = databuffer.DataBuffer( handle=core.BNGetConstantData(self.handle, state, value, size, ctypes.byref(builtin))) return db, BuiltinType(builtin.value) 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) |
