Skip to content

Commit 59c9669

Browse files
committed
Add derived strings and string recognizer API
1 parent 0f65203 commit 59c9669

14 files changed

+1180
-21
lines changed

binaryninjaapi.h

Lines changed: 164 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,89 @@ 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 DerivedStringLocation
5388+
{
5389+
BNDerivedStringLocationType locationType;
5390+
uint64_t addr;
5391+
uint64_t len;
5392+
5393+
bool operator==(const DerivedStringLocation& other) const
5394+
{
5395+
if (locationType != other.locationType)
5396+
return false;
5397+
if (addr != other.addr)
5398+
return false;
5399+
return len == other.len;
5400+
}
5401+
5402+
bool operator!=(const DerivedStringLocation& other) const
5403+
{
5404+
return !(*this == other);
5405+
}
5406+
5407+
bool operator<(const DerivedStringLocation& other) const
5408+
{
5409+
if (addr < other.addr)
5410+
return true;
5411+
if (addr > other.addr)
5412+
return false;
5413+
if (len < other.len)
5414+
return true;
5415+
if (len > other.len)
5416+
return false;
5417+
return locationType < other.locationType;
5418+
}
5419+
};
5420+
5421+
struct DerivedString
5422+
{
5423+
StringRef value;
5424+
std::optional<DerivedStringLocation> location;
5425+
Ref<CustomStringType> customType;
5426+
5427+
bool operator==(const DerivedString& other) const
5428+
{
5429+
if (value != other.value)
5430+
return false;
5431+
if (location != other.location)
5432+
return false;
5433+
return customType == other.customType;
5434+
}
5435+
5436+
bool operator!=(const DerivedString& other) const
5437+
{
5438+
return !(*this == other);
5439+
}
5440+
5441+
bool operator<(const DerivedString& other) const
5442+
{
5443+
if (value < other.value)
5444+
return true;
5445+
if (other.value < value)
5446+
return false;
5447+
if (location < other.location)
5448+
return true;
5449+
if (other.location < location)
5450+
return false;
5451+
return customType < other.customType;
5452+
}
5453+
5454+
BNDerivedString ToAPIObject(bool owned) const;
5455+
static DerivedString FromAPIObject(BNDerivedString* str, bool owned);
5456+
};
5457+
53605458
struct QualifiedNameAndType;
53615459
struct PossibleValueSet;
53625460
class Metadata;
@@ -7132,6 +7230,10 @@ namespace BinaryNinja {
71327230
*/
71337231
std::vector<BNStringReference> GetStrings(uint64_t start, uint64_t len);
71347232

7233+
std::vector<DerivedString> GetDerivedStrings();
7234+
std::vector<ReferenceSource> GetDerivedStringCodeReferences(
7235+
const DerivedString& str, std::optional<size_t> maxItems = std::nullopt);
7236+
71357237
/*! Sets up a call back function to be called when analysis has been completed.
71367238

71377239
This is helpful when using `UpdateAnalysis` which does not wait for analysis completion before returning.
@@ -15441,6 +15543,10 @@ namespace BinaryNinja {
1544115543
std::set<Variable> GetVariables();
1544215544
std::set<Variable> GetAliasedVariables();
1544315545
std::set<SSAVariable> GetSSAVariables();
15546+
15547+
void SetDerivedStringReferenceForExpr(size_t expr, const DerivedString& str);
15548+
void RemoveDerivedStringReferenceForExpr(size_t expr);
15549+
std::optional<DerivedString> GetDerivedStringReferenceForExpr(size_t expr);
1544415550
};
1544515551

1544615552
struct LineFormatterSettings
@@ -21326,6 +21432,62 @@ namespace BinaryNinja {
2132621432
HighLevelILTokenEmitter& tokens, DisassemblySettings* settings, BNSymbolDisplayType symbolDisplay,
2132721433
BNOperatorPrecedence precedence) override;
2132821434
};
21435+
21436+
class StringRecognizer : public StaticCoreRefCountObject<BNStringRecognizer>
21437+
{
21438+
std::string m_nameForRegister;
21439+
21440+
public:
21441+
StringRecognizer(const std::string& name);
21442+
StringRecognizer(BNStringRecognizer* renderer);
21443+
21444+
std::string GetName() const;
21445+
21446+
virtual bool IsValidForType(HighLevelILFunction* func, Type* type);
21447+
virtual std::optional<DerivedString> RecognizeConstant(
21448+
const HighLevelILInstruction& instr, Type* type, int64_t val);
21449+
virtual std::optional<DerivedString> RecognizeConstantPointer(
21450+
const HighLevelILInstruction& instr, Type* type, int64_t val);
21451+
virtual std::optional<DerivedString> RecognizeExternPointer(
21452+
const HighLevelILInstruction& instr, Type* type, int64_t val, uint64_t offset);
21453+
virtual std::optional<DerivedString> RecognizeImport(
21454+
const HighLevelILInstruction& instr, Type* type, int64_t val);
21455+
21456+
/*! Registers the string recognizer.
21457+
21458+
\param recognizer The string recognizer to register.
21459+
*/
21460+
static void Register(StringRecognizer* recognizer);
21461+
21462+
static Ref<StringRecognizer> GetByName(const std::string& name);
21463+
static std::vector<Ref<StringRecognizer>> GetRecognizers();
21464+
21465+
private:
21466+
static bool IsValidForTypeCallback(void* ctxt, BNHighLevelILFunction* hlil, BNType* type);
21467+
static bool RecognizeConstantCallback(
21468+
void* ctxt, BNHighLevelILFunction* hlil, size_t expr, BNType* type, int64_t val, BNDerivedString* result);
21469+
static bool RecognizeConstantPointerCallback(
21470+
void* ctxt, BNHighLevelILFunction* hlil, size_t expr, BNType* type, int64_t val, BNDerivedString* result);
21471+
static bool RecognizeExternPointerCallback(void* ctxt, BNHighLevelILFunction* hlil, size_t expr, BNType* type,
21472+
int64_t val, uint64_t offset, BNDerivedString* result);
21473+
static bool RecognizeImportCallback(
21474+
void* ctxt, BNHighLevelILFunction* hlil, size_t expr, BNType* type, int64_t val, BNDerivedString* result);
21475+
};
21476+
21477+
class CoreStringRecognizer : public StringRecognizer
21478+
{
21479+
public:
21480+
CoreStringRecognizer(BNStringRecognizer* recognizer);
21481+
bool IsValidForType(HighLevelILFunction* func, Type* type) override;
21482+
std::optional<DerivedString> RecognizeConstant(
21483+
const HighLevelILInstruction& instr, Type* type, int64_t val) override;
21484+
std::optional<DerivedString> RecognizeConstantPointer(
21485+
const HighLevelILInstruction& instr, Type* type, int64_t val) override;
21486+
std::optional<DerivedString> RecognizeExternPointer(
21487+
const HighLevelILInstruction& instr, Type* type, int64_t val, uint64_t offset) override;
21488+
std::optional<DerivedString> RecognizeImport(
21489+
const HighLevelILInstruction& instr, Type* type, int64_t val) override;
21490+
};
2132921491
} // namespace BinaryNinja
2133021492

2133121493

0 commit comments

Comments
 (0)