Skip to content

Commit ac33013

Browse files
committed
Add derived strings and string recognizer API
1 parent 8e91002 commit ac33013

14 files changed

+1321
-20
lines changed

binaryninjaapi.h

Lines changed: 122 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4074,6 +4074,7 @@ namespace BinaryNinja {
40744074
class Segment;
40754075
class Component;
40764076
class TypeArchive;
4077+
struct DerivedString;
40774078

40784079
/*!
40794080

@@ -4107,6 +4108,8 @@ namespace BinaryNinja {
41074108

41084109
static void StringFoundCallback(void* ctxt, BNBinaryView* data, BNStringType type, uint64_t offset, size_t len);
41094110
static void StringRemovedCallback(void* ctxt, BNBinaryView* data, BNStringType type, uint64_t offset, size_t len);
4111+
static void DerivedStringFoundCallback(void* ctxt, BNBinaryView* data, BNDerivedString* str);
4112+
static void DerivedStringRemovedCallback(void* ctxt, BNBinaryView* data, BNDerivedString* str);
41104113
static void TypeDefinedCallback(void* ctxt, BNBinaryView* data, BNQualifiedName* name, BNType* type);
41114114
static void TypeUndefinedCallback(void* ctxt, BNBinaryView* data, BNQualifiedName* name, BNType* type);
41124115
static void TypeReferenceChangedCallback(void* ctx, BNBinaryView* data, BNQualifiedName* name, BNType* type);
@@ -4203,6 +4206,8 @@ namespace BinaryNinja {
42034206
UndoEntryTaken = 1ULL << 50,
42044207
RedoEntryTaken = 1ULL << 51,
42054208
Rebased = 1ULL << 52,
4209+
DerivedStringFound = 1ULL << 53,
4210+
DerivedStringRemoved = 1ULL << 54,
42064211

42074212
BinaryDataUpdates = DataWritten | DataInserted | DataRemoved,
42084213
FunctionLifetime = FunctionAdded | FunctionRemoved,
@@ -4213,7 +4218,7 @@ namespace BinaryNinja {
42134218
TagUpdates = TagLifetime | TagUpdated,
42144219
SymbolLifetime = SymbolAdded | SymbolRemoved,
42154220
SymbolUpdates = SymbolLifetime | SymbolUpdated,
4216-
StringUpdates = StringFound | StringRemoved,
4221+
StringUpdates = StringFound | StringRemoved | DerivedStringFound | DerivedStringRemoved,
42174222
TypeLifetime = TypeDefined | TypeUndefined,
42184223
TypeUpdates = TypeLifetime | TypeReferenceChanged | TypeFieldReferenceChanged,
42194224
SegmentLifetime = SegmentAdded | SegmentRemoved,
@@ -4350,6 +4355,16 @@ namespace BinaryNinja {
43504355
(void)offset;
43514356
(void)len;
43524357
}
4358+
virtual void OnDerivedStringFound(BinaryView* data, const DerivedString& str)
4359+
{
4360+
(void)data;
4361+
(void)str;
4362+
}
4363+
virtual void OnDerivedStringRemoved(BinaryView* data, const DerivedString& str)
4364+
{
4365+
(void)data;
4366+
(void)str;
4367+
}
43534368
virtual void OnTypeDefined(BinaryView* data, const QualifiedName& name, Type* type)
43544369
{
43554370
(void)data;
@@ -4823,7 +4838,7 @@ namespace BinaryNinja {
48234838

48244839
const char* c_str() const;
48254840
size_t size() const;
4826-
BNStringRef* GetObject() { return m_ref; }
4841+
BNStringRef* GetObject() const { return m_ref; }
48274842

48284843
bool operator==(const StringRef& other) const { return this->operator std::string_view() == other.operator std::string_view(); }
48294844
bool operator!=(const StringRef& other) const { return this->operator std::string_view() != other.operator std::string_view(); }
@@ -5357,6 +5372,47 @@ namespace BinaryNinja {
53575372
std::vector<TypeReferenceSource> typeRefs;
53585373
};
53595374

5375+
class CustomStringType: public StaticCoreRefCountObject<BNCustomStringType>
5376+
{
5377+
public:
5378+
CustomStringType(BNCustomStringType* type);
5379+
std::string GetName() const;
5380+
std::string GetStringPrefix() const;
5381+
std::string GetStringPostfix() const;
5382+
5383+
static Ref<CustomStringType> Register(
5384+
const std::string& name, const std::string& stringPrefix = "", const std::string& stringPostfix = "");
5385+
};
5386+
5387+
struct DerivedString
5388+
{
5389+
StringRef value;
5390+
std::optional<std::pair<uint64_t, uint64_t>> addrAndLength;
5391+
Ref<CustomStringType> customType;
5392+
5393+
bool operator==(const DerivedString& other) const
5394+
{
5395+
if (value != other.value)
5396+
return false;
5397+
if (addrAndLength != other.addrAndLength)
5398+
return false;
5399+
return customType == other.customType;
5400+
}
5401+
5402+
bool operator<(const DerivedString& other) const
5403+
{
5404+
if (value < other.value)
5405+
return true;
5406+
if (other.value < value)
5407+
return false;
5408+
if (addrAndLength < other.addrAndLength)
5409+
return true;
5410+
if (other.addrAndLength < addrAndLength)
5411+
return false;
5412+
return customType < other.customType;
5413+
}
5414+
};
5415+
53605416
struct QualifiedNameAndType;
53615417
struct PossibleValueSet;
53625418
class Metadata;
@@ -7132,6 +7188,10 @@ namespace BinaryNinja {
71327188
*/
71337189
std::vector<BNStringReference> GetStrings(uint64_t start, uint64_t len);
71347190

7191+
std::vector<DerivedString> GetDerivedStrings();
7192+
std::vector<ReferenceSource> GetDerivedStringCodeReferences(
7193+
const DerivedString& str, std::optional<size_t> maxItems = std::nullopt);
7194+
71357195
/*! Sets up a call back function to be called when analysis has been completed.
71367196

71377197
This is helpful when using `UpdateAnalysis` which does not wait for analysis completion before returning.
@@ -15441,6 +15501,10 @@ namespace BinaryNinja {
1544115501
std::set<Variable> GetVariables();
1544215502
std::set<Variable> GetAliasedVariables();
1544315503
std::set<SSAVariable> GetSSAVariables();
15504+
15505+
void SetDerivedStringReferenceForExpr(size_t expr, const DerivedString& str);
15506+
void RemoveDerivedStringReferenceForExpr(size_t expr);
15507+
std::optional<DerivedString> GetDerivedStringReferenceForExpr(size_t expr);
1544415508
};
1544515509

1544615510
struct LineFormatterSettings
@@ -21320,6 +21384,62 @@ namespace BinaryNinja {
2132021384
HighLevelILTokenEmitter& tokens, DisassemblySettings* settings, BNSymbolDisplayType symbolDisplay,
2132121385
BNOperatorPrecedence precedence) override;
2132221386
};
21387+
21388+
class StringRecognizer : public StaticCoreRefCountObject<BNStringRecognizer>
21389+
{
21390+
std::string m_nameForRegister;
21391+
21392+
public:
21393+
StringRecognizer(const std::string& name);
21394+
StringRecognizer(BNStringRecognizer* renderer);
21395+
21396+
std::string GetName() const;
21397+
21398+
virtual bool IsValidForType(HighLevelILFunction* func, Type* type);
21399+
virtual std::optional<DerivedString> RecognizeConstant(
21400+
const HighLevelILInstruction& instr, Type* type, int64_t val);
21401+
virtual std::optional<DerivedString> RecognizeConstantPointer(
21402+
const HighLevelILInstruction& instr, Type* type, int64_t val);
21403+
virtual std::optional<DerivedString> RecognizeExternPointer(
21404+
const HighLevelILInstruction& instr, Type* type, int64_t val, uint64_t offset);
21405+
virtual std::optional<DerivedString> RecognizeImport(
21406+
const HighLevelILInstruction& instr, Type* type, int64_t val);
21407+
21408+
/*! Registers the string recognizer.
21409+
21410+
\param recognizer The string recognizer to register.
21411+
*/
21412+
static void Register(StringRecognizer* recognizer);
21413+
21414+
static Ref<StringRecognizer> GetByName(const std::string& name);
21415+
static std::vector<Ref<StringRecognizer>> GetRecognizers();
21416+
21417+
private:
21418+
static bool IsValidForTypeCallback(void* ctxt, BNHighLevelILFunction* hlil, BNType* type);
21419+
static bool RecognizeConstantCallback(
21420+
void* ctxt, BNHighLevelILFunction* hlil, size_t expr, BNType* type, int64_t val, BNDerivedString* result);
21421+
static bool RecognizeConstantPointerCallback(
21422+
void* ctxt, BNHighLevelILFunction* hlil, size_t expr, BNType* type, int64_t val, BNDerivedString* result);
21423+
static bool RecognizeExternPointerCallback(void* ctxt, BNHighLevelILFunction* hlil, size_t expr, BNType* type,
21424+
int64_t val, uint64_t offset, BNDerivedString* result);
21425+
static bool RecognizeImportCallback(
21426+
void* ctxt, BNHighLevelILFunction* hlil, size_t expr, BNType* type, int64_t val, BNDerivedString* result);
21427+
};
21428+
21429+
class CoreStringRecognizer : public StringRecognizer
21430+
{
21431+
public:
21432+
CoreStringRecognizer(BNStringRecognizer* recognizer);
21433+
bool IsValidForType(HighLevelILFunction* func, Type* type) override;
21434+
std::optional<DerivedString> RecognizeConstant(
21435+
const HighLevelILInstruction& instr, Type* type, int64_t val) override;
21436+
std::optional<DerivedString> RecognizeConstantPointer(
21437+
const HighLevelILInstruction& instr, Type* type, int64_t val) override;
21438+
std::optional<DerivedString> RecognizeExternPointer(
21439+
const HighLevelILInstruction& instr, Type* type, int64_t val, uint64_t offset) override;
21440+
std::optional<DerivedString> RecognizeImport(
21441+
const HighLevelILInstruction& instr, Type* type, int64_t val) override;
21442+
};
2132321443
} // namespace BinaryNinja
2132421444

