diff --git a/rust/src/architecture.rs b/rust/src/architecture.rs index 0e1349e67..9aee0b163 100644 --- a/rust/src/architecture.rs +++ b/rust/src/architecture.rs @@ -296,7 +296,7 @@ pub trait FlagGroup: Sized + Clone + Copy { /// Types to represent the different comparisons, so for `cr1_lt` we /// would return a mapping along the lines of: /// - /// ``` + /// ```text /// cr1_signed -> LLFC_SLT, /// cr1_unsigned -> LLFC_ULT, /// ``` diff --git a/rust/src/binaryview.rs b/rust/src/binaryview.rs index 70b1cab0e..5a4e270b3 100644 --- a/rust/src/binaryview.rs +++ b/rust/src/binaryview.rs @@ -1553,7 +1553,7 @@ pub type BinaryViewEventType = BNBinaryViewEventType; /// /// # Example /// -/// ```rust +/// ```no_run /// use binaryninja::binaryview::{BinaryView, BinaryViewEventHandler, BinaryViewEventType, register_binary_view_event}; /// /// struct EventHandlerContext { @@ -1561,7 +1561,7 @@ pub type BinaryViewEventType = BNBinaryViewEventType; /// } /// /// impl BinaryViewEventHandler for EventHandlerContext { -/// fn on_event(&mut self, binary_view: &BinaryView) { +/// fn on_event(&self, binary_view: &BinaryView) { /// // handle event /// } /// } diff --git a/rust/src/command.rs b/rust/src/command.rs index f53327342..e682baeef 100644 --- a/rust/src/command.rs +++ b/rust/src/command.rs @@ -16,12 +16,16 @@ //! //! All plugins need to provide one of the following functions for Binary Ninja to call: //! -//! ```rust -//! pub extern "C" fn CorePluginInit() -> bool {} +//! ```no_run +//! pub extern "C" fn CorePluginInit() -> bool { +//! todo!(); +//! } //! ``` //! -//! ```rust -//! pub extern "C" fn UIPluginInit() -> bool {} +//! ```no_run +//! pub extern "C" fn UIPluginInit() -> bool { +//! todo!(); +//! } //! ``` //! //! Both of these functions can call any of the following registration functions, though `CorePluginInit` is called during Binary Ninja core initialization, and `UIPluginInit` is called during Binary Ninja UI initialization. @@ -62,7 +66,9 @@ where /// The function call required for generic commands; commands added in this way will be in the `Plugins` submenu of the menu bar. /// /// # Example -/// ```rust +/// ```no_run +/// # use binaryninja::command::Command; +/// # use binaryninja::binaryview::BinaryView; /// struct MyCommand; /// /// impl Command for MyCommand { @@ -76,6 +82,7 @@ where /// } /// } /// +/// # use binaryninja::command::register; /// #[no_mangle] /// pub extern "C" fn CorePluginInit() -> bool { /// register( @@ -160,7 +167,9 @@ where /// The function call required for generic commands; commands added in this way will be in the `Plugins` submenu of the menu bar. /// /// # Example -/// ```rust +/// ```no_run +/// # use binaryninja::command::AddressCommand; +/// # use binaryninja::binaryview::BinaryView; /// struct MyCommand; /// /// impl AddressCommand for MyCommand { @@ -174,6 +183,7 @@ where /// } /// } /// +/// # use binaryninja::command::register_for_address; /// #[no_mangle] /// pub extern "C" fn CorePluginInit() -> bool { /// register_for_address( @@ -258,10 +268,13 @@ where /// The function call required for generic commands; commands added in this way will be in the `Plugins` submenu of the menu bar. /// /// # Example -/// ```rust +/// ```no_run +/// # use std::ops::Range; +/// # use binaryninja::command::RangeCommand; +/// # use binaryninja::binaryview::BinaryView; /// struct MyCommand; /// -/// impl AddressCommand for MyCommand { +/// impl RangeCommand for MyCommand { /// fn action(&self, view: &BinaryView, range: Range) { /// // Your code here /// } @@ -272,6 +285,7 @@ where /// } /// } /// +/// # use binaryninja::command::register_for_range; /// #[no_mangle] /// pub extern "C" fn CorePluginInit() -> bool { /// register_for_range( @@ -361,10 +375,14 @@ where /// The function call required for generic commands; commands added in this way will be in the `Plugins` submenu of the menu bar. /// /// # Example -/// ```rust +/// ```no_run +/// # use binaryninja::command::FunctionCommand; +/// # use binaryninja::binaryview::BinaryView; +/// # use binaryninja::function::Function; +/// # use binaryninja::command::register_for_function; /// struct MyCommand; /// -/// impl AddressCommand for MyCommand { +/// impl FunctionCommand for MyCommand { /// fn action(&self, view: &BinaryView, func: &Function) { /// // Your code here /// } diff --git a/rust/src/debuginfo.rs b/rust/src/debuginfo.rs index d53faef3a..a09e0c674 100644 --- a/rust/src/debuginfo.rs +++ b/rust/src/debuginfo.rs @@ -27,7 +27,7 @@ //! And finally calling `binaryninja::debuginfo::DebugInfoParser::register` to register it with the core. //! //! Here's a minimal, complete example boilerplate-plugin: -//! ``` +//! ```no_run //! use binaryninja::{ //! binaryview::BinaryView, //! debuginfo::{CustomDebugInfoParser, DebugInfo, DebugInfoParser}, @@ -40,8 +40,9 @@ //! true //! } //! -//! fn parse_info(&self, _debug_info: &mut DebugInfo, _view: &BinaryView, _debug_file: &BinaryView, _progress: Box bool>) { +//! fn parse_info(&self, _debug_info: &mut DebugInfo, _view: &BinaryView, _debug_file: &BinaryView, _progress: Box Result<(), ()>>) -> bool { //! println!("Parsing info"); +//! true //! } //! } //! @@ -53,11 +54,14 @@ //! ``` //! //! `DebugInfo` will then be automatically applied to binary views that contain debug information (via the setting `analysis.debugInfo.internal`), binary views that provide valid external debug info files (`analysis.debugInfo.external`), or manually fetched/applied as below: -//! ``` -//! let valid_parsers = DebugInfoParser::parsers_for_view(bv); -//! let parser = valid_parsers[0]; -//! let debug_info = parser.parse_debug_info(bv); -//! bv.apply_debug_info(debug_info); +//! ```no_run +//! # use binaryninja::debuginfo::DebugInfoParser; +//! # use binaryninja::binaryview::BinaryViewExt; +//! let bv = binaryninja::load("example").unwrap(); +//! let valid_parsers = DebugInfoParser::parsers_for_view(&bv); +//! let parser = valid_parsers.get(0); +//! let debug_info = parser.parse_debug_info(&bv, &bv, None, None).unwrap(); +//! bv.apply_debug_info(&debug_info); //! ``` //! //! Multiple debug-info parsers can manually contribute debug info for a binary view by simply calling `parse_debug_info` with the @@ -277,6 +281,14 @@ unsafe impl CoreOwnedArrayProvider for DebugInfoParser { } } +unsafe impl<'a> CoreArrayWrapper<'a> for DebugInfoParser { + type Wrapped = Guard<'a, DebugInfoParser>; + + unsafe fn wrap_raw(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped { + Guard::new(DebugInfoParser { handle: *raw }, &()) + } +} + /////////////////////// // DebugFunctionInfo @@ -414,7 +426,10 @@ impl DebugInfo { } /// Returns a generator of all functions provided by a named DebugInfoParser - pub fn functions_by_name(&self, parser_name: S) -> Vec { + pub fn functions_by_name( + &self, + parser_name: S + ) -> Vec { let parser_name = parser_name.into_bytes_with_nul(); let mut count: usize = 0; diff --git a/rust/src/headless.rs b/rust/src/headless.rs index e4024d8e3..740c3dc63 100644 --- a/rust/src/headless.rs +++ b/rust/src/headless.rs @@ -101,12 +101,13 @@ pub fn shutdown() { } /// Prelued-postlued helper function (calls [`init`] and [`shutdown`] for you) -/// ```rust +/// ```no_run +/// # use binaryninja::binaryview::BinaryViewExt; /// binaryninja::headless::script_helper(|| { -/// binaryninja::load("/bin/cat") -/// .expect("Couldn't open `/bin/cat`") -/// .iter() -/// .for_each(|func| println!(" `{}`", func.symbol().full_name())); +/// let cat = binaryninja::load("/bin/cat").expect("Couldn't open `/bin/cat`"); +/// for function in cat.functions().iter() { +/// println!(" `{}`", function.symbol().full_name()); +/// } /// }); /// ``` pub fn script_helper(func: fn()) { @@ -124,7 +125,7 @@ impl Session { Self {} } - /// ```rust + /// ```no_run /// let headless_session = binaryninja::headless::Session::new(); /// /// let bv = headless_session.load("/bin/cat").expect("Couldn't open `/bin/cat`"); @@ -133,7 +134,7 @@ impl Session { crate::load(filename) } - /// ```rust + /// ```no_run /// let settings = [("analysis.linearSweep.autorun", false)].into(); /// let headless_session = binaryninja::headless::Session::new(); /// diff --git a/rust/src/interaction.rs b/rust/src/interaction.rs index 76fc92752..7d10bbe4a 100644 --- a/rust/src/interaction.rs +++ b/rust/src/interaction.rs @@ -451,8 +451,10 @@ impl FormInputBuilder { /// /// This API is flexible and works both in the UI via a pop-up dialog and on the command-line. /// - /// ``` - /// let responses = interaction::FormInputBuilder::new() + /// ```no_run + /// # use binaryninja::interaction::FormInputBuilder; + /// # use binaryninja::interaction::FormResponses; + /// let responses = FormInputBuilder::new() /// .text_field("First Name", None) /// .text_field("Last Name", None) /// .choice_field( @@ -469,15 +471,19 @@ impl FormInputBuilder { /// .get_form_input("Form Title"); /// /// let food = match responses[2] { - /// Index(0) => "Pizza", - /// Index(1) => "Also Pizza", - /// Index(2) => "Also Pizza", - /// Index(3) => "Wrong Answer", + /// FormResponses::Index(0) => "Pizza", + /// FormResponses::Index(1) => "Also Pizza", + /// FormResponses::Index(2) => "Also Pizza", + /// FormResponses::Index(3) => "Wrong Answer", /// _ => panic!("This person doesn't like pizza?!?"), /// }; /// - /// let interaction::FormResponses::String(last_name) = responses[0]; - /// let interaction::FormResponses::String(first_name) = responses[1]; + /// let FormResponses::String(last_name) = &responses[0] else { + /// unreachable!() + /// }; + /// let FormResponses::String(first_name) = &responses[1] else { + /// unreachable!() + /// }; /// /// println!("{} {} likes {}", &first_name, &last_name, food); /// ``` diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 739bfbf68..8a51a7d87 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -49,7 +49,7 @@ //! //! Create a new library (`cargo new --lib `) and include the following in your `Cargo.toml`: //! -//! ``` +//! ```toml //! [lib] //! crate-type = ["cdylib"] //! @@ -73,17 +73,19 @@ //! //! ### `main.rs` //! Standalone binaries need to initialize Binary Ninja before they can work. You can do this through [`headless::Session`], [`headless::script_helper`], or [`headless::init()`] at start and [`headless::shutdown()`] at shutdown. -//! ```rust +//! ```no_run //! // This loads all the core architecture, platform, etc plugins //! // Standalone executables need to call this, but plugins do not //! let headless_session = binaryninja::headless::Session::new(); //! //! println!("Loading binary..."); //! let bv = headless_session.load("/bin/cat").expect("Couldn't open `/bin/cat`"); +//! +//! // Your code here... //! ``` //! //! ### `Cargo.toml` -//! ``` +//! ```toml //! [dependencies] //! binaryninja = { git = "https://github.com/Vector35/binaryninja-api.git", branch = "dev"} //! ``` @@ -215,7 +217,7 @@ pub fn load(filename: S) -> Option(name: S, range: Range) -> SectionBuilder { SectionBuilder::new(name, range) diff --git a/rust/src/segment.rs b/rust/src/segment.rs index 32f9db3ab..6ba2fbadf 100644 --- a/rust/src/segment.rs +++ b/rust/src/segment.rs @@ -117,8 +117,11 @@ impl Segment { /// You need to create a segment builder, customize that segment, then add it to a binary view: /// - /// ``` - /// bv.add_segment(Segment::new().align(4).entry_size(4)) + /// ```no_run + /// # use binaryninja::segment::Segment; + /// # use binaryninja::binaryview::BinaryViewExt; + /// let bv = binaryninja::load("example").unwrap(); + /// bv.add_segment(Segment::builder(0..0x1000).writable(true).readable(true)) /// ``` pub fn builder(ea_range: Range) -> SegmentBuilder { SegmentBuilder::new(ea_range) diff --git a/rust/src/symbol.rs b/rust/src/symbol.rs index bdf0d8552..edb93b47d 100644 --- a/rust/src/symbol.rs +++ b/rust/src/symbol.rs @@ -231,8 +231,10 @@ impl Symbol { /// To create a new symbol, you need to create a symbol builder, customize that symbol, then add `SymbolBuilder::create` it into a `Ref`: /// - /// ``` - /// Symbol::new().short_name("hello").full_name("hello").create(); + /// ```no_run + /// # use binaryninja::symbol::Symbol; + /// # use binaryninja::symbol::SymbolType; + /// Symbol::builder(SymbolType::Data, "hello", 0x1337).short_name("hello").full_name("hello").create(); /// ``` pub fn builder(ty: SymbolType, raw_name: &str, addr: u64) -> SymbolBuilder { SymbolBuilder::new(ty, raw_name, addr) diff --git a/rust/src/types.rs b/rust/src/types.rs index 2e5723305..2b300444f 100644 --- a/rust/src/types.rs +++ b/rust/src/types.rs @@ -695,11 +695,12 @@ pub struct Type { pub(crate) handle: *mut BNType, } -/// ``` -/// use binaryninja::types::Type; -/// let bv = unsafe { BinaryView::from_raw(view) }; -/// let my_custom_type_1 = Self::named_int(5, false, "my_w"); -/// let my_custom_type_2 = Self::int(5, false); +/// ```no_run +/// # use crate::binaryninja::binaryview::BinaryViewExt; +/// # use binaryninja::types::Type; +/// let bv = binaryninja::load("example.bin").unwrap(); +/// let my_custom_type_1 = Type::named_int(5, false, "my_w"); +/// let my_custom_type_2 = Type::int(5, false); /// bv.define_user_type("int_1", &my_custom_type_1); /// bv.define_user_type("int_2", &my_custom_type_2); /// ``` @@ -1642,9 +1643,10 @@ pub struct StructureBuilder { pub(crate) handle: *mut BNStructureBuilder, } -/// ```rust +/// ```no_run /// // Includes -/// use binaryninja::types::{Structure, Type}; +/// # use binaryninja::binaryview::BinaryViewExt; +/// use binaryninja::types::{Structure, StructureBuilder, Type, MemberAccess, MemberScope}; /// /// // Define struct, set size (in bytes) /// let mut my_custom_struct = StructureBuilder::new(); @@ -1653,16 +1655,16 @@ pub struct StructureBuilder { /// let field_3 = Type::int(8, false); /// /// // Assign those fields -/// my_custom_struct.append(&field_1, "field_4"); -/// my_custom_struct.insert(&field_1, "field_1", 0); -/// my_custom_struct.insert(&field_2, "field_2", 5); -/// my_custom_struct.insert(&field_3, "field_3", 9); +/// my_custom_struct.insert(&field_1, "field_1", 0, false, MemberAccess::PublicAccess, MemberScope::NoScope); +/// my_custom_struct.insert(&field_2, "field_2", 5, false, MemberAccess::PublicAccess, MemberScope::NoScope); +/// my_custom_struct.insert(&field_3, "field_3", 9, false, MemberAccess::PublicAccess, MemberScope::NoScope); +/// my_custom_struct.append(&field_1, "field_4", MemberAccess::PublicAccess, MemberScope::NoScope); /// /// // Convert structure to type -/// let my_custom_structure_type = Self::structure_type(&mut my_custom_struct); +/// let my_custom_structure_type = Type::structure(&my_custom_struct.finalize()); /// /// // Add the struct to the binary view to use in analysis -/// let bv = unsafe { BinaryView::from_raw(view) }; +/// let bv = binaryninja::load("example").unwrap(); /// bv.define_user_type("my_custom_struct", &my_custom_structure_type); /// ``` impl StructureBuilder {