From 67be2783847205ddc173a35420efeb02f89dcd82 Mon Sep 17 00:00:00 2001 From: James Johnson Date: Sun, 2 Nov 2025 14:02:19 -0500 Subject: [PATCH] Add functions_by_name to rust implementation of BinaryViewExt Python has the get_functions_by_name method on binary views that is useful for finding a function by name. This adds that same method to the rust implementation for binary views. The implementation is essentially the same as the python version apart from the ordering of the symbols. Python will order functions defined in the binary before functions defined outside of the binary. The rust implementation of `symbols_by_name` does not take an ordering for the symbols so that is currently left out here. --- rust/src/binary_view.rs | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/rust/src/binary_view.rs b/rust/src/binary_view.rs index 5d8f22cfac..593c1c4b6f 100644 --- a/rust/src/binary_view.rs +++ b/rust/src/binary_view.rs @@ -1340,6 +1340,45 @@ pub trait BinaryViewExt: BinaryViewBase { } } + /// List of functions with the given name. + /// + /// There is one special case where if you pass a string of the form `sub_[0-9a-f]+` then it will lookup all + /// functions defined at the address matched by the regular expression if that symbol is not defined in the + /// database. + /// + /// # Params + /// - `name`: Name that the function should have + /// - `plat`: Optional platform that the function should be defined for. Defaults to all platforms if `None` passed. + fn functions_by_name( + &self, + name: impl IntoCStr, + plat: Option<&Platform>, + ) -> Vec> { + let name = name.to_cstr(); + let symbols = self.symbols_by_name(&*name); + let mut addresses: Vec = symbols.into_iter().map(|s| s.address()).collect(); + if addresses.is_empty() && name.to_bytes().starts_with(b"sub_") { + if let Ok(str) = name.to_str() { + if let Ok(address) = u64::from_str_radix(&str[4..], 16) { + addresses.push(address); + } + } + } + + let mut functions = Vec::new(); + + for address in addresses { + let funcs = self.functions_at(address); + for func in funcs.into_iter() { + if func.start() == address && plat.map_or(true, |p| p == func.platform().as_ref()) { + functions.push(func.clone()); + } + } + } + + functions + } + fn function_at(&self, platform: &Platform, addr: u64) -> Option> { unsafe { let raw_func_ptr = BNGetAnalysisFunction(self.as_ref().handle, platform.handle, addr);