summaryrefslogtreecommitdiff
path: root/plugins/warp/api
diff options
context:
space:
mode:
authorMason Reed <mason@vector35.com>2025-08-26 23:59:38 -0400
committerMason Reed <mason@vector35.com>2025-10-01 21:38:39 -0400
commitede39aee7e00c40a43b67ca18dd8ab80ee863d85 (patch)
tree67c5eda347ece2282e3c888f38066b496e06dec8 /plugins/warp/api
parenta1c46813e7f279aa4cfdb9dbb91c45b559ebeacd (diff)
[WARP] Enhanced network support
Diffstat (limited to 'plugins/warp/api')
-rw-r--r--plugins/warp/api/python/warp.py122
-rw-r--r--plugins/warp/api/python/warp_enums.py7
-rw-r--r--plugins/warp/api/warp.cpp113
-rw-r--r--plugins/warp/api/warp.h96
-rw-r--r--plugins/warp/api/warpcore.h40
5 files changed, 356 insertions, 22 deletions
diff --git a/plugins/warp/api/python/warp.py b/plugins/warp/api/python/warp.py
index 66fef872..29537895 100644
--- a/plugins/warp/api/python/warp.py
+++ b/plugins/warp/api/python/warp.py
@@ -8,6 +8,7 @@ from binaryninja import BinaryView, Function, BasicBlock, Architecture, Platform
from binaryninja._binaryninjacore import BNFreeString, BNAllocString, BNType
from . import _warpcore as warpcore
+from .warp_enums import WARPContainerSearchItemKind
class WarpUUID:
@@ -195,6 +196,108 @@ class WarpFunction:
warpcore.BNWARPFunctionApply(self.handle, function.handle)
+class WarpContainerSearchQuery:
+ def __init__(self, query: str, offset: Optional[int] = None, limit: Optional[int] = None, source: Optional[Source] = None, source_tags: Optional[List[str]] = None):
+ self.query = query
+ self.source = source
+ self.offset = offset
+ self.limit = limit
+ offset_ptr = None
+ if offset is not None:
+ self._c_offset = ctypes.c_size_t(offset)
+ offset_ptr = ctypes.byref(self._c_offset)
+ limit_ptr = None
+ if limit is not None:
+ self._c_limit = ctypes.c_size_t(limit)
+ limit_ptr = ctypes.byref(self._c_limit)
+ source_ptr = None
+ if source is not None:
+ self._c_source = source.uuid
+ source_ptr = ctypes.byref(self._c_source)
+ source_tags_len = 0
+ source_tags_array_ptr = None
+ if source_tags is not None:
+ source_tags_ptr = (ctypes.c_char_p * len(source_tags))()
+ source_tags_len = len(source_tags)
+ for i in range(len(source_tags)):
+ source_tags_ptr[i] = source_tags[i].encode('utf-8')
+ source_tags_array_ptr = ctypes.cast(source_tags_ptr, ctypes.POINTER(ctypes.c_char_p))
+ self.handle = warpcore.BNWARPNewContainerSearchQuery(query, offset_ptr, limit_ptr, source_ptr, source_tags_array_ptr, source_tags_len)
+
+ def __del__(self):
+ if self.handle is not None:
+ warpcore.BNWARPFreeContainerSearchQueryReference(self.handle)
+
+ def __repr__(self):
+ # TODO: Display offset and limit in a pythonic way.
+ if self.source is None:
+ return f"<WarpContainerSearchQuery '{self.query}'>"
+ return f"<WarpContainerSearchQuery '{self.query}': '{self.source}'>"
+
+
+class WarpContainerSearchItem:
+ def __init__(self, handle: warpcore.BNWARPContainerSearchItem):
+ self.handle = handle
+
+ def __del__(self):
+ if self.handle is not None:
+ warpcore.BNWARPFreeContainerSearchItemReference(self.handle)
+
+ @property
+ def kind(self) -> WARPContainerSearchItemKind:
+ return WARPContainerSearchItemKind(warpcore.BNWARPContainerSearchItemGetKind(self.handle))
+
+ @property
+ def source(self) -> Source:
+ return Source(warpcore.BNWARPContainerSearchItemGetSource(self.handle))
+
+ @property
+ def name(self) -> str:
+ return warpcore.BNWARPContainerSearchItemGetName(self.handle)
+
+ def get_type(self, arch: Architecture) -> Optional[Type]:
+ ty = warpcore.BNWARPContainerSearchItemGetType(arch.handle, self.handle)
+ if not ty:
+ return None
+ return Type(ty)
+
+ @property
+ def function(self) -> Optional[WarpFunction]:
+ func = warpcore.BNWARPContainerSearchItemGetFunction(self.handle)
+ if not func:
+ return None
+ return WarpFunction(func)
+
+ def __repr__(self):
+ return f"<WarpContainerSearchItem '{self.name}': '{self.source}'>"
+
+
+class WarpContainerResponse:
+ def __init__(self, items: List[WarpContainerSearchItem], offset: int, total: int):
+ self.items = items
+ self.offset = offset
+ self.total = total
+
+ def __iter__(self):
+ return iter(self.items)
+
+ def __len__(self):
+ return len(self.items)
+
+ def __repr__(self):
+ return f"<WarpContainerResponse items={len(self.items)} offset={self.offset} total={self.total}>"
+
+ @staticmethod
+ def from_api(response: warpcore.BNWARPContainerSearchResponse) -> 'WarpContainerResponse':
+ try:
+ items = []
+ for i in range(response.count):
+ items.append(WarpContainerSearchItem(warpcore.BNWARPNewContainerSearchItemReference(response.items[i])))
+ return WarpContainerResponse(items=items, offset=response.offset, total=response.total)
+ finally:
+ warpcore.BNWARPFreeContainerSearchResponse(response)
+
+
class _WarpContainerMetaclass(type):
def __iter__(self):
binaryninja._init_plugins()
@@ -305,12 +408,19 @@ class WarpContainer(metaclass=_WarpContainerMetaclass):
core_guids[i] = guids[i].uuid
return warpcore.BNWARPContainerRemoveTypes(self.handle, source.uuid, core_guids, count)
- def fetch_functions(self, target: WarpTarget, guids: List[FunctionGUID]):
+ def fetch_functions(self, target: WarpTarget, guids: List[FunctionGUID], source_tags: Optional[List[str]] = None):
count = len(guids)
core_guids = (warpcore.BNWARPFunctionGUID * count)()
for i in range(count):
core_guids[i] = guids[i].uuid
- warpcore.BNWARPContainerFetchFunctions(self.handle, target.handle, core_guids, count)
+ if source_tags is None:
+ source_tags = []
+ source_tags_ptr = (ctypes.c_char_p * len(source_tags))()
+ source_tags_len = len(source_tags)
+ for i in range(len(source_tags)):
+ source_tags_ptr[i] = source_tags[i].encode('utf-8')
+ source_tags_array_ptr = ctypes.cast(source_tags_ptr, ctypes.POINTER(ctypes.c_char_p))
+ warpcore.BNWARPContainerFetchFunctions(self.handle, target.handle, source_tags_array_ptr, source_tags_len, core_guids, count)
def get_sources_with_function_guid(self, target: WarpTarget, guid: FunctionGUID) -> List[Source]:
count = ctypes.c_size_t()
@@ -346,7 +456,7 @@ class WarpContainer(metaclass=_WarpContainerMetaclass):
return result
def get_type_with_guid(self, arch: Architecture, source: Source, guid: TypeGUID) -> Optional[Type]:
- ty = warpcore.BNWARPContainerGetTypeWithGUID(self.handle, arch.handle, source.uuid, guid.uuid)
+ ty = warpcore.BNWARPContainerGetTypeWithGUID(arch.handle, self.handle, source.uuid, guid.uuid)
if not ty:
return None
return Type(ty)
@@ -362,6 +472,12 @@ class WarpContainer(metaclass=_WarpContainerMetaclass):
warpcore.BNWARPFreeUUIDList(guids, count.value)
return result
+ def search(self, query: WarpContainerSearchQuery) -> Optional[WarpContainerResponse]:
+ response = warpcore.BNWARPContainerSearch(self.handle, query.handle)
+ if not response:
+ return None
+ return WarpContainerResponse.from_api(response.contents)
+
def run_matcher(view: BinaryView):
warpcore.BNWARPRunMatcher(view.handle)
diff --git a/plugins/warp/api/python/warp_enums.py b/plugins/warp/api/python/warp_enums.py
index e47ff1c3..86be3a6c 100644
--- a/plugins/warp/api/python/warp_enums.py
+++ b/plugins/warp/api/python/warp_enums.py
@@ -1 +1,8 @@
import enum
+
+
+class WARPContainerSearchItemKind(enum.IntEnum):
+ WARPContainerSearchItemKindSource = 0
+ WARPContainerSearchItemKindFunction = 1
+ WARPContainerSearchItemKindType = 2
+ WARPContainerSearchItemKindSymbol = 3
diff --git a/plugins/warp/api/warp.cpp b/plugins/warp/api/warp.cpp
index 52c7ea9d..f6106605 100644
--- a/plugins/warp/api/warp.cpp
+++ b/plugins/warp/api/warp.cpp
@@ -5,6 +5,14 @@
using namespace Warp;
+std::optional<WarpUUID> WarpUUID::FromString(const std::string &str)
+{
+ BNWARPUUID uuid = {};
+ if (!BNWARPUUIDFromString(str.c_str(), &uuid))
+ return std::nullopt;
+ return WarpUUID(uuid);
+}
+
std::string WarpUUID::ToString() const
{
char *str = BNWARPUUIDGetString(&uuid);
@@ -133,6 +141,94 @@ void Function::RemoveMatch(const BinaryNinja::Function &function)
BNWARPFunctionApply(nullptr, function.m_object);
}
+ContainerSearchQuery::ContainerSearchQuery(BNWARPContainerSearchQuery *query)
+{
+ m_object = query;
+}
+
+ContainerSearchQuery::ContainerSearchQuery(const std::string &query)
+{
+ m_object = BNWARPNewContainerSearchQuery(query.c_str(), nullptr, nullptr, nullptr, nullptr, 0);
+}
+
+ContainerSearchQuery::ContainerSearchQuery(const std::string &query, const Source &source)
+{
+ m_object = BNWARPNewContainerSearchQuery(query.c_str(), nullptr, nullptr, source.Raw(), nullptr, 0);
+}
+
+ContainerSearchQuery::ContainerSearchQuery(const std::string &query, size_t offset, size_t limit, const std::optional<Source> &source, const std::vector<SourceTag> &tags)
+{
+ size_t tagCount = tags.size();
+ const char** rawTags = new const char*[tagCount];
+ for (size_t i = 0; i < tagCount; i++)
+ rawTags[i] = tags[i].c_str();
+ if (source)
+ m_object = BNWARPNewContainerSearchQuery(query.c_str(), &offset, &limit, source.value().Raw(), rawTags, tagCount);
+ else
+ m_object = BNWARPNewContainerSearchQuery(query.c_str(), &offset, &limit, nullptr, rawTags, tagCount);
+ delete[] rawTags;
+}
+
+ContainerSearchItem::ContainerSearchItem(BNWARPContainerSearchItem *item)
+{
+ m_object = item;
+}
+
+BNWARPContainerSearchItemKind ContainerSearchItem::GetKind() const
+{
+ return BNWARPContainerSearchItemGetKind(m_object);
+}
+
+Source ContainerSearchItem::GetSource() const
+{
+ return BNWARPContainerSearchItemGetSource(m_object);
+}
+
+BinaryNinja::Ref<BinaryNinja::Type> ContainerSearchItem::GetType(const BinaryNinja::Ref<BinaryNinja::Architecture> &arch) const
+{
+ BNType *type = BNWARPContainerSearchItemGetType(arch ? arch->m_object : nullptr, m_object);
+ if (!type)
+ return nullptr;
+ return new BinaryNinja::Type(type);
+}
+
+std::string ContainerSearchItem::GetName() const
+{
+ // NOTE: In the future we may want the name to be optional, see rust core side for more info.
+ char *rawName = BNWARPContainerSearchItemGetName(m_object);
+ std::string name = rawName;
+ BNFreeString(rawName);
+ return name;
+}
+
+Ref<Function> ContainerSearchItem::GetFunction() const
+{
+ BNWARPFunction *function = BNWARPContainerSearchItemGetFunction(m_object);
+ if (!function)
+ return nullptr;
+ return new Function(function);
+}
+
+
+ContainerSearchResponse::ContainerSearchResponse(std::vector<Ref<ContainerSearchItem>>&& items, size_t offset,
+ size_t total)
+{
+ this->items = std::move(items);
+ this->offset = offset;
+ this->total = total;
+}
+
+ContainerSearchResponse ContainerSearchResponse::FromAPIObject(BNWARPContainerSearchResponse *response)
+{
+ std::vector<Ref<ContainerSearchItem>> items;
+ items.reserve(response->count);
+ for (int i = 0; i < response->count; i++)
+ items.push_back(new ContainerSearchItem(BNWARPNewContainerSearchItemReference(response->items[i])));
+ ContainerSearchResponse resp = {std::move(items), response->offset, response->total};
+ BNWARPFreeContainerSearchResponse(response);
+ return resp;
+}
+
Container::Container(BNWARPContainer *container)
{
m_object = container;
@@ -249,14 +345,19 @@ bool Container::RemoveTypes(const Source &source, const std::vector<TypeGUID> &g
return result;
}
-void Container::FetchFunctions(const Target &target, const std::vector<FunctionGUID> &guids) const
+void Container::FetchFunctions(const Target &target, const std::vector<FunctionGUID> &guids, const std::vector<SourceTag> &tags) const
{
size_t count = guids.size();
BNWARPFunctionGUID *apiGuids = new BNWARPFunctionGUID[count];
for (size_t i = 0; i < count; i++)
apiGuids[i] = *guids[i].Raw();
- BNWARPContainerFetchFunctions(m_object, target.m_object, apiGuids, count);
+ size_t tagCount = tags.size();
+ const char** rawTags = new const char*[tagCount];
+ for (size_t i = 0; i < tagCount; i++)
+ rawTags[i] = tags[i].c_str();
+ BNWARPContainerFetchFunctions(m_object, target.m_object, rawTags, tagCount, apiGuids, count);
delete[] apiGuids;
+ delete[] rawTags;
}
std::vector<Source> Container::GetSourcesWithFunctionGUID(const Target& target, const FunctionGUID &guid) const
@@ -314,6 +415,14 @@ std::vector<TypeGUID> Container::GetTypeGUIDsWithName(const Source &source, cons
return result;
}
+std::optional<ContainerSearchResponse> Container::Search(const ContainerSearchQuery &query) const
+{
+ BNWARPContainerSearchResponse *response = BNWARPContainerSearch(m_object, query.m_object);
+ if (!response)
+ return std::nullopt;
+ return ContainerSearchResponse::FromAPIObject(response);
+}
+
void Warp::RunMatcher(const BinaryNinja::BinaryView &view)
{
BNWARPRunMatcher(view.m_object);
diff --git a/plugins/warp/api/warp.h b/plugins/warp/api/warp.h
index 807ba998..14be9a0d 100644
--- a/plugins/warp/api/warp.h
+++ b/plugins/warp/api/warp.h
@@ -68,7 +68,7 @@ namespace Warp {
{
T *m_obj;
#ifdef BN_REF_COUNT_DEBUG
- void* m_assignmentTrace = nullptr;
+ void *m_assignmentTrace = nullptr;
#endif
public:
@@ -230,8 +230,12 @@ namespace Warp {
public:
WarpUUID() = default;
-
- WarpUUID(BNWARPUUID uuid) : uuid(uuid) {}
+
+ WarpUUID(BNWARPUUID uuid) : uuid(uuid)
+ {
+ }
+
+ static std::optional<WarpUUID> FromString(const std::string &str);
std::string ToString() const;
@@ -245,12 +249,12 @@ namespace Warp {
return !(*this == other);
}
- BNWARPUUID* RawMut()
+ BNWARPUUID *RawMut()
{
return &uuid;
}
- const BNWARPUUID* Raw() const
+ const BNWARPUUID *Raw() const
{
return &uuid;
}
@@ -261,6 +265,7 @@ namespace Warp {
typedef WarpUUID FunctionGUID;
typedef WarpUUID ConstraintGUID;
typedef WarpUUID TypeGUID;
+ typedef std::string SourceTag;
class Target : public WarpRefCountObject<BNWARPTarget, BNWARPNewTargetReference,
BNWARPFreeTargetReference>
@@ -268,9 +273,9 @@ namespace Warp {
public:
explicit Target(BNWARPTarget *target);
- static Ref<Target> FromPlatform(const BinaryNinja::Platform& platform);
+ static Ref<Target> FromPlatform(const BinaryNinja::Platform &platform);
};
-
+
struct Constraint
{
ConstraintGUID guid;
@@ -278,7 +283,7 @@ namespace Warp {
Constraint(ConstraintGUID guid, std::optional<int64_t> offset);
- static Constraint FromAPIObject(BNWARPConstraint* constraint);
+ static Constraint FromAPIObject(BNWARPConstraint *constraint);
};
struct FunctionComment
@@ -288,7 +293,7 @@ namespace Warp {
FunctionComment(std::string text, int64_t offset);
- static FunctionComment FromAPIObject(BNWARPFunctionComment* comment);
+ static FunctionComment FromAPIObject(BNWARPFunctionComment *comment);
};
class Function : public WarpRefCountObject<BNWARPFunction, BNWARPNewFunctionReference, BNWARPFreeFunctionReference>
@@ -322,6 +327,51 @@ namespace Warp {
static void RemoveMatch(const BinaryNinja::Function &function);
};
+ class ContainerSearchQuery : public WarpRefCountObject<BNWARPContainerSearchQuery,
+ BNWARPNewContainerSearchQueryReference,
+ BNWARPFreeContainerSearchQueryReference>
+ {
+ public:
+ explicit ContainerSearchQuery(BNWARPContainerSearchQuery *query);
+
+ explicit ContainerSearchQuery(const std::string &query);
+
+ ContainerSearchQuery(const std::string &query, const Source &source);
+
+ ContainerSearchQuery(const std::string &query, size_t offset, size_t limit,
+ const std::optional<Source> &source = std::nullopt,
+ const std::vector<SourceTag> &tags = {});
+ };
+
+ class ContainerSearchItem : public WarpRefCountObject<BNWARPContainerSearchItem,
+ BNWARPNewContainerSearchItemReference,
+ BNWARPFreeContainerSearchItemReference>
+ {
+ public:
+ explicit ContainerSearchItem(BNWARPContainerSearchItem *item);
+
+ BNWARPContainerSearchItemKind GetKind() const;
+
+ Source GetSource() const;
+
+ BinaryNinja::Ref<BinaryNinja::Type> GetType(const BinaryNinja::Ref<BinaryNinja::Architecture> &arch) const;
+
+ std::string GetName() const;
+
+ Ref<Function> GetFunction() const;
+ };
+
+ struct ContainerSearchResponse
+ {
+ std::vector<Ref<ContainerSearchItem> > items;
+ size_t offset;
+ size_t total;
+
+ ContainerSearchResponse(std::vector<Ref<ContainerSearchItem> > &&items, size_t offset, size_t total);
+
+ static ContainerSearchResponse FromAPIObject(BNWARPContainerSearchResponse *response);
+ };
+
class Container : public WarpRefCountObject<BNWARPContainer, BNWARPNewContainerReference,
BNWARPFreeContainerReference>
{
@@ -345,36 +395,50 @@ namespace Warp {
std::optional<std::string> SourcePath(const Source &source) const;
- bool AddFunctions(const Target &target, const Source &source, const std::vector<Ref<Function> > &functions) const;
+ bool AddFunctions(const Target &target, const Source &source,
+ const std::vector<Ref<Function> > &functions) const;
bool AddTypes(const BinaryNinja::BinaryView &view, const Source &source,
const std::vector<BinaryNinja::Ref<BinaryNinja::Type> > &types) const;
- bool RemoveFunctions(const Target &target, const Source &source, const std::vector<Ref<Function> > &functions) const;
+ bool RemoveFunctions(const Target &target, const Source &source,
+ const std::vector<Ref<Function> > &functions) const;
bool RemoveTypes(const Source &source, const std::vector<TypeGUID> &guids) const;
- void FetchFunctions(const Target& target, const std::vector<FunctionGUID> &guids) const;
+ void FetchFunctions(const Target &target, const std::vector<FunctionGUID> &guids, const std::vector<SourceTag> &tags = {}) const;
- std::vector<Source> GetSourcesWithFunctionGUID(const Target& target, const FunctionGUID &guid) const;
+ std::vector<Source> GetSourcesWithFunctionGUID(const Target &target, const FunctionGUID &guid) const;
std::vector<Source> GetSourcesWithTypeGUID(const TypeGUID &guid) const;
- std::vector<Ref<Function> > GetFunctionsWithGUID(const Target& target, const Source &source, const FunctionGUID &guid) const;
+ std::vector<Ref<Function> > GetFunctionsWithGUID(const Target &target, const Source &source,
+ const FunctionGUID &guid) const;
BinaryNinja::Ref<BinaryNinja::Type> GetTypeWithGUID(const BinaryNinja::Architecture &arch, const Source &source,
const TypeGUID &guid) const;
std::vector<TypeGUID> GetTypeGUIDsWithName(const Source &source, const std::string &name) const;
+
+ std::optional<ContainerSearchResponse> Search(const ContainerSearchQuery &query) const;
};
- void RunMatcher(const BinaryNinja::BinaryView& view);
+ void RunMatcher(const BinaryNinja::BinaryView &view);
bool IsInstructionVariant(const BinaryNinja::LowLevelILFunction &function, BinaryNinja::ExprId idx);
bool IsInstructionBlacklisted(const BinaryNinja::LowLevelILFunction &function, BinaryNinja::ExprId idx);
-
+
std::optional<FunctionGUID> GetAnalysisFunctionGUID(const BinaryNinja::Function &function);
std::optional<BasicBlockGUID> GetBasicBlockGUID(const BinaryNinja::BasicBlock &basicBlock);
}
+
+template<> struct std::hash<Warp::WarpUUID>
+{
+ size_t operator()(Warp::WarpUUID const& item) const noexcept
+ {
+ // TODO: Use the raw bytes instead.
+ return std::hash<std::string>()(item.ToString());
+ }
+}; \ No newline at end of file
diff --git a/plugins/warp/api/warpcore.h b/plugins/warp/api/warpcore.h
index 20a59b7b..b62f2427 100644
--- a/plugins/warp/api/warpcore.h
+++ b/plugins/warp/api/warpcore.h
@@ -61,6 +61,7 @@ extern "C"
};
char* BNWARPUUIDGetString(const BNWARPUUID* uuid);
+ bool BNWARPUUIDFromString(const char* str, BNWARPUUID* uuid);
bool BNWARPUUIDEqual(const BNWARPUUID* a, const BNWARPUUID* b);
void BNWARPFreeUUIDList(BNWARPUUID* uuids, size_t count);
@@ -74,6 +75,24 @@ extern "C"
typedef struct BNWARPContainer BNWARPContainer;
typedef struct BNWARPFunction BNWARPFunction;
typedef struct BNWARPConstraint BNWARPConstraint;
+ typedef struct BNWARPContainerSearchQuery BNWARPContainerSearchQuery;
+ typedef struct BNWARPContainerSearchItem BNWARPContainerSearchItem;
+
+ enum BNWARPContainerSearchItemKind
+ {
+ WARPContainerSearchItemKindSource = 0,
+ WARPContainerSearchItemKindFunction = 1,
+ WARPContainerSearchItemKindType = 2,
+ WARPContainerSearchItemKindSymbol = 3,
+ };
+
+ struct BNWARPContainerSearchResponse
+ {
+ size_t count;
+ BNWARPContainerSearchItem** items;
+ size_t offset;
+ size_t total;
+ };
struct BNWARPConstraint
{
@@ -108,7 +127,7 @@ extern "C"
WARP_FFI_API bool BNWARPContainerRemoveFunctions(BNWARPContainer* container, const BNWARPTarget* target, const BNWARPSource* source, BNWARPFunction** functions, size_t count);
WARP_FFI_API bool BNWARPContainerRemoveTypes(BNWARPContainer* container, const BNWARPSource* source, BNWARPTypeGUID* types, size_t count);
- WARP_FFI_API void BNWARPContainerFetchFunctions(BNWARPContainer* container, BNWARPTarget* target, const BNWARPTypeGUID* guids, size_t count);
+ WARP_FFI_API void BNWARPContainerFetchFunctions(BNWARPContainer* container, BNWARPTarget* target, const char** sourceTags, size_t sourceTagCount, const BNWARPTypeGUID* guids, size_t count);
WARP_FFI_API BNWARPSource* BNWARPContainerGetSourcesWithFunctionGUID(BNWARPContainer* container, const BNWARPTarget* target, const BNWARPFunctionGUID* guid, size_t* count);
WARP_FFI_API BNWARPSource* BNWARPContainerGetSourcesWithTypeGUID(BNWARPContainer* container, const BNWARPTypeGUID* guid, size_t* count);
@@ -120,6 +139,25 @@ extern "C"
WARP_FFI_API void BNWARPFreeContainerReference(BNWARPContainer* container);
WARP_FFI_API void BNWARPFreeContainerList(BNWARPContainer** containers, size_t count);
+ WARP_FFI_API BNWARPContainerSearchQuery* BNWARPNewContainerSearchQuery(const char* query, const size_t* offset, const size_t* limit, const BNWARPSource* source, const char** sourceTags, size_t sourceTagCount);
+
+ WARP_FFI_API BNWARPContainerSearchResponse* BNWARPContainerSearch(BNWARPContainer* container, const BNWARPContainerSearchQuery* query);
+
+ WARP_FFI_API BNWARPContainerSearchItemKind BNWARPContainerSearchItemGetKind(BNWARPContainerSearchItem* item);
+ WARP_FFI_API BNWARPSource BNWARPContainerSearchItemGetSource(BNWARPContainerSearchItem* item);
+ WARP_FFI_API BNType* BNWARPContainerSearchItemGetType(BNArchitecture* arch, BNWARPContainerSearchItem* item);
+ WARP_FFI_API char* BNWARPContainerSearchItemGetName(BNWARPContainerSearchItem* item);
+ WARP_FFI_API BNWARPFunction* BNWARPContainerSearchItemGetFunction(BNWARPContainerSearchItem* item);
+
+ WARP_FFI_API BNWARPContainerSearchQuery* BNWARPNewContainerSearchQueryReference(BNWARPContainerSearchQuery* query);
+ WARP_FFI_API void BNWARPFreeContainerSearchQueryReference(BNWARPContainerSearchQuery* query);
+
+ WARP_FFI_API BNWARPContainerSearchItem* BNWARPNewContainerSearchItemReference(BNWARPContainerSearchItem* item);
+ WARP_FFI_API void BNWARPFreeContainerSearchItemReference(BNWARPContainerSearchItem* item);
+ WARP_FFI_API void BNWARPFreeContainerSearchItemList(BNWARPContainerSearchItem** items, size_t count);
+
+ WARP_FFI_API void BNWARPFreeContainerSearchResponse(BNWARPContainerSearchResponse* response);
+
WARP_FFI_API void BNWARPFunctionApply(BNWARPFunction* function, BNFunction* analysisFunction);
WARP_FFI_API BNWARPFunctionGUID BNWARPFunctionGetGUID(BNWARPFunction* function);
WARP_FFI_API BNSymbol* BNWARPFunctionGetSymbol(BNWARPFunction* function, BNFunction* analysisFunction);