Skip to content

Commit 017349b

Browse files
authored
[WARP] Allow containers to be constructed programmatically (#7952)
1 parent e2e420c commit 017349b

6 files changed

Lines changed: 42 additions & 1 deletion

File tree

plugins/warp/api/python/warp.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,13 @@ def all() -> List['WarpContainer']:
350350
warpcore.BNWARPFreeContainerList(containers, count.value)
351351
return result
352352

353+
@staticmethod
354+
def add(name: str) -> 'WarpContainer':
355+
container = warpcore.BNWARPAddContainer(name)
356+
if container is None:
357+
raise ValueError(f"Failed to add container: {name}")
358+
return WarpContainer(container)
359+
353360
@staticmethod
354361
def by_name(name: str) -> Optional['WarpContainer']:
355362
for container in WarpContainer:

plugins/warp/api/warp.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,14 @@ std::vector<Ref<Container> > Container::All()
246246
return result;
247247
}
248248

249+
Ref<Container> Container::Add(const std::string &name)
250+
{
251+
BNWARPContainer *result = BNWARPAddContainer(name.c_str());
252+
if (!result)
253+
return nullptr;
254+
return new Container(result);
255+
}
256+
249257
std::string Container::GetName() const
250258
{
251259
char *rawName = BNWARPContainerGetName(m_object);

plugins/warp/api/warp.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,9 @@ namespace Warp {
381381
/// Retrieve all available containers.
382382
static std::vector<Ref<Container> > All();
383383

384+
/// Add a new container with the given name.
385+
static Ref<Container> Add(const std::string &name);
386+
384387
std::string GetName() const;
385388

386389
std::vector<Source> GetSources() const;

plugins/warp/api/warpcore.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ extern "C"
111111
WARP_FFI_API BNWARPFunction* BNWARPGetFunction(BNFunction* analysisFunction);
112112
WARP_FFI_API BNWARPFunction* BNWARPGetMatchedFunction(BNFunction* analysisFunction);
113113
WARP_FFI_API BNWARPContainer** BNWARPGetContainers(size_t* count);
114+
WARP_FFI_API BNWARPContainer* BNWARPAddContainer(const char* name);
114115

115116
WARP_FFI_API char* BNWARPContainerGetName(BNWARPContainer* container);
116117

plugins/warp/src/cache/container.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,8 @@ pub fn cached_containers() -> Vec<Arc<RwLock<Box<dyn Container>>>> {
3535
let containers_cache = CONTAINER_CACHE.get_or_init(Default::default);
3636
containers_cache.iter().map(|c| c.clone()).collect()
3737
}
38+
39+
pub fn cached_container_by_name(name: &str) -> Option<Arc<RwLock<Box<dyn Container>>>> {
40+
let containers_cache = CONTAINER_CACHE.get_or_init(Default::default);
41+
containers_cache.get(name).map(|c| c.clone())
42+
}

plugins/warp/src/plugin/ffi/container.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
use crate::cache::container::cached_containers;
1+
use crate::cache::container::{add_cached_container, cached_container_by_name, cached_containers};
2+
use crate::container::disk::DiskContainer;
23
use crate::container::{
34
ContainerSearchItem, ContainerSearchItemKind, ContainerSearchQuery, SourcePath, SourceTag,
45
};
@@ -12,6 +13,7 @@ use binaryninja::rc::Ref;
1213
use binaryninja::string::BnString;
1314
use binaryninja::types::Type;
1415
use binaryninjacore_sys::{BNArchitecture, BNBinaryView, BNType};
16+
use std::collections::HashMap;
1517
use std::ffi::{c_char, CStr};
1618
use std::mem::ManuallyDrop;
1719
use std::ops::Deref;
@@ -172,6 +174,21 @@ pub unsafe extern "C" fn BNWARPContainerSearchItemGetFunction(
172174
}
173175
}
174176

177+
#[no_mangle]
178+
pub unsafe extern "C" fn BNWARPAddContainer(name: *const c_char) -> *mut BNWARPContainer {
179+
let name_cstr = unsafe { CStr::from_ptr(name) };
180+
let name_str = name_cstr.to_str().unwrap();
181+
// TODO: Using this generic API name for disk container, I think anything like the network container
182+
// TODO: should probably be a second class name so something like BNWARPAddNetworkContainer.
183+
let disk_container = DiskContainer::new(name_str.to_string(), HashMap::new());
184+
let container_name = disk_container.to_string();
185+
add_cached_container(disk_container);
186+
match cached_container_by_name(&container_name) {
187+
Some(container) => Arc::into_raw(container) as *mut BNWARPContainer,
188+
None => std::ptr::null_mut(),
189+
}
190+
}
191+
175192
#[no_mangle]
176193
pub unsafe extern "C" fn BNWARPGetContainers(count: *mut usize) -> *mut *mut BNWARPContainer {
177194
// NOTE: Leak the arc pointers to be freed by BNWARPFreeContainerList

0 commit comments

Comments
 (0)