summaryrefslogtreecommitdiff
path: root/binaryninjaapi.h
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 /binaryninjaapi.h
parentcae26921cf2b2e564f66e58b77a3963fe36f6d2d (diff)
Add derived strings and string recognizer API
Diffstat (limited to 'binaryninjaapi.h')
-rw-r--r--binaryninjaapi.h166
1 files changed, 164 insertions, 2 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h
index 96105e66..ecdeabdf 100644
--- a/binaryninjaapi.h
+++ b/binaryninjaapi.h
@@ -4074,6 +4074,7 @@ namespace BinaryNinja {
class Segment;
class Component;
class TypeArchive;
+ struct DerivedString;
/*!
@@ -4107,6 +4108,8 @@ namespace BinaryNinja {
static void StringFoundCallback(void* ctxt, BNBinaryView* data, BNStringType type, uint64_t offset, size_t len);
static void StringRemovedCallback(void* ctxt, BNBinaryView* data, BNStringType type, uint64_t offset, size_t len);
+ static void DerivedStringFoundCallback(void* ctxt, BNBinaryView* data, BNDerivedString* str);
+ static void DerivedStringRemovedCallback(void* ctxt, BNBinaryView* data, BNDerivedString* str);
static void TypeDefinedCallback(void* ctxt, BNBinaryView* data, BNQualifiedName* name, BNType* type);
static void TypeUndefinedCallback(void* ctxt, BNBinaryView* data, BNQualifiedName* name, BNType* type);
static void TypeReferenceChangedCallback(void* ctx, BNBinaryView* data, BNQualifiedName* name, BNType* type);
@@ -4203,6 +4206,8 @@ namespace BinaryNinja {
UndoEntryTaken = 1ULL << 50,
RedoEntryTaken = 1ULL << 51,
Rebased = 1ULL << 52,
+ DerivedStringFound = 1ULL << 53,
+ DerivedStringRemoved = 1ULL << 54,
BinaryDataUpdates = DataWritten | DataInserted | DataRemoved,
FunctionLifetime = FunctionAdded | FunctionRemoved,
@@ -4213,7 +4218,7 @@ namespace BinaryNinja {
TagUpdates = TagLifetime | TagUpdated,
SymbolLifetime = SymbolAdded | SymbolRemoved,
SymbolUpdates = SymbolLifetime | SymbolUpdated,
- StringUpdates = StringFound | StringRemoved,
+ StringUpdates = StringFound | StringRemoved | DerivedStringFound | DerivedStringRemoved,
TypeLifetime = TypeDefined | TypeUndefined,
TypeUpdates = TypeLifetime | TypeReferenceChanged | TypeFieldReferenceChanged,
SegmentLifetime = SegmentAdded | SegmentRemoved,
@@ -4350,6 +4355,16 @@ namespace BinaryNinja {
(void)offset;
(void)len;
}
+ virtual void OnDerivedStringFound(BinaryView* data, const DerivedString& str)
+ {
+ (void)data;
+ (void)str;
+ }
+ virtual void OnDerivedStringRemoved(BinaryView* data, const DerivedString& str)
+ {
+ (void)data;
+ (void)str;
+ }
virtual void OnTypeDefined(BinaryView* data, const QualifiedName& name, Type* type)
{
(void)data;
@@ -4823,7 +4838,7 @@ namespace BinaryNinja {
const char* c_str() const;
size_t size() const;
- BNStringRef* GetObject() { return m_ref; }
+ BNStringRef* GetObject() const { return m_ref; }
bool operator==(const StringRef& other) const { return this->operator std::string_view() == other.operator std::string_view(); }
bool operator!=(const StringRef& other) const { return this->operator std::string_view() != other.operator std::string_view(); }
@@ -5357,6 +5372,89 @@ namespace BinaryNinja {
std::vector<TypeReferenceSource> typeRefs;
};
+ class CustomStringType: public StaticCoreRefCountObject<BNCustomStringType>
+ {
+ public:
+ CustomStringType(BNCustomStringType* type);
+ std::string GetName() const;
+ std::string GetStringPrefix() const;
+ std::string GetStringPostfix() const;
+
+ static Ref<CustomStringType> Register(
+ const std::string& name, const std::string& stringPrefix = "", const std::string& stringPostfix = "");
+ };
+
+ struct DerivedStringLocation
+ {
+ BNDerivedStringLocationType locationType;
+ uint64_t addr;
+ uint64_t len;
+
+ bool operator==(const DerivedStringLocation& other) const
+ {
+ if (locationType != other.locationType)
+ return false;
+ if (addr != other.addr)
+ return false;
+ return len == other.len;
+ }
+
+ bool operator!=(const DerivedStringLocation& other) const
+ {
+ return !(*this == other);
+ }
+
+ bool operator<(const DerivedStringLocation& other) const
+ {
+ if (addr < other.addr)
+ return true;
+ if (addr > other.addr)
+ return false;
+ if (len < other.len)
+ return true;
+ if (len > other.len)
+ return false;
+ return locationType < other.locationType;
+ }
+ };
+
+ struct DerivedString
+ {
+ StringRef value;
+ std::optional<DerivedStringLocation> location;
+ Ref<CustomStringType> customType;
+
+ bool operator==(const DerivedString& other) const
+ {
+ if (value != other.value)
+ return false;
+ if (location != other.location)
+ return false;
+ return customType == other.customType;
+ }
+
+ bool operator!=(const DerivedString& other) const
+ {
+ return !(*this == other);
+ }
+
+ bool operator<(const DerivedString& other) const
+ {
+ if (value < other.value)
+ return true;
+ if (other.value < value)
+ return false;
+ if (location < other.location)
+ return true;
+ if (other.location < location)
+ return false;
+ return customType < other.customType;
+ }
+
+ BNDerivedString ToAPIObject(bool owned) const;
+ static DerivedString FromAPIObject(BNDerivedString* str, bool owned);
+ };
+
struct QualifiedNameAndType;
struct PossibleValueSet;
class Metadata;
@@ -7132,6 +7230,10 @@ namespace BinaryNinja {
*/
std::vector<BNStringReference> GetStrings(uint64_t start, uint64_t len);
+ std::vector<DerivedString> GetDerivedStrings();
+ std::vector<ReferenceSource> GetDerivedStringCodeReferences(
+ const DerivedString& str, std::optional<size_t> maxItems = std::nullopt);
+
/*! Sets up a call back function to be called when analysis has been completed.
This is helpful when using `UpdateAnalysis` which does not wait for analysis completion before returning.
@@ -15441,6 +15543,10 @@ namespace BinaryNinja {
std::set<Variable> GetVariables();
std::set<Variable> GetAliasedVariables();
std::set<SSAVariable> GetSSAVariables();
+
+ void SetDerivedStringReferenceForExpr(size_t expr, const DerivedString& str);
+ void RemoveDerivedStringReferenceForExpr(size_t expr);
+ std::optional<DerivedString> GetDerivedStringReferenceForExpr(size_t expr);
};
struct LineFormatterSettings
@@ -21326,6 +21432,62 @@ namespace BinaryNinja {
HighLevelILTokenEmitter& tokens, DisassemblySettings* settings, BNSymbolDisplayType symbolDisplay,
BNOperatorPrecedence precedence) override;
};
+
+ class StringRecognizer : public StaticCoreRefCountObject<BNStringRecognizer>
+ {
+ std::string m_nameForRegister;
+
+ public:
+ StringRecognizer(const std::string& name);
+ StringRecognizer(BNStringRecognizer* renderer);
+
+ std::string GetName() const;
+
+ virtual bool IsValidForType(HighLevelILFunction* func, Type* type);
+ virtual std::optional<DerivedString> RecognizeConstant(
+ const HighLevelILInstruction& instr, Type* type, int64_t val);
+ virtual std::optional<DerivedString> RecognizeConstantPointer(
+ const HighLevelILInstruction& instr, Type* type, int64_t val);
+ virtual std::optional<DerivedString> RecognizeExternPointer(
+ const HighLevelILInstruction& instr, Type* type, int64_t val, uint64_t offset);
+ virtual std::optional<DerivedString> RecognizeImport(
+ const HighLevelILInstruction& instr, Type* type, int64_t val);
+
+ /*! Registers the string recognizer.
+
+ \param recognizer The string recognizer to register.
+ */
+ static void Register(StringRecognizer* recognizer);
+
+ static Ref<StringRecognizer> GetByName(const std::string& name);
+ static std::vector<Ref<StringRecognizer>> GetRecognizers();
+
+ private:
+ static bool IsValidForTypeCallback(void* ctxt, BNHighLevelILFunction* hlil, BNType* type);
+ static bool RecognizeConstantCallback(
+ void* ctxt, BNHighLevelILFunction* hlil, size_t expr, BNType* type, int64_t val, BNDerivedString* result);
+ static bool RecognizeConstantPointerCallback(
+ void* ctxt, BNHighLevelILFunction* hlil, size_t expr, BNType* type, int64_t val, BNDerivedString* result);
+ static bool RecognizeExternPointerCallback(void* ctxt, BNHighLevelILFunction* hlil, size_t expr, BNType* type,
+ 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);
+ };
+
+ class CoreStringRecognizer : public StringRecognizer
+ {
+ public:
+ CoreStringRecognizer(BNStringRecognizer* recognizer);
+ bool IsValidForType(HighLevelILFunction* func, Type* type) override;
+ std::optional<DerivedString> RecognizeConstant(
+ const HighLevelILInstruction& instr, Type* type, int64_t val) override;
+ std::optional<DerivedString> RecognizeConstantPointer(
+ const HighLevelILInstruction& instr, Type* type, int64_t val) override;
+ std::optional<DerivedString> RecognizeExternPointer(
+ 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;
+ };
} // namespace BinaryNinja