diff options
| author | Mason Reed <mason@vector35.com> | 2026-03-13 12:24:18 -0700 |
|---|---|---|
| committer | Mason Reed <35282038+emesare@users.noreply.github.com> | 2026-03-24 18:46:48 -0700 |
| commit | 3c88b11e5df33116580ac008e36092775df66135 (patch) | |
| tree | cd64fbe149f05683ddabcccd0db7b87356f1f8cf /plugins/warp/api | |
| parent | f325aa7b6026a1daef84931baeb1f50d7da10c10 (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.cpp | 5 | ||||
| -rw-r--r-- | plugins/warp/api/python/warp.py | 176 | ||||
| -rw-r--r-- | plugins/warp/api/python/warp_enums.py | 13 | ||||
| -rw-r--r-- | plugins/warp/api/warp.cpp | 210 | ||||
| -rw-r--r-- | plugins/warp/api/warp.h | 92 | ||||
| -rw-r--r-- | plugins/warp/api/warpcore.h | 82 |
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 |
