diff options
| author | Rusty Wagner <rusty.wagner@gmail.com> | 2025-10-13 19:35:01 -0400 |
|---|---|---|
| committer | Rusty Wagner <rusty.wagner@gmail.com> | 2025-10-21 13:52:39 -0400 |
| commit | 5d4fc5f1fb7a0c368d2a048a5d750564c970c9c9 (patch) | |
| tree | cd740b4af25fe5184935fd67067025733f17b099 /stringrecognizer.cpp | |
| parent | cae26921cf2b2e564f66e58b77a3963fe36f6d2d (diff) | |
Add derived strings and string recognizer API
Diffstat (limited to 'stringrecognizer.cpp')
| -rw-r--r-- | stringrecognizer.cpp | 300 |
1 files changed, 300 insertions, 0 deletions
diff --git a/stringrecognizer.cpp b/stringrecognizer.cpp new file mode 100644 index 00000000..dc6ac2f8 --- /dev/null +++ b/stringrecognizer.cpp @@ -0,0 +1,300 @@ +#include "binaryninjaapi.h" +#include "ffi.h" +#include "highlevelilinstruction.h" + +using namespace BinaryNinja; +using namespace std; + + +BNDerivedString DerivedString::ToAPIObject(bool owned) const +{ + BNDerivedString result; + result.value = owned ? BNDuplicateStringRef(value.GetObject()) : value.GetObject(); + result.locationValid = location.has_value(); + if (location.has_value()) + { + result.location.locationType = location->locationType; + result.location.addr = location->addr; + result.location.len = location->len; + } + else + { + result.location.locationType = DataBackedStringLocation; + result.location.addr = 0; + result.location.len = 0; + } + result.customType = customType ? customType->GetObject() : nullptr; + return result; +} + + +DerivedString DerivedString::FromAPIObject(BNDerivedString* str, bool owned) +{ + DerivedString result; + result.value = StringRef(owned ? str->value : BNDuplicateStringRef(str->value)); + if (str->locationValid) + result.location = {str->location.locationType, str->location.addr, str->location.len}; + result.customType = str->customType ? new CustomStringType(str->customType) : nullptr; + return result; +} + + +CustomStringType::CustomStringType(BNCustomStringType* type) +{ + m_object = type; +} + + +string CustomStringType::GetName() const +{ + char* name = BNGetCustomStringTypeName(m_object); + string result = name; + BNFreeString(name); + return result; +} + + +string CustomStringType::GetStringPrefix() const +{ + char* prefix = BNGetCustomStringTypePrefix(m_object); + string result = prefix; + BNFreeString(prefix); + return result; +} + + +string CustomStringType::GetStringPostfix() const +{ + char* postfix = BNGetCustomStringTypePostfix(m_object); + string result = postfix; + BNFreeString(postfix); + return result; +} + + +Ref<CustomStringType> CustomStringType::Register( + const std::string& name, const std::string& stringPrefix, const std::string& stringPostfix) +{ + BNCustomStringTypeInfo info; + info.name = (char*)name.c_str(); + info.stringPrefix = (char*)stringPrefix.c_str(); + info.stringPostfix = (char*)stringPostfix.c_str(); + BNCustomStringType* result = BNRegisterCustomStringType(&info); + return new CustomStringType(result); +} + + +StringRecognizer::StringRecognizer(const std::string& name): m_nameForRegister(name) +{ + m_object = nullptr; +} + + +StringRecognizer::StringRecognizer(BNStringRecognizer* recognizer) +{ + m_object = recognizer; +} + + +string StringRecognizer::GetName() const +{ + char* name = BNGetStringRecognizerName(m_object); + string result = name; + BNFreeString(name); + return result; +} + + +bool StringRecognizer::IsValidForType(HighLevelILFunction*, Type*) +{ + return true; +} + + +std::optional<DerivedString> StringRecognizer::RecognizeConstant(const HighLevelILInstruction&, Type*, int64_t) +{ + return std::nullopt; +} + + +std::optional<DerivedString> StringRecognizer::RecognizeConstantPointer(const HighLevelILInstruction&, Type*, int64_t) +{ + return std::nullopt; +} + + +std::optional<DerivedString> StringRecognizer::RecognizeExternPointer( + const HighLevelILInstruction&, Type*, int64_t, uint64_t) +{ + return std::nullopt; +} + + +std::optional<DerivedString> StringRecognizer::RecognizeImport(const HighLevelILInstruction&, Type*, int64_t) +{ + return std::nullopt; +} + + +void StringRecognizer::Register(StringRecognizer* recognizer) +{ + BNCustomStringRecognizer callbacks; + callbacks.context = recognizer; + callbacks.isValidForType = IsValidForTypeCallback; + callbacks.recognizeConstant = RecognizeConstantCallback; + callbacks.recognizeConstantPointer = RecognizeConstantPointerCallback; + callbacks.recognizeExternPointer = RecognizeExternPointerCallback; + callbacks.recognizeImport = RecognizeImportCallback; + + recognizer->AddRefForRegistration(); + recognizer->m_object = BNRegisterStringRecognizer(recognizer->m_nameForRegister.c_str(), &callbacks); +} + + +bool StringRecognizer::IsValidForTypeCallback(void* ctxt, BNHighLevelILFunction* hlil, BNType* type) +{ + StringRecognizer* recognizer = (StringRecognizer*)ctxt; + Ref<HighLevelILFunction> hlilObj = new HighLevelILFunction(BNNewHighLevelILFunctionReference(hlil)); + Ref<Type> typeObj = new Type(BNNewTypeReference(type)); + return recognizer->IsValidForType(hlilObj, typeObj); +} + + +bool StringRecognizer::RecognizeConstantCallback( + void* ctxt, BNHighLevelILFunction* hlil, size_t expr, BNType* type, int64_t val, BNDerivedString* result) +{ + StringRecognizer* recognizer = (StringRecognizer*)ctxt; + Ref<HighLevelILFunction> hlilObj = new HighLevelILFunction(BNNewHighLevelILFunctionReference(hlil)); + HighLevelILInstruction instr = hlilObj->GetExpr(expr); + Ref<Type> typeObj = new Type(BNNewTypeReference(type)); + auto str = recognizer->RecognizeConstant(instr, typeObj, val); + if (!str.has_value()) + return false; + *result = str->ToAPIObject(true); + return true; +} + + +bool StringRecognizer::RecognizeConstantPointerCallback( + void* ctxt, BNHighLevelILFunction* hlil, size_t expr, BNType* type, int64_t val, BNDerivedString* result) +{ + StringRecognizer* recognizer = (StringRecognizer*)ctxt; + Ref<HighLevelILFunction> hlilObj = new HighLevelILFunction(BNNewHighLevelILFunctionReference(hlil)); + HighLevelILInstruction instr = hlilObj->GetExpr(expr); + Ref<Type> typeObj = new Type(BNNewTypeReference(type)); + auto str = recognizer->RecognizeConstantPointer(instr, typeObj, val); + if (!str.has_value()) + return false; + *result = str->ToAPIObject(true); + return true; +} + + +bool StringRecognizer::RecognizeExternPointerCallback(void* ctxt, BNHighLevelILFunction* hlil, size_t expr, + BNType* type, int64_t val, uint64_t offset, BNDerivedString* result) +{ + StringRecognizer* recognizer = (StringRecognizer*)ctxt; + Ref<HighLevelILFunction> hlilObj = new HighLevelILFunction(BNNewHighLevelILFunctionReference(hlil)); + HighLevelILInstruction instr = hlilObj->GetExpr(expr); + Ref<Type> typeObj = new Type(BNNewTypeReference(type)); + auto str = recognizer->RecognizeExternPointer(instr, typeObj, val, offset); + if (!str.has_value()) + return false; + *result = str->ToAPIObject(true); + return true; +} + + +bool StringRecognizer::RecognizeImportCallback( + void* ctxt, BNHighLevelILFunction* hlil, size_t expr, BNType* type, int64_t val, BNDerivedString* result) +{ + StringRecognizer* recognizer = (StringRecognizer*)ctxt; + Ref<HighLevelILFunction> hlilObj = new HighLevelILFunction(BNNewHighLevelILFunctionReference(hlil)); + HighLevelILInstruction instr = hlilObj->GetExpr(expr); + Ref<Type> typeObj = new Type(BNNewTypeReference(type)); + auto str = recognizer->RecognizeImport(instr, typeObj, val); + 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()); + if (!recognizer) + return nullptr; + return new CoreStringRecognizer(recognizer); +} + + +vector<Ref<StringRecognizer>> StringRecognizer::GetRecognizers() +{ + size_t count = 0; + BNStringRecognizer** recognizers = BNGetStringRecognizerList(&count); + + vector<Ref<StringRecognizer>> result; + result.reserve(count); + for (size_t i = 0; i < count; i++) + result.push_back(new CoreStringRecognizer(recognizers[i])); + + BNFreeStringRecognizerList(recognizers); + return result; +} + + +CoreStringRecognizer::CoreStringRecognizer(BNStringRecognizer* recognizer): + StringRecognizer(recognizer) +{ +} + + +bool CoreStringRecognizer::IsValidForType(HighLevelILFunction* func, Type* type) +{ + return BNIsStringRecognizerValidForType(m_object, func->GetObject(), type->GetObject()); +} + + +std::optional<DerivedString> CoreStringRecognizer::RecognizeConstant( + const HighLevelILInstruction& instr, Type* type, int64_t val) +{ + BNDerivedString str; + if (!BNStringRecognizerRecognizeConstant(m_object, instr.function->GetObject(), instr.exprIndex, + type->GetObject(), val, &str)) + return std::nullopt; + return DerivedString::FromAPIObject(&str, true); +} + + +std::optional<DerivedString> CoreStringRecognizer::RecognizeConstantPointer( + const HighLevelILInstruction& instr, Type* type, int64_t val) +{ + BNDerivedString str; + if (!BNStringRecognizerRecognizeConstantPointer(m_object, instr.function->GetObject(), instr.exprIndex, + type->GetObject(), val, &str)) + return std::nullopt; + return DerivedString::FromAPIObject(&str, true); +} + + +std::optional<DerivedString> CoreStringRecognizer::RecognizeExternPointer( + const HighLevelILInstruction& instr, Type* type, int64_t val, uint64_t offset) +{ + BNDerivedString str; + if (!BNStringRecognizerRecognizeExternPointer(m_object, instr.function->GetObject(), instr.exprIndex, + type->GetObject(), val, offset, &str)) + return std::nullopt; + return DerivedString::FromAPIObject(&str, true); +} + + +std::optional<DerivedString> CoreStringRecognizer::RecognizeImport( + const HighLevelILInstruction& instr, Type* type, int64_t val) +{ + BNDerivedString str; + if (!BNStringRecognizerRecognizeImport(m_object, instr.function->GetObject(), instr.exprIndex, + type->GetObject(), val, &str)) + return std::nullopt; + return DerivedString::FromAPIObject(&str, true); +} |
