summaryrefslogtreecommitdiff
path: root/rust/src/binary_view.rs
diff options
context:
space:
mode:
authorJames Johnson <jjohnsonjj1251@gmail.com>2025-11-02 14:02:19 -0500
committerMason Reed <35282038+emesare@users.noreply.github.com>2025-11-17 17:55:09 -0500
commit887fd85066bde0cc64d7c5c94ea09f056f163842 (patch)
tree6d0ba9125547339e845c01505ebc285891a40f1f /rust/src/binary_view.rs
parent89e76e22de16e873e676c93713866236035dc7fd (diff)
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.
Diffstat (limited to 'rust/src/binary_view.rs')
-rw-r--r--rust/src/binary_view.rs39
1 files changed, 39 insertions, 0 deletions
diff --git a/rust/src/binary_view.rs b/rust/src/binary_view.rs
index 5d8f22cf..593c1c4b 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<Ref<Function>> {
+ let name = name.to_cstr();
+ let symbols = self.symbols_by_name(&*name);
+ let mut addresses: Vec<u64> = 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<Ref<Function>> {
unsafe {
let raw_func_ptr = BNGetAnalysisFunction(self.as_ref().handle, platform.handle, addr);