2132521445

binaryninjacore.h

Lines changed: 78 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,14 @@
3737
// Current ABI version for linking to the core. This is incremented any time
3838
// there are changes to the API that affect linking, including new functions,
3939
// new types, or modifications to existing functions or types.
40-
#define BN_CURRENT_CORE_ABI_VERSION 137
40+
#define BN_CURRENT_CORE_ABI_VERSION 138
4141

4242
// Minimum ABI version that is supported for loading of plugins. Plugins that
4343
// are linked to an ABI version less than this will not be able to load and
4444
// will require rebuilding. The minimum version is increased when there are
4545
// incompatible changes that break binary compatibility, such as changes to
4646
// existing types or functions.
47-
#define BN_MINIMUM_CORE_ABI_VERSION 136
47+
#define BN_MINIMUM_CORE_ABI_VERSION 138
4848

4949
#ifdef __GNUC__
5050
#ifdef BINARYNINJACORE_LIBRARY
@@ -312,6 +312,8 @@ extern "C"
312312
typedef struct BNIndirectBranchInfo BNIndirectBranchInfo;
313313
typedef struct BNArchitectureAndAddress BNArchitectureAndAddress;
314314
typedef struct BNConstantRenderer BNConstantRenderer;
315+
typedef struct BNStringRecognizer BNStringRecognizer;
316+
typedef struct BNCustomStringType BNCustomStringType;
315317

