Skip to content

Commit 67be278

Browse files
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.
1 parent 9b285ff commit 67be278

File tree

1 file changed

+39
-0
lines changed

1 file changed

+39
-0
lines changed

rust/src/binary_view.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1340,6 +1340,45 @@ pub trait BinaryViewExt: BinaryViewBase {
13401340
}
13411341
}
13421342

1343+
/// List of functions with the given name.
1344+
///
1345+
/// There is one special case where if you pass a string of the form `sub_[0-9a-f]+` then it will lookup all
1346+
/// functions defined at the address matched by the regular expression if that symbol is not defined in the
1347+
/// database.
1348+
///
1349+
/// # Params
1350+
/// - `name`: Name that the function should have
1351+
/// - `plat`: Optional platform that the function should be defined for. Defaults to all platforms if `None` passed.
1352+
fn functions_by_name(
1353+
&self,
1354+
name: impl IntoCStr,
1355+
plat: Option<&Platform>,
1356+
) -> Vec<Ref<Function>> {
1357+
let name = name.to_cstr();
1358+
let symbols = self.symbols_by_name(&*name);
1359+
let mut addresses: Vec<u64> = symbols.into_iter().map(|s| s.address()).collect();
1360+
if addresses.is_empty() && name.to_bytes().starts_with(b"sub_") {
1361+
if let Ok(str) = name.to_str() {
1362+
if let Ok(address) = u64::from_str_radix(&str[4..], 16) {
1363+
addresses.push(address);
1364+
}
1365+
}
1366+
}
1367+
1368+
let mut functions = Vec::new();
1369+
1370+
for address in addresses {
1371+
let funcs = self.functions_at(address);
1372+
for func in funcs.into_iter() {
1373+
if func.start() == address && plat.map_or(true, |p| p == func.platform().as_ref()) {
1374+
functions.push(func.clone());
1375+
}
1376+
}
1377+
}
1378+
1379+
functions
1380+
}
1381+
13431382
fn function_at(&self, platform: &Platform, addr: u64) -> Option<Ref<Function>> {
13441383
unsafe {
13451384
let raw_func_ptr = BNGetAnalysisFunction(self.as_ref().handle, platform.handle, addr);

0 commit comments

Comments
 (0)