summaryrefslogtreecommitdiff
path: root/stringrecognizer.cpp
diff options
context:
space:
mode:
authorRusty Wagner <rusty.wagner@gmail.com>2025-10-13 19:35:01 -0400
committerRusty Wagner <rusty.wagner@gmail.com>2025-10-21 13:52:39 -0400
commit5d4fc5f1fb7a0c368d2a048a5d750564c970c9c9 (patch)
treecd740b4af25fe5184935fd67067025733f17b099 /stringrecognizer.cpp
parentcae26921cf2b2e564f66e58b77a3963fe36f6d2d (diff)
Add derived strings and string recognizer API
Diffstat (limited to 'stringrecognizer.cpp')
-rw-r--r--stringrecognizer.cpp300
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);
+}