316318
typedef bool(*BNProgressFunction)(void*, size_t, size_t);
317319

@@ -460,7 +462,8 @@ extern "C"
460462
StringDisplayTokenContext = 10, // For displaying strings which aren't associated with an address
461463
ContentCollapsedContext = 11,
462464
ContentExpandedContext = 12,
463-
ContentCollapsiblePadding = 13
465+
ContentCollapsiblePadding = 13,
466+
DerivedStringReferenceTokenContext = 14
464467
} BNInstructionTextTokenContext;
465468

466469
typedef enum BNLinearDisassemblyLineType
@@ -1631,6 +1634,15 @@ extern "C"
16311634
size_t nameCount;
16321635
} BNQualifiedName;
16331636

1637+
typedef struct BNDerivedString
1638+
{
1639+
BNStringRef* value;
1640+
bool addrValid;
1641+
uint64_t addr;
1642+
uint64_t len;
1643+
BNCustomStringType* customType;
1644+
} BNDerivedString;
1645+
16341646
typedef struct BNBinaryDataNotification
16351647
{
16361648
void* context;
@@ -1656,6 +1668,8 @@ extern "C"
16561668
void (*symbolUpdated)(void* ctxt, BNBinaryView* view, BNSymbol* sym);
16571669
void (*stringFound)(void* ctxt, BNBinaryView* view, BNStringType type, uint64_t offset, size_t len);
16581670
void (*stringRemoved)(void* ctxt, BNBinaryView* view, BNStringType type, uint64_t offset, size_t len);
1671+
void (*derivedStringFound)(void* ctxt, BNBinaryView* view, BNDerivedString* str);
1672+
void (*derivedStringRemoved)(void* ctxt, BNBinaryView* view, BNDerivedString* str);
16591673
void (*typeDefined)(void* ctxt, BNBinaryView* view, BNQualifiedName* name, BNType* type);
16601674
void (*typeUndefined)(void* ctxt, BNBinaryView* view, BNQualifiedName* name, BNType* type);
16611675
void (*typeReferenceChanged)(void* ctxt, BNBinaryView* view, BNQualifiedName* name, BNType* type);
@@ -3818,6 +3832,27 @@ extern "C"
38183832
BNOperatorPrecedence precedence);
38193833
} BNCustomConstantRenderer;
38203834

