summaryrefslogtreecommitdiff
path: root/plugins/warp/api
diff options
context:
space:
mode:
authorMason Reed <mason@vector35.com>2026-03-13 12:24:18 -0700
committerMason Reed <35282038+emesare@users.noreply.github.com>2026-03-24 18:46:48 -0700
commit3c88b11e5df33116580ac008e36092775df66135 (patch)
treecd64fbe149f05683ddabcccd0db7b87356f1f8cf /plugins/warp/api
parentf325aa7b6026a1daef84931baeb1f50d7da10c10 (diff)
[WARP] Improved UX and API
- Exposes WARP type objects directly - Adds processor API (for generating warp files directly) - Adds file and chunk API - Misc cleanup - Simplified the amount of commands - Replaced the "Create" commands with a purpose built processor dialog - Added a native QT viewer for WARP files - Simplified committing to a remote with a purpose built commit dialog
Diffstat (limited to 'plugins/warp/api')
-rw-r--r--plugins/warp/api/python/generator.cpp5
-rw-r--r--plugins/warp/api/python/warp.py176
-rw-r--r--plugins/warp/api/python/warp_enums.py13
-rw-r--r--plugins/warp/api/warp.cpp210
-rw-r--r--plugins/warp/api/warp.h92
-rw-r--r--plugins/warp/api/warpcore.h82
6 files changed, 525 insertions, 53 deletions
diff --git a/plugins/warp/api/python/generator.cpp b/plugins/warp/api/python/generator.cpp
index 0fd231fe..9e72c2ec 100644
--- a/plugins/warp/api/python/generator.cpp
+++ b/plugins/warp/api/python/generator.cpp
@@ -321,6 +321,11 @@ int main(int argc, char* argv[])
fprintf(out, "from binaryninja._binaryninjacore import BNType, BNTypeHandle\n");
continue;
}
+ if (name == "BNDataBuffer")
+ {
+ fprintf(out, "from binaryninja._binaryninjacore import BNDataBuffer, BNDataBufferHandle\n");
+ continue;
+ }
if (i.second->GetClass() == StructureTypeClass)
{
fprintf(out, "class %s(ctypes.Structure):\n", name.c_str());
diff --git a/plugins/warp/api/python/warp.py b/plugins/warp/api/python/warp.py
index 2ba1c681..b10b2c09 100644
--- a/plugins/warp/api/python/warp.py
+++ b/plugins/warp/api/python/warp.py
@@ -4,11 +4,11 @@ import uuid
from typing import List, Optional, Union
import binaryninja
-from binaryninja import BinaryView, Function, BasicBlock, Architecture, Platform, Type, Symbol, LowLevelILInstruction, LowLevelILFunction
+from binaryninja import BinaryView, Function, BasicBlock, Architecture, Platform, Type, Symbol, LowLevelILInstruction, LowLevelILFunction, DataBuffer, Project, ProjectFile
from binaryninja._binaryninjacore import BNFreeString, BNAllocString, BNType
from . import _warpcore as warpcore
-from .warp_enums import WARPContainerSearchItemKind
+from .warp_enums import WARPContainerSearchItemKind, WARPProcessorIncludedData, WARPProcessorIncludedFunctions
class WarpUUID:
@@ -74,6 +74,30 @@ class TypeGUID(WarpUUID):
return f"<TypeGUID '{str(self)}'>"
+class WarpType:
+ def __init__(self, handle: warpcore.BNWARPType):
+ self.handle = handle
+
+ def __del__(self):
+ if self.handle is not None:
+ warpcore.BNWARPFreeTypeReference(self.handle)
+
+ def __repr__(self):
+ return f"<WarpType name: '{self.name}' confidence: '{self.confidence}'>"
+
+ @property
+ def name(self) -> str:
+ return warpcore.BNWARPTypeGetName(self.handle)
+
+ @property
+ def confidence(self) -> int:
+ return warpcore.BNWARPTypeGetConfidence(self.handle)
+
+ def analysis_type(self, arch: Optional[Architecture] = None) -> Type:
+ if arch is None:
+ return Type.create(handle=warpcore.BNWARPTypeGetAnalysisType(None, self.handle))
+ return Type.create(handle=warpcore.BNWARPTypeGetAnalysisType(arch.handle, self.handle))
+
@dataclasses.dataclass
class WarpFunctionComment:
text: str
@@ -155,11 +179,12 @@ class WarpFunction:
symbol_handle = warpcore.BNWARPFunctionGetSymbol(self.handle, function.handle)
return Symbol(symbol_handle)
- def get_type(self, function: Function) -> Optional[Type]:
- type_handle = warpcore.BNWARPFunctionGetType(self.handle, function.handle)
+ @property
+ def type(self) -> Optional[WarpType]:
+ type_handle = warpcore.BNWARPFunctionGetType(self.handle)
if not type_handle:
return None
- return Type(type_handle)
+ return WarpType(type_handle)
@property
def constraints(self) -> List[WarpConstraint]:
@@ -259,11 +284,12 @@ class WarpContainerSearchItem:
def name(self) -> str:
return warpcore.BNWARPContainerSearchItemGetName(self.handle)
- def get_type(self, arch: Architecture) -> Optional[Type]:
- ty = warpcore.BNWARPContainerSearchItemGetType(arch.handle, self.handle)
+ @property
+ def type(self) -> Optional[WarpType]:
+ ty = warpcore.BNWARPContainerSearchItemGetType(self.handle)
if not ty:
return None
- return Type(ty)
+ return WarpType(ty)
@property
def function(self) -> Optional[WarpFunction]:
@@ -405,12 +431,12 @@ class WarpContainer(metaclass=_WarpContainerMetaclass):
core_funcs[i] = functions[i].handle
return warpcore.BNWARPContainerAddFunctions(self.handle, target.handle, source.uuid, core_funcs, count)
- def add_types(self, view: BinaryView, source: Source, types: List[Type]) -> bool:
+ def add_types(self, source: Source, types: List[WarpType]) -> bool:
count = len(types)
- core_types = (ctypes.POINTER(BNType) * count)()
+ core_types = (ctypes.POINTER(warpcore.BNWARPType) * count)()
for i in range(count):
core_types[i] = types[i].handle
- return warpcore.BNWARPContainerAddTypes(view.handle, self.handle, source.uuid, core_types, count)
+ return warpcore.BNWARPContainerAddTypes(self.handle, source.uuid, core_types, count)
def remove_functions(self, target: WarpTarget, source: Source, functions: List[Function]) -> bool:
count = len(functions)
@@ -479,11 +505,11 @@ class WarpContainer(metaclass=_WarpContainerMetaclass):
warpcore.BNWARPFreeFunctionList(funcs, count.value)
return result
- def get_type_with_guid(self, arch: Architecture, source: Source, guid: TypeGUID) -> Optional[Type]:
- ty = warpcore.BNWARPContainerGetTypeWithGUID(arch.handle, self.handle, source.uuid, guid.uuid)
+ def get_type_with_guid(self, source: Source, guid: TypeGUID) -> Optional[WarpType]:
+ ty = warpcore.BNWARPContainerGetTypeWithGUID(self.handle, source.uuid, guid.uuid)
if not ty:
return None
- return Type(ty)
+ return WarpType(ty)
def get_type_guids_with_name(self, source: Source, name: str) -> List[TypeGUID]:
count = ctypes.c_size_t()
@@ -503,6 +529,128 @@ class WarpContainer(metaclass=_WarpContainerMetaclass):
return WarpContainerResponse.from_api(response.contents)
+class WarpChunk:
+ def __init__(self, handle: warpcore.BNWARPChunk):
+ self.handle = handle
+
+ def __del__(self):
+ if self.handle is not None:
+ warpcore.BNWARPFreeChunkReference(self.handle)
+
+ def __repr__(self):
+ return f"<WarpChunk functions: '{len(self.functions)}' types: '{len(self.types)}'>"
+
+ @property
+ def functions(self) -> List[WarpFunction]:
+ count = ctypes.c_size_t()
+ funcs = warpcore.BNWARPChunkGetFunctions(self.handle, count)
+ if not funcs:
+ return []
+ result = []
+ for i in range(count.value):
+ result.append(WarpFunction(warpcore.BNWARPNewFunctionReference(funcs[i])))
+ warpcore.BNWARPFreeFunctionList(funcs, count.value)
+ return result
+
+ @property
+ def types(self) -> List[WarpType]:
+ count = ctypes.c_size_t()
+ types = warpcore.BNWARPChunkGetTypes(self.handle, count)
+ if not types:
+ return []
+ result = []
+ for i in range(count.value):
+ result.append(WarpType(warpcore.BNWARPNewTypeReference(types[i])))
+ warpcore.BNWARPFreeTypeList(types, count.value)
+ return result
+
+class WarpFile:
+ def __init__(self, handle: Union[warpcore.BNWARPFileHandle, str]):
+ if isinstance(handle, str):
+ self.handle = warpcore.BNWARPNewFileFromPath(handle)
+ else:
+ self.handle = handle
+
+ def __del__(self):
+ if self.handle is not None:
+ warpcore.BNWARPFreeFileReference(self.handle)
+
+ def __repr__(self):
+ return f"<WarpFile chunks: '{len(self.chunks)}'>"
+
+ @property
+ def chunks(self) -> List[WarpChunk]:
+ count = ctypes.c_size_t()
+ chunks = warpcore.BNWARPFileGetChunks(self.handle, count)
+ if not chunks:
+ return []
+ result = []
+ for i in range(count.value):
+ result.append(WarpChunk(warpcore.BNWARPNewChunkReference(chunks[i])))
+ warpcore.BNWARPFreeChunkList(chunks, count.value)
+ return result
+
+ def to_data_buffer(self) -> DataBuffer:
+ return DataBuffer(handle=warpcore.BNWARPFileToDataBuffer(self.handle))
+
+
+@dataclasses.dataclass
+class WarpProcessorState:
+ cancelled: bool = False
+ unprocessed_file_count: int = 0
+ processed_file_count: int = 0
+ analyzing_files: List[str] = dataclasses.field(default_factory=list)
+ processing_files: List[str] = dataclasses.field(default_factory=list)
+
+ @staticmethod
+ def from_api(state: warpcore.BNWARPProcessorState) -> 'WarpProcessorState':
+ analyzing_files = []
+ processing_files = []
+ for i in range(state.analyzing_files_count):
+ analyzing_files.append(state.analyzing_files[i])
+ for i in range(state.processing_files_count):
+ processing_files.append(state.processing_files[i])
+ return WarpProcessorState(
+ cancelled=state.cancelled,
+ unprocessed_file_count=state.unprocessed_file_count,
+ processed_file_count=state.processed_file_count,
+ analyzing_files=analyzing_files,
+ processing_files=processing_files
+ )
+
+class WarpProcessor:
+ def __init__(self, included_data: WARPProcessorIncludedData = WARPProcessorIncludedData.WARPProcessorIncludedDataAll,
+ included_functions: WARPProcessorIncludedFunctions = WARPProcessorIncludedFunctions.WARPProcessorIncludedFunctionsAnnotated,
+ worker_count: int = 1):
+ self.handle = warpcore.BNWARPNewProcessor(ctypes.c_int(included_data), ctypes.c_int(included_functions), worker_count)
+
+ def __del__(self):
+ if self.handle is not None:
+ warpcore.BNWARPFreeProcessor(self.handle)
+
+ def add_path(self, path: str):
+ warpcore.BNWARPProcessorAddPath(self.handle, path)
+
+ def add_project(self, project: Project):
+ warpcore.BNWARPProcessorAddProject(self.handle, project.handle)
+
+ def add_project_file(self, project_file: ProjectFile):
+ warpcore.BNWARPProcessorAddProjectFile(self.handle, project_file.handle)
+
+ def add_binary_view(self, view: BinaryView):
+ warpcore.BNWARPProcessorAddBinaryView(self.handle, view.handle)
+
+ def start(self) -> Optional[WarpFile]:
+ file = warpcore.BNWARPProcessorStart(self.handle)
+ if not file:
+ return None
+ return WarpFile(file)
+
+ def state(self) -> WarpProcessorState:
+ state_raw = warpcore.BNWARPProcessorGetState(self.handle)
+ warpcore.BNWARPFreeProcessorState(state_raw)
+ return WarpProcessorState.from_api(state_raw)
+
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 86be3a6c..d3f9f393 100644
--- a/plugins/warp/api/python/warp_enums.py
+++ b/plugins/warp/api/python/warp_enums.py
@@ -6,3 +6,16 @@ class WARPContainerSearchItemKind(enum.IntEnum):
WARPContainerSearchItemKindFunction = 1
WARPContainerSearchItemKindType = 2
WARPContainerSearchItemKindSymbol = 3
+
+
+class WARPProcessorIncludedData(enum.IntEnum):
+ WARPProcessorIncludedDataSymbols = 0
+ WARPProcessorIncludedDataSignatures = 1
+ WARPProcessorIncludedDataTypes = 2
+ WARPProcessorIncludedDataAll = 3
+
+
+class WARPProcessorIncludedFunctions(enum.IntEnum):
+ WARPProcessorIncludedFunctionsSelected = 0
+ WARPProcessorIncludedFunctionsAnnotated = 1
+ WARPProcessorIncludedFunctionsAll = 2
diff --git a/plugins/warp/api/warp.cpp b/plugins/warp/api/warp.cpp
index debbbc00..8c932602 100644
--- a/plugins/warp/api/warp.cpp
+++ b/plugins/warp/api/warp.cpp
@@ -34,6 +34,41 @@ Ref<Target> Target::FromPlatform(const BinaryNinja::Platform &platform)
return new Target(result);
}
+Type::Type(BNWARPType *type)
+{
+ m_object = type;
+}
+
+std::optional<std::string> Type::GetName() const
+{
+ char *name = BNWARPTypeGetName(m_object);
+ if (!name)
+ return std::nullopt;
+ std::string result = name;
+ BNFreeString(name);
+ return result;
+}
+
+uint8_t Type::GetConfidence() const
+{
+ return BNWARPTypeGetConfidence(m_object);
+}
+
+Ref<Type> Type::FromAnalysisType(const BinaryNinja::Type &type, uint8_t confidence)
+{
+ BNWARPType* ty = BNWARPGetType(type.m_object, confidence);
+ // TODO: Assert always should convert.
+ return new Type(ty);
+}
+
+BinaryNinja::Ref<BinaryNinja::Type> Type::GetAnalysisType(BinaryNinja::Architecture* arch) const
+{
+ BNType* ty = BNWARPTypeGetAnalysisType(arch ? arch->m_object : nullptr, m_object);
+ if (!ty)
+ return nullptr;
+ return new BinaryNinja::Type(ty);
+}
+
Constraint::Constraint(ConstraintGUID guid, std::optional<int64_t> offset)
{
this->guid = guid;
@@ -83,17 +118,17 @@ BinaryNinja::Ref<BinaryNinja::Symbol> Function::GetSymbol(const BinaryNinja::Fun
return new BinaryNinja::Symbol(symbol);
}
-BinaryNinja::Ref<BinaryNinja::Type> Function::GetType(const BinaryNinja::Function &function) const
+Ref<Type> Function::GetType() const
{
- BNType *type = BNWARPFunctionGetType(m_object, function.m_object);
+ BNWARPType *type = BNWARPFunctionGetType(m_object);
if (!type)
return nullptr;
- return new BinaryNinja::Type(type);
+ return new Type(type);
}
std::vector<Constraint> Function::GetConstraints() const
{
- size_t count;
+ size_t count = 0;
BNWARPConstraint *constraints = BNWARPFunctionGetConstraints(m_object, &count);
std::vector<Constraint> result;
result.reserve(count);
@@ -105,7 +140,7 @@ std::vector<Constraint> Function::GetConstraints() const
std::vector<FunctionComment> Function::GetComments() const
{
- size_t count;
+ size_t count = 0;
BNWARPFunctionComment *comments = BNWARPFunctionGetComments(m_object, &count);
std::vector<FunctionComment> result;
result.reserve(count);
@@ -184,12 +219,12 @@ Source ContainerSearchItem::GetSource() const
return BNWARPContainerSearchItemGetSource(m_object);
}
-BinaryNinja::Ref<BinaryNinja::Type> ContainerSearchItem::GetType(const BinaryNinja::Ref<BinaryNinja::Architecture> &arch) const
+Ref<Type> ContainerSearchItem::GetType() const
{
- BNType *type = BNWARPContainerSearchItemGetType(arch ? arch->m_object : nullptr, m_object);
+ BNWARPType *type = BNWARPContainerSearchItemGetType(m_object);
if (!type)
return nullptr;
- return new BinaryNinja::Type(type);
+ return new Type(type);
}
std::string ContainerSearchItem::GetName() const
@@ -236,7 +271,7 @@ Container::Container(BNWARPContainer *container)
std::vector<Ref<Container> > Container::All()
{
- size_t count;
+ size_t count = 0;
BNWARPContainer **containers = BNWARPGetContainers(&count);
std::vector<Ref<Container> > result;
result.reserve(count);
@@ -264,7 +299,7 @@ std::string Container::GetName() const
std::vector<Source> Container::GetSources() const
{
- size_t count;
+ size_t count = 0;
BNWARPSource *sources = BNWARPContainerGetSources(m_object, &count);
std::vector<Source> result;
result.reserve(count);
@@ -318,14 +353,13 @@ bool Container::AddFunctions(const Target &target, const Source &source, const s
return result;
}
-bool Container::AddTypes(const BinaryNinja::BinaryView &view, const Source &source,
- const std::vector<BinaryNinja::Ref<BinaryNinja::Type> > &types) const
+bool Container::AddTypes(const Source &source, const std::vector<Ref<Type>> &types) const
{
size_t count = types.size();
- BNType **apiTypes = new BNType *[count];
+ BNWARPType **apiTypes = new BNWARPType *[count];
for (size_t i = 0; i < count; i++)
apiTypes[i] = types[i]->m_object;
- const bool result = BNWARPContainerAddTypes(view.m_object, m_object, source.Raw(), apiTypes, count);
+ const bool result = BNWARPContainerAddTypes(m_object, source.Raw(), apiTypes, count);
delete[] apiTypes;
return result;
}
@@ -375,7 +409,7 @@ void Container::FetchFunctions(const Target &target, const std::vector<FunctionG
std::vector<Source> Container::GetSourcesWithFunctionGUID(const Target& target, const FunctionGUID &guid) const
{
- size_t count;
+ size_t count = 0;
BNWARPSource *sources = BNWARPContainerGetSourcesWithFunctionGUID(m_object, target.m_object, guid.Raw(), &count);
std::vector<Source> result;
result.reserve(count);
@@ -387,7 +421,7 @@ std::vector<Source> Container::GetSourcesWithFunctionGUID(const Target& target,
std::vector<Source> Container::GetSourcesWithTypeGUID(const TypeGUID &guid) const
{
- size_t count;
+ size_t count = 0;
BNWARPSource *sources = BNWARPContainerGetSourcesWithTypeGUID(m_object, guid.Raw(), &count);
std::vector<Source> result;
result.reserve(count);
@@ -399,7 +433,7 @@ std::vector<Source> Container::GetSourcesWithTypeGUID(const TypeGUID &guid) cons
std::vector<Ref<Function> > Container::GetFunctionsWithGUID(const Target& target, const Source &source, const FunctionGUID &guid) const
{
- size_t count;
+ size_t count = 0;
BNWARPFunction **functions = BNWARPContainerGetFunctionsWithGUID(m_object, target.m_object, source.Raw(), guid.Raw(), &count);
std::vector<Ref<Function> > result;
result.reserve(count);
@@ -409,16 +443,15 @@ std::vector<Ref<Function> > Container::GetFunctionsWithGUID(const Target& target
return result;
}
-BinaryNinja::Ref<BinaryNinja::Type> Container::GetTypeWithGUID(const BinaryNinja::Architecture &arch,
- const Source &source, const TypeGUID &guid) const
+Ref<Type> Container::GetTypeWithGUID(const Source &source, const TypeGUID &guid) const
{
- BNType *type = BNWARPContainerGetTypeWithGUID(arch.m_object, m_object, source.Raw(), guid.Raw());
- return new BinaryNinja::Type(type);
+ BNWARPType *type = BNWARPContainerGetTypeWithGUID(m_object, source.Raw(), guid.Raw());
+ return new Type(type);
}
std::vector<TypeGUID> Container::GetTypeGUIDsWithName(const Source &source, const std::string &name) const
{
- size_t count;
+ size_t count = 0;
BNWARPTypeGUID *guids = BNWARPContainerGetTypeGUIDsWithName(m_object, source.Raw(), name.c_str(), &count);
std::vector<TypeGUID> result;
result.reserve(count);
@@ -436,6 +469,139 @@ std::optional<ContainerSearchResponse> Container::Search(const ContainerSearchQu
return ContainerSearchResponse::FromAPIObject(response);
}
+Chunk::Chunk(BNWARPChunk *chunk)
+{
+ m_object = chunk;
+}
+
+Ref<Target> Chunk::GetTarget() const
+{
+ BNWARPTarget *target = BNWARPChunkGetTarget(m_object);
+ if (!target)
+ return nullptr;
+ return new Target(target);
+}
+
+std::vector<Ref<Function>> Chunk::GetFunctions() const
+{
+ size_t count = 0;
+ BNWARPFunction** functions = BNWARPChunkGetFunctions(m_object, &count);
+ std::vector<Ref<Function>> result;
+ result.reserve(count);
+ for (size_t i = 0; i < count; i++)
+ result.push_back(new Function(BNWARPNewFunctionReference(functions[i])));
+ BNWARPFreeFunctionList(functions, count);
+ return result;
+}
+
+std::vector<Ref<Type>> Chunk::GetTypes() const
+{
+ size_t count = 0;
+ BNWARPType** types = BNWARPChunkGetTypes(m_object, &count);
+ std::vector<Ref<Type>> result;
+ result.reserve(count);
+ for (size_t i = 0; i < count; i++)
+ result.push_back(new Type(BNWARPNewTypeReference(types[i])));
+ BNWARPFreeTypeList(types, count);
+ return result;
+}
+
+File::File(BNWARPFile *file)
+{
+ m_object = file;
+}
+
+Ref<File> File::FromPath(const std::string &path)
+{
+ BNWARPFile *result = BNWARPNewFileFromPath(path.c_str());
+ if (!result)
+ return nullptr;
+ return new File(result);
+}
+
+std::vector<Ref<Chunk>> File::GetChunks() const
+{
+ size_t count = 0;
+ BNWARPChunk **chunks = BNWARPFileGetChunks(m_object, &count);
+ std::vector<Ref<Chunk>> result;
+ result.reserve(count);
+ for (int i = 0; i < count; i++)
+ result.push_back(new Chunk(BNWARPNewChunkReference(chunks[i])));
+ BNWARPFreeChunkList(chunks, count);
+ return result;
+}
+
+BinaryNinja::DataBuffer File::ToDataBuffer() const
+{
+ return BinaryNinja::DataBuffer(BNWARPFileToDataBuffer(m_object));
+}
+
+ProcessorState ProcessorState::FromAPIObject(BNWARPProcessorState *state)
+{
+ ProcessorState result;
+ result.cancelled = state->cancelled;
+ result.unprocessedFilesCount = state->unprocessedFilesCount;
+ result.processedFilesCount = state->processedFilesCount;
+ result.analyzingFiles.reserve(state->analyzingFilesCount);
+ for (size_t i = 0; i < state->analyzingFilesCount; ++i)
+ result.analyzingFiles.emplace_back(state->analyzingFiles[i]);
+ result.processingFiles.reserve(state->processingFilesCount);
+ for (size_t i = 0; i < state->processingFilesCount; ++i)
+ result.processingFiles.emplace_back(state->processingFiles[i]);
+ return result;
+}
+
+Processor::Processor(BNWARPProcessorIncludedData includedData, BNWARPProcessorIncludedFunctions includedFunctions, size_t workerCount)
+{
+ m_object = BNWARPNewProcessor(includedData, includedFunctions, workerCount);
+}
+
+Processor::~Processor()
+{
+ BNWARPFreeProcessor(m_object);
+}
+
+void Processor::AddPath(const std::string &path) const
+{
+ BNWARPProcessorAddPath(m_object, path.c_str());
+}
+
+void Processor::AddProject(const BinaryNinja::Project &project) const
+{
+ BNWARPProcessorAddProject(m_object, project.m_object);
+}
+
+void Processor::AddProjectFile(const BinaryNinja::ProjectFile &projectFile) const
+{
+ BNWARPProcessorAddProjectFile(m_object, projectFile.m_object);
+}
+
+void Processor::AddBinaryView(const BinaryNinja::BinaryView &view) const
+{
+ BNWARPProcessorAddBinaryView(m_object, view.m_object);
+}
+
+Ref<File> Processor::Start() const
+{
+ BNWARPFile* file = BNWARPProcessorStart(m_object);
+ if (!file)
+ return nullptr;
+ return new File(file);
+}
+
+void Processor::Cancel() const
+{
+ BNWARPProcessorCancel(m_object);
+}
+
+ProcessorState Processor::GetState() const
+{
+ BNWARPProcessorState stateRaw = BNWARPProcessorGetState(m_object);
+ ProcessorState state = ProcessorState::FromAPIObject(&stateRaw);
+ BNWARPFreeProcessorState(stateRaw);
+ return state;
+}
+
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 ccb4da97..42e8ac70 100644
--- a/plugins/warp/api/warp.h
+++ b/plugins/warp/api/warp.h
@@ -276,9 +276,23 @@ namespace Warp {
static Ref<Target> FromPlatform(const BinaryNinja::Platform &platform);
};
+ class Type : public WarpRefCountObject<BNWARPType, BNWARPNewTypeReference,
+ BNWARPFreeTypeReference>
+ {
+ public:
+ explicit Type(BNWARPType *type);
+
+ [[nodiscard]] static Ref<Type> FromAnalysisType(const BinaryNinja::Type &type, uint8_t confidence);
+
+ std::optional<std::string> GetName() const;
+ uint8_t GetConfidence() const;
+
+ [[nodiscard]] BinaryNinja::Ref<BinaryNinja::Type> GetAnalysisType(BinaryNinja::Architecture* arch = nullptr) const;
+ };
+
struct Constraint
{
- ConstraintGUID guid;
+ ConstraintGUID guid {};
std::optional<int64_t> offset;
Constraint(ConstraintGUID guid, std::optional<int64_t> offset);
@@ -312,7 +326,7 @@ namespace Warp {
BinaryNinja::Ref<BinaryNinja::Symbol> GetSymbol(const BinaryNinja::Function &function) const;
- BinaryNinja::Ref<BinaryNinja::Type> GetType(const BinaryNinja::Function &function) const;
+ Ref<Type> GetType() const;
std::vector<Constraint> GetConstraints() const;
@@ -354,7 +368,7 @@ namespace Warp {
Source GetSource() const;
- BinaryNinja::Ref<BinaryNinja::Type> GetType(const BinaryNinja::Ref<BinaryNinja::Architecture> &arch) const;
+ Ref<Type> GetType() const;
std::string GetName() const;
@@ -363,7 +377,7 @@ namespace Warp {
struct ContainerSearchResponse
{
- std::vector<Ref<ContainerSearchItem> > items;
+ std::vector<Ref<ContainerSearchItem>> items;
size_t offset;
size_t total;
@@ -379,7 +393,7 @@ namespace Warp {
explicit Container(BNWARPContainer *container);
/// Retrieve all available containers.
- static std::vector<Ref<Container> > All();
+ static std::vector<Ref<Container>> All();
/// Add a new container with the given name.
static Ref<Container> Add(const std::string &name);
@@ -399,13 +413,12 @@ 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;
+ 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 AddTypes(const Source &source, const std::vector<Ref<Type>> &types) const;
bool RemoveFunctions(const Target &target, const Source &source,
- const std::vector<Ref<Function> > &functions) const;
+ const std::vector<Ref<Function>> &functions) const;
bool RemoveTypes(const Source &source, const std::vector<TypeGUID> &guids) const;
@@ -418,14 +431,71 @@ namespace Warp {
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;
+ Ref<Type> GetTypeWithGUID(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;
};
+ class Chunk : public WarpRefCountObject<BNWARPChunk, BNWARPNewChunkReference, BNWARPFreeChunkReference>
+ {
+ friend class File;
+
+ public:
+ explicit Chunk(BNWARPChunk *chunk);
+
+ Ref<Target> GetTarget() const;
+
+ [[nodiscard]] std::vector<Ref<Function>> GetFunctions() const;
+ [[nodiscard]] std::vector<Ref<Type>> GetTypes() const;
+ };
+
+ class File : public WarpRefCountObject<BNWARPFile, BNWARPNewFileReference, BNWARPFreeFileReference>
+ {
+ public:
+ explicit File(BNWARPFile *file);
+
+ static Ref<File> FromPath(const std::string &path);
+
+ [[nodiscard]] std::vector<Ref<Chunk>> GetChunks() const;
+ [[nodiscard]] BinaryNinja::DataBuffer ToDataBuffer() const;
+ };
+
+ class ProcessorState
+ {
+ public:
+ std::vector<std::string> analyzingFiles;
+ std::vector<std::string> processingFiles;
+ bool cancelled;
+ size_t unprocessedFilesCount;
+ size_t processedFilesCount;
+
+ ProcessorState() = default;
+
+ static ProcessorState FromAPIObject(BNWARPProcessorState *state);
+ };
+
+ class Processor
+ {
+ BNWARPProcessor* m_object;
+ public:
+ explicit Processor(BNWARPProcessorIncludedData includedData,
+ BNWARPProcessorIncludedFunctions includedFunctions, size_t workerCount);
+
+ ~Processor();
+
+ void AddPath(const std::string &path) const;
+ void AddProject(const BinaryNinja::Project &project) const;
+ void AddProjectFile(const BinaryNinja::ProjectFile &projectFile) const;
+ void AddBinaryView(const BinaryNinja::BinaryView &view) const;
+
+ Ref<File> Start() const;
+ void Cancel() const;
+
+ ProcessorState GetState() const;
+ };
+
void RunMatcher(const BinaryNinja::BinaryView &view);
bool IsInstructionVariant(const BinaryNinja::LowLevelILFunction &function, BinaryNinja::ExprId idx);
diff --git a/plugins/warp/api/warpcore.h b/plugins/warp/api/warpcore.h
index 21ef105b..c1762ae6 100644
--- a/plugins/warp/api/warpcore.h
+++ b/plugins/warp/api/warpcore.h
@@ -48,6 +48,9 @@ extern "C"
typedef struct BNFunction BNFunction;
typedef struct BNSymbol BNSymbol;
typedef struct BNType BNType;
+ typedef struct BNDataBuffer BNDataBuffer;
+ typedef struct BNProject BNProject;
+ typedef struct BNProjectFile BNProjectFile;
struct BNWARPUUID
{
@@ -71,20 +74,39 @@ extern "C"
typedef BNWARPUUID BNWARPFunctionGUID;
typedef BNWARPUUID BNWARPTypeGUID;
+ typedef struct BNWARPProcessor BNWARPProcessor;
+ typedef struct BNWARPFile BNWARPFile;
+ typedef struct BNWARPChunk BNWARPChunk;
typedef struct BNWARPTarget BNWARPTarget;
typedef struct BNWARPContainer BNWARPContainer;
typedef struct BNWARPFunction BNWARPFunction;
+ typedef struct BNWARPType BNWARPType;
typedef struct BNWARPConstraint BNWARPConstraint;
typedef struct BNWARPContainerSearchQuery BNWARPContainerSearchQuery;
typedef struct BNWARPContainerSearchItem BNWARPContainerSearchItem;
- enum BNWARPContainerSearchItemKind
+ typedef enum BNWARPProcessorIncludedData : uint8_t
+ {
+ WARPProcessorIncludedDataSymbols = 0,
+ WARPProcessorIncludedDataSignatures = 1,
+ WARPProcessorIncludedDataTypes = 2,
+ WARPProcessorIncludedDataAll = 3,
+ } BNWARPProcessorIncludedData;
+
+ typedef enum BNWARPProcessorIncludedFunctions : uint8_t
+ {
+ WARPProcessorIncludedFunctionsSelected = 0,
+ WARPProcessorIncludedFunctionsAnnotated = 1,
+ WARPProcessorIncludedFunctionsAll = 2,
+ } BNWARPProcessorIncludedFunctions;
+
+ typedef enum BNWARPContainerSearchItemKind
{
WARPContainerSearchItemKindSource = 0,
WARPContainerSearchItemKindFunction = 1,
WARPContainerSearchItemKindType = 2,
WARPContainerSearchItemKindSymbol = 3,
- };
+ } BNWARPContainerSearchItemKind;
struct BNWARPContainerSearchResponse
{
@@ -99,6 +121,28 @@ extern "C"
BNWARPConstraintGUID guid;
int64_t offset;
};
+
+ struct BNWARPProcessorState
+ {
+ bool cancelled;
+ size_t unprocessedFilesCount;
+ size_t processedFilesCount;
+ char** analyzingFiles;
+ size_t analyzingFilesCount;
+ char** processingFiles;
+ size_t processingFilesCount;
+ };
+
+ WARP_FFI_API BNWARPProcessor* BNWARPNewProcessor(BNWARPProcessorIncludedData includedData, BNWARPProcessorIncludedFunctions includedFunctions, size_t workerCount);
+ WARP_FFI_API void BNWARPProcessorAddPath(BNWARPProcessor* processor, const char* path);
+ WARP_FFI_API void BNWARPProcessorAddProject(BNWARPProcessor* processor, BNProject* project);
+ WARP_FFI_API void BNWARPProcessorAddProjectFile(BNWARPProcessor* processor, BNProjectFile* projectFile);
+ WARP_FFI_API void BNWARPProcessorAddBinaryView(BNWARPProcessor* processor, BNBinaryView* view);
+ WARP_FFI_API BNWARPFile* BNWARPProcessorStart(BNWARPProcessor* processor);
+ WARP_FFI_API void BNWARPProcessorCancel(BNWARPProcessor* processor);
+ WARP_FFI_API BNWARPProcessorState BNWARPProcessorGetState(BNWARPProcessor* processor);
+ WARP_FFI_API void BNWARPFreeProcessor(BNWARPProcessor* processor);
+ WARP_FFI_API void BNWARPFreeProcessorState(BNWARPProcessorState processorState);
WARP_FFI_API void BNWARPRunMatcher(BNBinaryView* view);
@@ -123,7 +167,7 @@ extern "C"
WARP_FFI_API char* BNWARPContainerGetSourcePath(BNWARPContainer* container, const BNWARPSource* source);
WARP_FFI_API bool BNWARPContainerAddFunctions(BNWARPContainer* container, const BNWARPTarget* target, const BNWARPSource* source, BNWARPFunction** functions, size_t count);
- WARP_FFI_API bool BNWARPContainerAddTypes(BNBinaryView* view, BNWARPContainer* container, const BNWARPSource* source, BNType** types, size_t count);
+ WARP_FFI_API bool BNWARPContainerAddTypes(BNWARPContainer* container, const BNWARPSource* source, BNWARPType** types, size_t count);
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);
@@ -133,7 +177,7 @@ extern "C"
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);
WARP_FFI_API BNWARPFunction** BNWARPContainerGetFunctionsWithGUID(BNWARPContainer* container, const BNWARPTarget* target, const BNWARPSource* source, const BNWARPFunctionGUID* guid, size_t* count);
- WARP_FFI_API BNType* BNWARPContainerGetTypeWithGUID(BNArchitecture* arch, BNWARPContainer* container, const BNWARPSource* source, const BNWARPTypeGUID* guid);
+ WARP_FFI_API BNWARPType* BNWARPContainerGetTypeWithGUID(BNWARPContainer* container, const BNWARPSource* source, const BNWARPTypeGUID* guid);
WARP_FFI_API BNWARPTypeGUID* BNWARPContainerGetTypeGUIDsWithName(BNWARPContainer* container, const BNWARPSource* source, const char* name, size_t* count);
WARP_FFI_API BNWARPContainer* BNWARPNewContainerReference(BNWARPContainer* container);
@@ -146,7 +190,7 @@ extern "C"
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 BNWARPType* BNWARPContainerSearchItemGetType(BNWARPContainerSearchItem* item);
WARP_FFI_API char* BNWARPContainerSearchItemGetName(BNWARPContainerSearchItem* item);
WARP_FFI_API BNWARPFunction* BNWARPContainerSearchItemGetFunction(BNWARPContainerSearchItem* item);
@@ -163,7 +207,7 @@ extern "C"
WARP_FFI_API BNWARPFunctionGUID BNWARPFunctionGetGUID(BNWARPFunction* function);
WARP_FFI_API BNSymbol* BNWARPFunctionGetSymbol(BNWARPFunction* function, BNFunction* analysisFunction);
WARP_FFI_API char* BNWARPFunctionGetSymbolName(BNWARPFunction* function);
- WARP_FFI_API BNType* BNWARPFunctionGetType(BNWARPFunction* function, BNFunction* analysisFunction);
+ WARP_FFI_API BNWARPType* BNWARPFunctionGetType(BNWARPFunction* function);
WARP_FFI_API BNWARPConstraint* BNWARPFunctionGetConstraints(BNWARPFunction* function, size_t* count);
WARP_FFI_API BNWARPFunctionComment* BNWARPFunctionGetComments(BNWARPFunction* function, size_t* count);
WARP_FFI_API bool BNWARPFunctionsEqual(BNWARPFunction* functionA, BNWARPFunction* functionB);
@@ -175,11 +219,37 @@ extern "C"
WARP_FFI_API void BNWARPFreeFunctionReference(BNWARPFunction* function);
WARP_FFI_API void BNWARPFreeFunctionList(BNWARPFunction** functions, size_t count);
+ WARP_FFI_API BNWARPType* BNWARPGetType(BNType* analysisType, uint8_t confidence);
+ WARP_FFI_API char* BNWARPTypeGetName(BNWARPType* ty);
+ WARP_FFI_API uint8_t BNWARPTypeGetConfidence(BNWARPType* ty);
+ WARP_FFI_API BNType* BNWARPTypeGetAnalysisType(BNArchitecture* arch, BNWARPType* ty);
+
+ WARP_FFI_API BNWARPType* BNWARPNewTypeReference(BNWARPType* ty);
+ WARP_FFI_API void BNWARPFreeTypeReference(BNWARPType* ty);
+
WARP_FFI_API BNWARPTarget* BNWARPGetTarget(BNPlatform* platform);
WARP_FFI_API BNWARPTarget* BNWARPNewTargetReference(BNWARPTarget* target);
WARP_FFI_API void BNWARPFreeTargetReference(BNWARPTarget* target);
+ WARP_FFI_API BNWARPFile* BNWARPNewFileFromPath(const char* path);
+
+ WARP_FFI_API BNWARPChunk** BNWARPFileGetChunks(BNWARPFile* file, size_t* count);
+ WARP_FFI_API BNDataBuffer* BNWARPFileToDataBuffer(BNWARPFile* file);
+
+ WARP_FFI_API BNWARPTarget* BNWARPChunkGetTarget(BNWARPChunk* chunk);
+ WARP_FFI_API BNWARPFunction** BNWARPChunkGetFunctions(BNWARPChunk* chunk, size_t* count);
+ WARP_FFI_API BNWARPType** BNWARPChunkGetTypes(BNWARPChunk* chunk, size_t* count);
+
+ WARP_FFI_API BNWARPFile* BNWARPNewFileReference(BNWARPFile* file);
+ WARP_FFI_API void BNWARPFreeFileReference(BNWARPFile* file);
+
+ WARP_FFI_API BNWARPChunk* BNWARPNewChunkReference(BNWARPChunk* chunk);
+ WARP_FFI_API void BNWARPFreeChunkReference(BNWARPChunk* chunk);
+
+ WARP_FFI_API void BNWARPFreeChunkList(BNWARPChunk** chunks, size_t count);
+ WARP_FFI_API void BNWARPFreeTypeList(BNWARPType** types, size_t count);
+
#ifdef __cplusplus
}
#endif