#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::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 StringRecognizer::RecognizeConstant(const HighLevelILInstruction&, Type*, int64_t) { return std::nullopt; } std::optional StringRecognizer::RecognizeConstantPointer(const HighLevelILInstruction&, Type*, int64_t) { return std::nullopt; } std::optional StringRecognizer::RecognizeExternPointer( const HighLevelILInstruction&, Type*, int64_t, uint64_t) { return std::nullopt; } std::optional 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 hlilObj = new HighLevelILFunction(BNNewHighLevelILFunctionReference(hlil)); Ref 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 hlilObj = new HighLevelILFunction(BNNewHighLevelILFunctionReference(hlil)); HighLevelILInstruction instr = hlilObj->GetExpr(expr); Ref 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 hlilObj = new HighLevelILFunction(BNNewHighLevelILFunctionReference(hlil)); HighLevelILInstruction instr = hlilObj->GetExpr(expr); Ref 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 hlilObj = new HighLevelILFunction(BNNewHighLevelILFunctionReference(hlil)); HighLevelILInstruction instr = hlilObj->GetExpr(expr); Ref 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 hlilObj = new HighLevelILFunction(BNNewHighLevelILFunctionReference(hlil)); HighLevelILInstruction instr = hlilObj->GetExpr(expr); Ref 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::GetByName(const std::string& name) { BNStringRecognizer* recognizer = BNGetStringRecognizerByName(name.c_str()); if (!recognizer) return nullptr; return new CoreStringRecognizer(recognizer); } vector> StringRecognizer::GetRecognizers() { size_t count = 0; BNStringRecognizer** recognizers = BNGetStringRecognizerList(&count); vector> 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 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 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 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 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); }