3835+
typedef struct BNCustomStringRecognizer
3836+
{
3837+
void* context;
3838+
bool (*isValidForType)(void* ctxt, BNHighLevelILFunction* hlil, BNType* type);
3839+
bool (*recognizeConstant)(
3840+
void* ctxt, BNHighLevelILFunction* hlil, size_t expr, BNType* type, int64_t val, BNDerivedString* result);
3841+
bool (*recognizeConstantPointer)(
3842+
void* ctxt, BNHighLevelILFunction* hlil, size_t expr, BNType* type, int64_t val, BNDerivedString* result);
3843+
bool (*recognizeExternPointer)(void* ctxt, BNHighLevelILFunction* hlil, size_t expr, BNType* type, int64_t val,
3844+
uint64_t offset, BNDerivedString* result);
3845+
bool (*recognizeImport)(
3846+
void* ctxt, BNHighLevelILFunction* hlil, size_t expr, BNType* type, int64_t val, BNDerivedString* result);
3847+
} BNCustomStringRecognizer;
3848+
3849+
typedef struct BNCustomStringTypeInfo
3850+
{
3851+
char* name;
3852+
char* stringPrefix;
3853+
char* stringPostfix;
3854+
} BNCustomStringTypeInfo;
3855+
38213856
BINARYNINJACOREAPI char* BNAllocString(const char* contents);
38223857
BINARYNINJACOREAPI char* BNAllocStringWithLength(const char* contents, size_t len);
38233858
BINARYNINJACOREAPI void BNFreeString(char* str);
@@ -5261,6 +5296,11 @@ extern "C"
52615296
BNBinaryView* view, uint64_t start, uint64_t len, size_t* count);
52625297
BINARYNINJACOREAPI void BNFreeStringReferenceList(BNStringReference* strings);
52635298

5299+
BINARYNINJACOREAPI BNDerivedString* BNGetDerivedStrings(BNBinaryView* view, size_t* count);
5300+
BINARYNINJACOREAPI BNReferenceSource* BNGetDerivedStringCodeReferences(
5301+
BNBinaryView* view, BNDerivedString* str, size_t* count, bool limit, size_t maxItems);
5302+
BINARYNINJACOREAPI void BNFreeDerivedStringList(BNDerivedString* strings, size_t count);
5303+
52645304
BINARYNINJACOREAPI BNVariableNameAndType* BNGetStackLayout(BNFunction* func, size_t* count);
52655305
BINARYNINJACOREAPI void BNFreeVariableNameAndTypeList(BNVariableNameAndType* vars, size_t count);
52665306
BINARYNINJACOREAPI void BNCreateAutoStackVariable(
@@ -6564,6 +6604,12 @@ extern "C"
65646604
BINARYNINJACOREAPI bool BNHighLevelILExprEqual(
65656605
BNHighLevelILFunction* leftFunc, size_t leftExpr, BNHighLevelILFunction* rightFunc, size_t rightExpr);
65666606

6607+
BINARYNINJACOREAPI void BNSetHighLevelILDerivedStringReferenceForExpr(
6608+
BNHighLevelILFunction* func, size_t expr, BNDerivedString* str);
6609+
BINARYNINJACOREAPI void BNRemoveHighLevelILDerivedStringReferenceForExpr(BNHighLevelILFunction* func, size_t expr);
6610+
BINARYNINJACOREAPI bool BNGetHighLevelILDerivedStringReferenceForExpr(
6611+
BNHighLevelILFunction* func, size_t expr, BNDerivedString* out);
6612+
65676613
// Type Libraries
65686614
BINARYNINJACOREAPI BNTypeLibrary* BNNewTypeLibrary(BNArchitecture* arch, const char* name);
65696615
BINARYNINJACOREAPI BNTypeLibrary* BNNewTypeLibraryReference(BNTypeLibrary* lib);
@@ -8686,13 +8732,15 @@ extern "C"
86868732
BINARYNINJACOREAPI BNStringRef* BNDuplicateStringRef(BNStringRef* ref);
86878733
BINARYNINJACOREAPI const char* BNGetStringRefContents(BNStringRef* ref);
86888734
BINARYNINJACOREAPI size_t BNGetStringRefSize(BNStringRef* ref);
8735+
BINARYNINJACOREAPI BNStringRef* BNCreateStringRef(const char* str);
8736+
BINARYNINJACOREAPI BNStringRef* BNCreateStringRefOfLength(const char* str, size_t len);
86898737

86908738
// Constant Renderers
86918739
BINARYNINJACOREAPI BNConstantRenderer* BNRegisterConstantRenderer(
86928740
const char* name, BNCustomConstantRenderer* renderer);
86938741
BINARYNINJACOREAPI BNConstantRenderer* BNGetConstantRendererByName(const char* name);
86948742
BINARYNINJACOREAPI BNConstantRenderer** BNGetConstantRendererList(size_t* count);
8695-
BINARYNINJACOREAPI void BNFreeConstantRendererList(BNLanguageRepresentationFunctionType** renderers);
8743+
BINARYNINJACOREAPI void BNFreeConstantRendererList(BNConstantRenderer** renderers);
86968744
BINARYNINJACOREAPI char* BNGetConstantRendererName(BNConstantRenderer* renderer);
86978745
BINARYNINJACOREAPI bool BNIsConstantRendererValidForType(
86988746
BNConstantRenderer* renderer, BNHighLevelILFunction* il, BNType* type);
@@ -8703,6 +8751,32 @@ extern "C"
87038751
BNHighLevelILFunction* il, size_t exprIndex, BNType* type, int64_t val, BNHighLevelILTokenEmitter* tokens,
87048752
BNDisassemblySettings* settings, BNSymbolDisplayType symbolDisplay, BNOperatorPrecedence precedence);
87058753

