diff options
| author | Mason Reed <35282038+emesare@users.noreply.github.com> | 2026-02-22 20:40:28 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-02-22 20:40:28 -0800 |
| commit | 017349bdbe171c66974a5835f2f74f76138386ea (patch) | |
| tree | 2e81f92e683f4b1d12c129360c788e0e52217d82 /plugins/warp | |
| parent | e2e420c91147f2a83cf59b37c973f57e209ef67a (diff) | |
[WARP] Allow containers to be constructed programmatically (#7952)
Diffstat (limited to 'plugins/warp')
| -rw-r--r-- | plugins/warp/api/python/warp.py | 7 | ||||
| -rw-r--r-- | plugins/warp/api/warp.cpp | 8 | ||||
| -rw-r--r-- | plugins/warp/api/warp.h | 3 | ||||
| -rw-r--r-- | plugins/warp/api/warpcore.h | 1 | ||||
| -rw-r--r-- | plugins/warp/src/cache/container.rs | 5 | ||||
| -rw-r--r-- | plugins/warp/src/plugin/ffi/container.rs | 19 |
6 files changed, 42 insertions, 1 deletions
diff --git a/plugins/warp/api/python/warp.py b/plugins/warp/api/python/warp.py index fc487a4d..a699ebbc 100644 --- a/plugins/warp/api/python/warp.py +++ b/plugins/warp/api/python/warp.py @@ -351,6 +351,13 @@ class WarpContainer(metaclass=_WarpContainerMetaclass): return result @staticmethod + def add(name: str) -> 'WarpContainer': + container = warpcore.BNWARPAddContainer(name) + if container is None: + raise ValueError(f"Failed to add container: {name}") + return WarpContainer(container) + + @staticmethod def by_name(name: str) -> Optional['WarpContainer']: for container in WarpContainer: if container.name == name: diff --git a/plugins/warp/api/warp.cpp b/plugins/warp/api/warp.cpp index f6106605..c051e3c7 100644 --- a/plugins/warp/api/warp.cpp +++ b/plugins/warp/api/warp.cpp @@ -246,6 +246,14 @@ std::vector<Ref<Container> > Container::All() return result; } +Ref<Container> Container::Add(const std::string &name) +{ + BNWARPContainer *result = BNWARPAddContainer(name.c_str()); + if (!result) + return nullptr; + return new Container(result); +} + std::string Container::GetName() const { char *rawName = BNWARPContainerGetName(m_object); diff --git a/plugins/warp/api/warp.h b/plugins/warp/api/warp.h index 14be9a0d..01f4aaee 100644 --- a/plugins/warp/api/warp.h +++ b/plugins/warp/api/warp.h @@ -381,6 +381,9 @@ namespace Warp { /// Retrieve all available containers. static std::vector<Ref<Container> > All(); + /// Add a new container with the given name. + static Ref<Container> Add(const std::string &name); + std::string GetName() const; std::vector<Source> GetSources() const; diff --git a/plugins/warp/api/warpcore.h b/plugins/warp/api/warpcore.h index 633ffcbf..c52485aa 100644 --- a/plugins/warp/api/warpcore.h +++ b/plugins/warp/api/warpcore.h @@ -111,6 +111,7 @@ extern "C" WARP_FFI_API BNWARPFunction* BNWARPGetFunction(BNFunction* analysisFunction); WARP_FFI_API BNWARPFunction* BNWARPGetMatchedFunction(BNFunction* analysisFunction); WARP_FFI_API BNWARPContainer** BNWARPGetContainers(size_t* count); + WARP_FFI_API BNWARPContainer* BNWARPAddContainer(const char* name); WARP_FFI_API char* BNWARPContainerGetName(BNWARPContainer* container); diff --git a/plugins/warp/src/cache/container.rs b/plugins/warp/src/cache/container.rs index 0b478ed1..99746d9a 100644 --- a/plugins/warp/src/cache/container.rs +++ b/plugins/warp/src/cache/container.rs @@ -35,3 +35,8 @@ pub fn cached_containers() -> Vec<Arc<RwLock<Box<dyn Container>>>> { let containers_cache = CONTAINER_CACHE.get_or_init(Default::default); containers_cache.iter().map(|c| c.clone()).collect() } + +pub fn cached_container_by_name(name: &str) -> Option<Arc<RwLock<Box<dyn Container>>>> { + let containers_cache = CONTAINER_CACHE.get_or_init(Default::default); + containers_cache.get(name).map(|c| c.clone()) +} diff --git a/plugins/warp/src/plugin/ffi/container.rs b/plugins/warp/src/plugin/ffi/container.rs index 2376ef10..a107a785 100644 --- a/plugins/warp/src/plugin/ffi/container.rs +++ b/plugins/warp/src/plugin/ffi/container.rs @@ -1,4 +1,5 @@ -use crate::cache::container::cached_containers; +use crate::cache::container::{add_cached_container, cached_container_by_name, cached_containers}; +use crate::container::disk::DiskContainer; use crate::container::{ ContainerSearchItem, ContainerSearchItemKind, ContainerSearchQuery, SourcePath, SourceTag, }; @@ -12,6 +13,7 @@ use binaryninja::rc::Ref; use binaryninja::string::BnString; use binaryninja::types::Type; use binaryninjacore_sys::{BNArchitecture, BNBinaryView, BNType}; +use std::collections::HashMap; use std::ffi::{c_char, CStr}; use std::mem::ManuallyDrop; use std::ops::Deref; @@ -173,6 +175,21 @@ pub unsafe extern "C" fn BNWARPContainerSearchItemGetFunction( } #[no_mangle] +pub unsafe extern "C" fn BNWARPAddContainer(name: *const c_char) -> *mut BNWARPContainer { + let name_cstr = unsafe { CStr::from_ptr(name) }; + let name_str = name_cstr.to_str().unwrap(); + // TODO: Using this generic API name for disk container, I think anything like the network container + // TODO: should probably be a second class name so something like BNWARPAddNetworkContainer. + let disk_container = DiskContainer::new(name_str.to_string(), HashMap::new()); + let container_name = disk_container.to_string(); + add_cached_container(disk_container); + match cached_container_by_name(&container_name) { + Some(container) => Arc::into_raw(container) as *mut BNWARPContainer, + None => std::ptr::null_mut(), + } +} + +#[no_mangle] pub unsafe extern "C" fn BNWARPGetContainers(count: *mut usize) -> *mut *mut BNWARPContainer { // NOTE: Leak the arc pointers to be freed by BNWARPFreeContainerList let boxed_raw_containers: Box<[_]> = |
