summaryrefslogtreecommitdiff
path: root/rust/src
diff options
context:
space:
mode:
authorFabian Freyer <fabian.freyer@physik.tu-berlin.de>2022-01-31 02:07:34 +0100
committerKyle Martin <krm504@nyu.edu>2022-02-08 16:30:16 -0500
commit1ea29a230051c2413120e0436bd9dd339dd1c2f5 (patch)
tree6dd340b6a22f59694fef347d410c03eace8334ef /rust/src
parent07311129ef2e9407b281fd5048d1a238a4689a73 (diff)
rust: Add tags and tag types to the API
This is missing all the things that iterate over tag types for now.
Diffstat (limited to 'rust/src')
-rw-r--r--rust/src/binaryview.rs114
-rw-r--r--rust/src/lib.rs1
-rw-r--r--rust/src/tags.rs167
3 files changed, 282 insertions, 0 deletions
diff --git a/rust/src/binaryview.rs b/rust/src/binaryview.rs
index 17a2570c..15f3030c 100644
--- a/rust/src/binaryview.rs
+++ b/rust/src/binaryview.rs
@@ -34,6 +34,7 @@ use crate::section::{Section, SectionBuilder};
use crate::segment::{Segment, SegmentBuilder};
use crate::settings::Settings;
use crate::symbol::{Symbol, SymbolType};
+use crate::tags::{Tag, TagType};
use crate::types::{DataVariable, QualifiedName, Type};
use crate::Endianness;
@@ -667,6 +668,119 @@ pub trait BinaryViewExt: BinaryViewBase {
)
};
}
+
+ /// Creates a new [TagType] and adds it to the view.
+ ///
+ /// # Arguments
+ /// * `name` - the name for the tag
+ /// * `icon` - the icon (recommended 1 emoji or 2 chars) for the tag
+ fn create_tag_type<N: BnStrCompatible, I: BnStrCompatible>(
+ &self,
+ name: N,
+ icon: I,
+ ) -> Ref<TagType> {
+ let tag_type = TagType::create(self.as_ref());
+ tag_type.set_name(name);
+ tag_type.set_icon(icon);
+ unsafe {
+ BNAddTagType(self.as_ref().handle, tag_type.handle);
+ }
+ tag_type
+ }
+
+ /// Removes a [TagType] and all tags that use it
+ fn remove_tag_type(&self, tag_type: &TagType) {
+ unsafe { BNRemoveTagType(self.as_ref().handle, tag_type.handle) }
+ }
+
+ /// Get a tag type by its name.
+ ///
+ /// Shorthand for [get_tag_type_by_name].
+ fn get_tag_type<S: BnStrCompatible>(&self, name: S) -> Option<Ref<TagType>> {
+ self.get_tag_type_by_name(name)
+ }
+
+ /// Get a tag type by its name
+ fn get_tag_type_by_name<S: BnStrCompatible>(&self, name: S) -> Option<Ref<TagType>> {
+ let name = name.as_bytes_with_nul();
+
+ unsafe {
+ let handle = BNGetTagType(self.as_ref().handle, name.as_ref().as_ptr() as *mut _);
+ if handle.is_null() {
+ return None;
+ }
+ Some(TagType::from_raw(handle))
+ }
+ }
+
+ /// Get a tag type by its id
+ fn get_tag_type_by_id<S: BnStrCompatible>(&self, id: S) -> Option<Ref<TagType>> {
+ let id = id.as_bytes_with_nul();
+
+ unsafe {
+ let handle = BNGetTagTypeById(self.as_ref().handle, id.as_ref().as_ptr() as *mut _);
+ if handle.is_null() {
+ return None;
+ }
+ Some(TagType::from_raw(handle))
+ }
+ }
+
+ fn create_tag<S: BnStrCompatible>(
+ &self,
+ t: &TagType,
+ data: S,
+ user: bool,
+ ) -> Ref<Tag> {
+ let tag = Tag::new(t, data);
+ unsafe { BNAddTag(self.as_ref().handle, tag.handle, user) }
+ tag
+ }
+
+ fn create_user_tag<S: BnStrCompatible>(&self, t: &TagType, data: S) -> Ref<Tag> {
+ self.create_tag(t, data, true)
+ }
+
+ fn create_auto_tag<S: BnStrCompatible>(&self, t: &TagType, data: S) -> Ref<Tag> {
+ self.create_tag(t, data, false)
+ }
+
+ /// Get a tag by its id.
+ ///
+ /// Note this does not tell you anything about where it is used.
+ fn get_tag<S: BnStrCompatible>(&self, id: S) -> Option<Ref<Tag>> {
+ let id = id.as_bytes_with_nul();
+ unsafe {
+ let handle = BNGetTag(self.as_ref().handle, id.as_ref().as_ptr() as *mut _);
+ if handle.is_null() {
+ return None;
+ }
+ Some(Tag::from_raw(handle))
+ }
+ }
+
+ /// adds an already-created Tag object at a data address.
+ ///
+ /// Since this adds a user tag, it will be added to the current undo buffer.
+ fn add_user_data_tag(&self, addr: u64, tag: &Tag) {
+ unsafe { BNAddUserDataTag(self.as_ref().handle, addr, tag.handle) }
+ }
+
+ /// adds an already-created Tag object at a data address.
+ fn add_auto_data_tag(&self, addr: u64, tag: &Tag) {
+ unsafe { BNAddAutoDataTag(self.as_ref().handle, addr, tag.handle) }
+ }
+
+ /// removes a Tag object at a data address.
+ fn remove_auto_data_tag(&self, addr: u64, tag: &Tag) {
+ unsafe { BNRemoveAutoDataTag(self.as_ref().handle, addr, tag.handle) }
+ }
+
+ /// removes a Tag object at a data address.
+ /// Since this removes a user tag, it will be added to the current undo buffer.
+ fn remove_user_data_tag(&self, addr: u64, tag: &Tag) {
+ unsafe { BNRemoveUserDataTag(self.as_ref().handle, addr, tag.handle) }
+ }
}
impl<T: BinaryViewBase> BinaryViewExt for T {}
diff --git a/rust/src/lib.rs b/rust/src/lib.rs
index 9965859b..6555e947 100644
--- a/rust/src/lib.rs
+++ b/rust/src/lib.rs
@@ -61,6 +61,7 @@ pub mod segment;
pub mod settings;
pub mod string;
pub mod symbol;
+pub mod tags;
pub mod types;
use std::collections::HashMap;
diff --git a/rust/src/tags.rs b/rust/src/tags.rs
new file mode 100644
index 00000000..eddcc5f0
--- /dev/null
+++ b/rust/src/tags.rs
@@ -0,0 +1,167 @@
+use binaryninjacore_sys::*;
+
+use crate::binaryview::BinaryView;
+
+use crate::rc::*;
+use crate::string::*;
+
+pub struct Tag {
+ pub(crate) handle: *mut BNTag,
+}
+
+impl Tag {
+ pub(crate) unsafe fn from_raw(handle: *mut BNTag) -> Ref<Self> {
+ debug_assert!(!handle.is_null());
+
+ Ref::new(Self { handle })
+ }
+
+ pub fn new<S: BnStrCompatible>(t: &TagType, data: S) -> Ref<Self> {
+ let data = data.as_bytes_with_nul();
+ unsafe { Self::from_raw(BNCreateTag(t.handle, data.as_ref().as_ptr() as *mut _)) }
+ }
+
+ pub fn id(&self) -> BnString {
+ unsafe { BnString::from_raw(BNTagGetId(self.handle)) }
+ }
+
+ pub fn data(&self) -> BnString {
+ unsafe { BnString::from_raw(BNTagGetData(self.handle)) }
+ }
+
+ pub fn t(&self) -> Ref<TagType> {
+ unsafe { TagType::from_raw(BNTagGetType(self.handle)) }
+ }
+
+ pub fn set_data<S: BnStrCompatible>(&self, data: S) {
+ let data = data.as_bytes_with_nul();
+ unsafe {
+ BNTagSetData(self.handle, data.as_ref().as_ptr() as *mut _);
+ }
+ }
+}
+
+unsafe impl RefCountable for Tag {
+ unsafe fn inc_ref(handle: &Self) -> Ref<Self> {
+ Ref::new(Self {
+ handle: BNNewTagReference(handle.handle),
+ })
+ }
+
+ unsafe fn dec_ref(handle: &Self) {
+ BNFreeTag(handle.handle);
+ }
+}
+
+impl AsRef<Tag> for Tag {
+ fn as_ref(&self) -> &Self {
+ self
+ }
+}
+
+impl ToOwned for Tag {
+ type Owned = Ref<Self>;
+
+ fn to_owned(&self) -> Self::Owned {
+ unsafe { RefCountable::inc_ref(self) }
+ }
+}
+
+unsafe impl Send for Tag {}
+unsafe impl Sync for Tag {}
+
+pub type TagTypeType = BNTagTypeType;
+
+pub struct TagType {
+ pub(crate) handle: *mut BNTagType,
+}
+
+impl TagType {
+ pub(crate) unsafe fn from_raw(handle: *mut BNTagType) -> Ref<Self> {
+ debug_assert!(!handle.is_null());
+
+ Ref::new(Self { handle })
+ }
+
+ pub(crate) fn create(view: &BinaryView) -> Ref<Self> {
+ unsafe { Self::from_raw(BNCreateTagType(view.handle)) }
+ }
+
+ pub fn id(&self) -> BnString {
+ unsafe { BnString::from_raw(BNTagTypeGetId(self.handle)) }
+ }
+
+ pub fn icon(&self) -> BnString {
+ unsafe { BnString::from_raw(BNTagTypeGetIcon(self.handle)) }
+ }
+
+ pub fn set_icon<S: BnStrCompatible>(&self, icon: S) {
+ let icon = icon.as_bytes_with_nul();
+ unsafe {
+ BNTagTypeSetName(self.handle, icon.as_ref().as_ptr() as *mut _);
+ }
+ }
+
+ pub fn name(&self) -> BnString {
+ unsafe { BnString::from_raw(BNTagTypeGetName(self.handle)) }
+ }
+
+ pub fn set_name<S: BnStrCompatible>(&self, name: S) {
+ let name = name.as_bytes_with_nul();
+ unsafe {
+ BNTagTypeSetName(self.handle, name.as_ref().as_ptr() as *mut _);
+ }
+ }
+
+ pub fn visible(&self) -> bool {
+ unsafe { BNTagTypeGetVisible(self.handle) }
+ }
+
+ pub fn set_visible(&self, visible: bool) {
+ unsafe { BNTagTypeSetVisible(self.handle, visible) }
+ }
+
+ pub fn t(&self) -> TagTypeType {
+ unsafe { BNTagTypeGetType(self.handle) }
+ }
+
+ pub fn set_type<S: BnStrCompatible>(&self, t: S) {
+ let t = t.as_bytes_with_nul();
+ unsafe {
+ BNTagTypeSetName(self.handle, t.as_ref().as_ptr() as *mut _);
+ }
+ }
+
+ pub fn view(&self) -> Ref<BinaryView> {
+ unsafe { BinaryView::from_raw(BNTagTypeGetView(self.handle)) }
+ }
+}
+
+unsafe impl RefCountable for TagType {
+ unsafe fn inc_ref(handle: &Self) -> Ref<Self> {
+ Ref::new(Self {
+ handle: BNNewTagTypeReference(handle.handle),
+ })
+ }
+
+ unsafe fn dec_ref(handle: &Self) {
+ BNFreeTagType(handle.handle);
+ }
+}
+
+impl AsRef<TagType> for TagType {
+ fn as_ref(&self) -> &Self {
+ self
+ }
+}
+
+impl ToOwned for TagType {
+ type Owned = Ref<Self>;
+
+ fn to_owned(&self) -> Self::Owned {
+ unsafe { RefCountable::inc_ref(self) }
+ }
+}
+
+unsafe impl Send for TagType {}
+unsafe impl Sync for TagType {}