8754+
// String recognizers
8755+
BINARYNINJACOREAPI BNCustomStringType* BNRegisterCustomStringType(BNCustomStringTypeInfo* info);
8756+
BINARYNINJACOREAPI BNCustomStringType* BNGetCustomStringTypeByName(const char* name);
8757+
BINARYNINJACOREAPI BNCustomStringType* BNGetCustomStringTypeByID(uint32_t id);
8758+
BINARYNINJACOREAPI BNCustomStringType** BNGetCustomStringTypeList(size_t* count);
8759+
BINARYNINJACOREAPI void BNFreeCustomStringTypeList(BNCustomStringType** types);
8760+
BINARYNINJACOREAPI char* BNGetCustomStringTypeName(BNCustomStringType* type);
8761+
BINARYNINJACOREAPI char* BNGetCustomStringTypePrefix(BNCustomStringType* type);
8762+
BINARYNINJACOREAPI char* BNGetCustomStringTypePostfix(BNCustomStringType* type);
8763+
BINARYNINJACOREAPI BNStringRecognizer* BNRegisterStringRecognizer(
8764+
const char* name, BNCustomStringRecognizer* recognizer);
8765+
BINARYNINJACOREAPI BNStringRecognizer* BNGetStringRecognizerByName(const char* name);
8766+
BINARYNINJACOREAPI BNStringRecognizer** BNGetStringRecognizerList(size_t* count);
8767+
BINARYNINJACOREAPI void BNFreeStringRecognizerList(BNStringRecognizer** recognizers);
8768+
BINARYNINJACOREAPI char* BNGetStringRecognizerName(BNStringRecognizer* recognizer);
8769+
BINARYNINJACOREAPI bool BNIsStringRecognizerValidForType(
8770+
BNStringRecognizer* recognizer, BNHighLevelILFunction* il, BNType* type);
8771+
BINARYNINJACOREAPI bool BNStringRecognizerRecognizeConstant(BNStringRecognizer* recognizer,
8772+
BNHighLevelILFunction* il, size_t exprIndex, BNType* type, int64_t val, BNDerivedString* out);
8773+
BINARYNINJACOREAPI bool BNStringRecognizerRecognizeConstantPointer(BNStringRecognizer* recognizer,
8774+
BNHighLevelILFunction* il, size_t exprIndex, BNType* type, int64_t val, BNDerivedString* out);
8775+
BINARYNINJACOREAPI bool BNStringRecognizerRecognizeExternPointer(BNStringRecognizer* recognizer,
8776+
BNHighLevelILFunction* il, size_t exprIndex, BNType* type, int64_t val, uint64_t offset, BNDerivedString* out);
8777+
BINARYNINJACOREAPI bool BNStringRecognizerRecognizeImport(BNStringRecognizer* recognizer, BNHighLevelILFunction* il,
8778+
size_t exprIndex, BNType* type, int64_t val, BNDerivedString* out);
8779+
87068780
#ifdef __cplusplus
87078781
}
87088782
#endif

0 commit comments

Comments
 (0)