Strategies for finding binary dependencies
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

add wheel iteration

+87 -25
+29
Cargo.lock
··· 60 60 "comfy-table", 61 61 "elf", 62 62 "glob", 63 + "walkdir", 63 64 ] 64 65 65 66 [[package]] ··· 294 295 ] 295 296 296 297 [[package]] 298 + name = "same-file" 299 + version = "1.0.6" 300 + source = "registry+https://github.com/rust-lang/crates.io-index" 301 + checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" 302 + dependencies = [ 303 + "winapi-util", 304 + ] 305 + 306 + [[package]] 297 307 name = "scopeguard" 298 308 version = "1.2.0" 299 309 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 347 357 checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" 348 358 349 359 [[package]] 360 + name = "walkdir" 361 + version = "2.5.0" 362 + source = "registry+https://github.com/rust-lang/crates.io-index" 363 + checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" 364 + dependencies = [ 365 + "same-file", 366 + "winapi-util", 367 + ] 368 + 369 + [[package]] 350 370 name = "winapi" 351 371 version = "0.3.9" 352 372 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 361 381 version = "0.4.0" 362 382 source = "registry+https://github.com/rust-lang/crates.io-index" 363 383 checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 384 + 385 + [[package]] 386 + name = "winapi-util" 387 + version = "0.1.11" 388 + source = "registry+https://github.com/rust-lang/crates.io-index" 389 + checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" 390 + dependencies = [ 391 + "windows-sys", 392 + ] 364 393 365 394 [[package]] 366 395 name = "winapi-x86_64-pc-windows-gnu"
+1
Cargo.toml
··· 10 10 comfy-table = "7.2.2" 11 11 elf = "0.8.0" 12 12 glob = "0.3.3" 13 + walkdir = "2.5.0"
+57 -25
src/bin/print_symbols.rs
··· 1 1 // © Vlad-Stefan Harbuz <vlad@vlad.website> 2 2 // SPDX-License-Identifier: Apache-2.0 3 3 4 - use std::ffi::OsString; 5 - use std::path::Path; 6 - use comfy_table::{Cell, Table}; 4 + // use std::ffi::OsString; 5 + // use std::path::Path; 6 + use std::fs::File; 7 + use std::io::{self, BufRead}; 7 8 9 + // use glob::glob; 8 10 use clap::Parser; 11 + use comfy_table::{Cell, Table}; 9 12 use elf::ElfStream; 10 13 use elf::endian::AnyEndian; 11 - use glob::glob; 14 + use walkdir::WalkDir; 12 15 13 - /// Print symbols for all ELF files in a directory 16 + /// Examine shared objects within a directory containing many extracted Python wheel files 14 17 #[derive(Parser, Debug)] 15 18 #[command(version, about, long_about = None)] 16 19 struct Args { ··· 19 22 dir: String, 20 23 } 21 24 25 + fn read_lines(filename: &str) -> io::Result<io::Lines<io::BufReader<File>>> { 26 + let file = File::open(filename)?; 27 + Ok(io::BufReader::new(file).lines()) 28 + } 29 + 22 30 /* 23 31 From https://github.com/cole14/rust-readelf/blob/419f78ac79d2e5b538ffe28777b54a487d953840/src/rust-readelf.rs 24 32 SPDX-SnippetBegin 25 33 SPDX-License-Identifier: MIT 26 34 SPDX-SnippetCopyrightText: Christopher Cole 27 35 */ 28 - fn print_dynamic_symbol_table(elf_file: &mut ElfStream<AnyEndian, std::fs::File>) { 36 + fn print_dynamic_symbol_table(elf_file: &mut ElfStream<AnyEndian, File>) { 29 37 // Get the .dynsym table. If this file doesn't have one, then we're done 30 38 let (dynsyms, dynstrs) = match elf_file 31 39 .dynamic_symbol_table() ··· 104 112 fn main() { 105 113 let args = Args::parse(); 106 114 107 - let dir_path = OsString::from(args.dir); 108 - let dir = Path::new(&dir_path); 109 - let glob_so_target_path = dir.join("**").join("*.so"); 110 - let glob_so_target = glob_so_target_path 111 - .to_str() 112 - .expect("could not convert path to string"); 113 - let glob_bin_target_path = dir.join("**").join("*.bin"); 114 - let glob_bin_target = glob_bin_target_path 115 - .to_str() 116 - .expect("could not convert path to string"); 117 - let glob_res = glob(glob_so_target).expect("failed to read glob pattern") 118 - .chain(glob(glob_bin_target).expect("failed to read glob pattern")); 115 + let mut n_so_files = 0; 119 116 120 - for filename in glob_res.map_while(Result::ok) { 121 - println!("{:?}", filename); 117 + // TODO: Restrict to only directories 118 + for wheel_dir in WalkDir::new(args.dir).min_depth(1).max_depth(1) { 119 + let wheel_dir = wheel_dir.expect("could not read file"); 120 + let wheel_dir_path = wheel_dir.path().to_str().expect("could not convert path to str"); 122 121 123 - let filepath = std::path::PathBuf::from(filename); 124 - let file_stream = std::fs::File::open(filepath).expect("could not open file"); 125 - let mut elf_file = 126 - ElfStream::<AnyEndian, _>::open_stream(file_stream).expect("could not open ELF stream"); 122 + let mut name = None; 123 + 124 + for dist_info_candidate in WalkDir::new(wheel_dir_path).min_depth(1).max_depth(1) { 125 + let dist_info_candidate = dist_info_candidate.expect("could not read file"); 126 + let dist_info_candidate_path = dist_info_candidate.path().to_str().expect("could not convert path to str"); 127 + if dist_info_candidate_path.ends_with(".dist-info") { 128 + let metadata_path = format!("{}/METADATA", dist_info_candidate_path); 129 + let metadata_lines = read_lines(&metadata_path).expect("could not read METADATA"); 130 + for line in metadata_lines.map_while(Result::ok) { 131 + if line.starts_with("Name: ") { 132 + name = Some(line.replace("Name: ", "")); 133 + } 134 + } 135 + } 136 + } 137 + 138 + if let Some(name) = name { 139 + println!("→ {}", name); 140 + 141 + for file in WalkDir::new(wheel_dir_path) { 142 + let file = file.expect("could not read file"); 143 + let path = file.path().to_str().expect("could not convert path to str"); 127 144 128 - print_dynamic_symbol_table(&mut elf_file); 145 + let is_so = path.ends_with(".so") || path.contains(".so."); 146 + if is_so { 147 + println!("\t{}", path); 148 + n_so_files += 1; 149 + // let pathbuf = std::path::PathBuf::from(path); 150 + // let file_stream = File::open(pathbuf).expect("could not open file"); 151 + // let mut elf_file = 152 + // ElfStream::<AnyEndian, _>::open_stream(file_stream).expect("could not open ELF stream"); 153 + // print_dynamic_symbol_table(&mut elf_file); 154 + } 155 + } 156 + } else { 157 + panic!("Could not get name for {}", wheel_dir_path); 158 + } 129 159 } 160 + 161 + println!("found {} .so files", n_so_files); 130 162 }