diff options
| -rw-r--r-- | binaryninjaapi.h | 17 | ||||
| -rw-r--r-- | binaryninjacore.h | 8 | ||||
| -rw-r--r-- | python/function.py | 2 | ||||
| -rw-r--r-- | python/stringrecognizer.py | 40 | ||||
| -rw-r--r-- | stringrecognizer.cpp | 31 |
5 files changed, 95 insertions, 3 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h index fa0a4716..57f896dd 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -22342,6 +22342,19 @@ namespace BinaryNinja { virtual std::optional<DerivedString> RecognizeImport( const HighLevelILInstruction& instr, Type* type, int64_t val); + /*! 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 \c constant_data accessor. + + If a string is found, return a \c DerivedString with the string information. + + \param instr High level expression containing the constant data + \return Optional \c DerivedString for any string that is found + */ + virtual std::optional<DerivedString> RecognizeConstantData( + const HighLevelILInstruction& instr); + /*! Registers the string recognizer. \param recognizer The string recognizer to register. @@ -22361,6 +22374,8 @@ namespace BinaryNinja { int64_t val, uint64_t offset, BNDerivedString* result); static bool RecognizeImportCallback( void* ctxt, BNHighLevelILFunction* hlil, size_t expr, BNType* type, int64_t val, BNDerivedString* result); + static bool RecognizeConstantDataCallback( + void* ctxt, BNHighLevelILFunction* hlil, size_t expr, BNDerivedString* result); }; class CoreStringRecognizer : public StringRecognizer @@ -22376,6 +22391,8 @@ namespace BinaryNinja { const HighLevelILInstruction& instr, Type* type, int64_t val, uint64_t offset) override; std::optional<DerivedString> RecognizeImport( const HighLevelILInstruction& instr, Type* type, int64_t val) override; + std::optional<DerivedString> RecognizeConstantData( + const HighLevelILInstruction& instr) override; }; } // namespace BinaryNinja diff --git a/binaryninjacore.h b/binaryninjacore.h index 382bf1d2..a0b985ec 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -37,14 +37,14 @@ // Current ABI version for linking to the core. This is incremented any time // there are changes to the API that affect linking, including new functions, // new types, or modifications to existing functions or types. -#define BN_CURRENT_CORE_ABI_VERSION 165 +#define BN_CURRENT_CORE_ABI_VERSION 166 // Minimum ABI version that is supported for loading of plugins. Plugins that // are linked to an ABI version less than this will not be able to load and // will require rebuilding. The minimum version is increased when there are // incompatible changes that break binary compatibility, such as changes to // existing types or functions. -#define BN_MINIMUM_CORE_ABI_VERSION 165 +#define BN_MINIMUM_CORE_ABI_VERSION 166 #ifdef __GNUC__ #ifdef BINARYNINJACORE_LIBRARY @@ -4022,6 +4022,8 @@ extern "C" uint64_t offset, BNDerivedString* result); bool (*recognizeImport)( void* ctxt, BNHighLevelILFunction* hlil, size_t expr, BNType* type, int64_t val, BNDerivedString* result); + bool (*recognizeConstantData)( + void* ctxt, BNHighLevelILFunction* hlil, size_t expr, BNDerivedString* result); } BNCustomStringRecognizer; typedef struct BNCustomStringTypeInfo @@ -9079,6 +9081,8 @@ extern "C" BNHighLevelILFunction* il, size_t exprIndex, BNType* type, int64_t val, uint64_t offset, BNDerivedString* out); BINARYNINJACOREAPI bool BNStringRecognizerRecognizeImport(BNStringRecognizer* recognizer, BNHighLevelILFunction* il, size_t exprIndex, BNType* type, int64_t val, BNDerivedString* out); + BINARYNINJACOREAPI bool BNStringRecognizerRecognizeConstantData(BNStringRecognizer* recognizer, + BNHighLevelILFunction* il, size_t exprIndex, BNDerivedString* out); // PossibleValueSet operations BINARYNINJACOREAPI void BNFreePossibleValueSet(BNPossibleValueSet* object); 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) diff --git a/stringrecognizer.cpp b/stringrecognizer.cpp index dc6ac2f8..47e0ca5e 100644 --- a/stringrecognizer.cpp +++ b/stringrecognizer.cpp @@ -136,6 +136,12 @@ std::optional<DerivedString> StringRecognizer::RecognizeImport(const HighLevelIL } +std::optional<DerivedString> StringRecognizer::RecognizeConstantData(const HighLevelILInstruction&) +{ + return std::nullopt; +} + + void StringRecognizer::Register(StringRecognizer* recognizer) { BNCustomStringRecognizer callbacks; @@ -145,6 +151,7 @@ void StringRecognizer::Register(StringRecognizer* recognizer) callbacks.recognizeConstantPointer = RecognizeConstantPointerCallback; callbacks.recognizeExternPointer = RecognizeExternPointerCallback; callbacks.recognizeImport = RecognizeImportCallback; + callbacks.recognizeConstantData = RecognizeConstantDataCallback; recognizer->AddRefForRegistration(); recognizer->m_object = BNRegisterStringRecognizer(recognizer->m_nameForRegister.c_str(), &callbacks); @@ -220,6 +227,20 @@ bool StringRecognizer::RecognizeImportCallback( } +bool StringRecognizer::RecognizeConstantDataCallback( + void* ctxt, BNHighLevelILFunction* hlil, size_t expr, BNDerivedString* result) +{ + StringRecognizer* recognizer = (StringRecognizer*)ctxt; + Ref<HighLevelILFunction> hlilObj = new HighLevelILFunction(BNNewHighLevelILFunctionReference(hlil)); + HighLevelILInstruction instr = hlilObj->GetExpr(expr); + auto str = recognizer->RecognizeConstantData(instr); + if (!str.has_value()) + return false; + *result = str->ToAPIObject(true); + return true; +} + + Ref<StringRecognizer> StringRecognizer::GetByName(const std::string& name) { BNStringRecognizer* recognizer = BNGetStringRecognizerByName(name.c_str()); @@ -298,3 +319,13 @@ std::optional<DerivedString> CoreStringRecognizer::RecognizeImport( return std::nullopt; return DerivedString::FromAPIObject(&str, true); } + + +std::optional<DerivedString> CoreStringRecognizer::RecognizeConstantData( + const HighLevelILInstruction& instr) +{ + BNDerivedString str; + if (!BNStringRecognizerRecognizeConstantData(m_object, instr.function->GetObject(), instr.exprIndex, &str)) + return std::nullopt; + return DerivedString::FromAPIObject(&str, true); +} |
