Skip to main content

collect_executable_files

Function collect_executable_files 

Source
pub fn collect_executable_files(
    dir: &PathBuf,
    options: &ScanOptions,
) -> Result<Vec<PathBuf>>
Expand description

Collect all executable files from a directory

This function walks through a directory and identifies executable files based on their magic bytes and the specified file filter. It can operate recursively or just scan the top level, and can respect filesystem boundaries.

§Arguments

  • dir - Directory path to scan
  • options - Scan options including recursion, filtering, and filesystem boundaries

§Returns

Returns a vector of paths to executable files found in the directory.

Examples found in repository?
examples/custom_filter.rs (line 16)
9fn main() -> Result<(), Box<dyn std::error::Error>> {
10    // Collect executable files from a directory
11    let scan_path = PathBuf::from("/usr/bin");
12    let options = ScanOptions {
13        recursive: false,
14        ..Default::default()
15    };
16    let files = collect_executable_files(&scan_path, &options)?;
17    
18    println!("Found {} executable files in {}", files.len(), scan_path.display());
19    
20    // Analyze files with the same options
21    let report = analyze_files(files, &options)?;
22    
23    // Custom filtering: find files missing stack canaries
24    let files_without_canary: Vec<&SecurityCheck> = report.files
25        .iter()
26        .filter(|check| {
27            check.checks.get("canary").map_or(false, |v| v.contains("No Canary"))
28        })
29        .collect();
30    
31    println!("\n=== Files Missing Stack Canaries ===");
32    if files_without_canary.is_empty() {
33        println!("All files have stack canary protection! ✓");
34    } else {
35        for check in files_without_canary {
36            println!("⚠️  {} ({})", check.file_path, check.file_type);
37        }
38    }
39    
40    // Custom filtering: find files with RPATH issues
41    let files_with_rpath: Vec<&SecurityCheck> = report.files
42        .iter()
43        .filter(|check| {
44            check.checks.get("rpath").map_or(false, |v| v == "RPATH") ||
45            check.checks.get("runpath").map_or(false, |v| v == "RUNPATH")
46        })
47        .collect();
48    
49    println!("\n=== Files with RPATH/RUNPATH Issues ===");
50    if files_with_rpath.is_empty() {
51        println!("No RPATH/RUNPATH issues found! ✓");
52    } else {
53        for check in files_with_rpath {
54            println!("⚠️  {} ({})", check.file_path, check.file_type);
55            if let Some(rpath) = check.checks.get("rpath") {
56                if rpath == "RPATH" {
57                    println!("    - Has RPATH");
58                }
59            }
60            if let Some(runpath) = check.checks.get("runpath") {
61                if runpath == "RUNPATH" {
62                    println!("    - Has RUNPATH");
63                }
64            }
65        }
66    }
67    
68    // Security score calculation
69    let total_checks = report.files.len();
70    let security_score = if total_checks > 0 {
71        (report.summary.secure_files as f64 / total_checks as f64) * 100.0
72    } else {
73        0.0
74    };
75    
76    println!("\n=== Security Score ===");
77    println!("Overall security score: {:.1}%", security_score);
78    println!("({}/{} files are secure)", report.summary.secure_files, total_checks);
79    
80    Ok(())
81}
More examples
Hide additional examples
examples/advanced_filtering.rs (line 25)
12fn main() -> Result<(), Box<dyn std::error::Error>> {
13    println!("=== ExeCheck Advanced Filtering Example ===\n");
14
15    // Example 1: Filter only Windows executables (.exe)
16    println!("1. Scanning for Windows executables (.exe files only):");
17    let exe_options = ScanOptions {
18        recursive: false,
19        issues_only: false,
20        strict: false,
21        file_filter: FileFilter::WindowsExecutables,
22        one_filesystem: false,
23    };
24    
25    if let Ok(exe_files) = collect_executable_files(&PathBuf::from("."), &exe_options) {
26        println!("   Found {} .exe files", exe_files.len());
27        for file in exe_files.iter().take(3) {
28            println!("   - {}", file.display());
29        }
30    } else {
31        println!("   No .exe files found or error occurred");
32    }
33
34    // Example 2: Filter only Windows DLLs (.dll)
35    println!("\n2. Scanning for Windows DLLs (.dll files only):");
36    let dll_options = ScanOptions {
37        recursive: false,
38        issues_only: false,
39        strict: false,
40        file_filter: FileFilter::WindowsDlls,
41        one_filesystem: false,
42    };
43    
44    if let Ok(dll_files) = collect_executable_files(&PathBuf::from("."), &dll_options) {
45        println!("   Found {} .dll files", dll_files.len());
46        for file in dll_files.iter().take(3) {
47            println!("   - {}", file.display());
48        }
49    } else {
50        println!("   No .dll files found or error occurred");
51    }
52
53    // Example 3: Custom extension filtering
54    println!("\n3. Custom extension filtering (exe, dll, so, dylib):");
55    let custom_extensions = vec![
56        "exe".to_string(),
57        "dll".to_string(), 
58        "so".to_string(),
59        "dylib".to_string(),
60    ];
61    
62    let custom_options = ScanOptions {
63        recursive: true,
64        issues_only: false,
65        strict: false,
66        file_filter: FileFilter::Extensions(custom_extensions),
67        one_filesystem: false,
68    };
69    
70    if let Ok(custom_files) = collect_executable_files(&PathBuf::from("."), &custom_options) {
71        println!("   Found {} files with custom extensions", custom_files.len());
72        for file in custom_files.iter().take(5) {
73            println!("   - {}", file.display());
74        }
75    } else {
76        println!("   No files with custom extensions found or error occurred");
77    }
78
79    // Example 4: Custom predicate filtering
80    println!("\n4. Custom predicate filtering (files containing 'lib' in name):");
81    let lib_filter = |path: &std::path::Path| {
82        path.file_name()
83            .and_then(|name| name.to_str())
84            .map_or(false, |name| name.to_lowercase().contains("lib"))
85    };
86    
87    let predicate_options = ScanOptions {
88        recursive: true,
89        issues_only: false,
90        strict: false,
91        file_filter: FileFilter::Custom(lib_filter),
92        one_filesystem: false,
93    };
94    
95    if let Ok(lib_files) = collect_executable_files(&PathBuf::from("/usr/lib"), &predicate_options) {
96        println!("   Found {} library files", lib_files.len());
97        for file in lib_files.iter().take(5) {
98            println!("   - {}", file.display());
99        }
100    } else {
101        println!("   Error scanning /usr/lib or no library files found");
102    }
103
104    // Example 5: Filesystem boundary demonstration (Unix only)
105    #[cfg(unix)]
106    {
107        println!("\n5. Filesystem boundary scanning (Unix only):");
108        let boundary_options = ScanOptions {
109            recursive: true,
110            issues_only: false,
111            strict: false,
112            file_filter: FileFilter::All,
113            one_filesystem: true, // Stay within single filesystem
114        };
115        
116        if let Ok(boundary_files) = collect_executable_files(&PathBuf::from("/"), &boundary_options) {
117            println!("   Found {} files within root filesystem", boundary_files.len());
118            println!("   (This prevents crossing into /proc, /sys, mounted drives, etc.)");
119        } else {
120            println!("   Error scanning root filesystem with boundary restrictions");
121        }
122    }
123    
124    #[cfg(not(unix))]
125    {
126        println!("\n5. Filesystem boundary scanning:");
127        println!("   (Not supported on this platform - Unix-like systems only)");
128    }
129
130    // Example 6: Practical use case - analyze only PE files in a directory
131    println!("\n6. Practical example - Analyze Windows executables and DLLs with JSON output:");
132    
133    let analysis_options = ScanOptions {
134        recursive: true,
135        issues_only: true, // Only show files with security issues
136        strict: false,
137        file_filter: FileFilter::WindowsExecutablesAndDlls,
138        one_filesystem: false,
139    };
140    
141    // Try to analyze current directory for demo purposes
142    if let Ok(files) = collect_executable_files(&PathBuf::from("."), &analysis_options) {
143        if !files.is_empty() {
144            let report = analyze_files(files, &analysis_options)?;
145            
146            if !report.files.is_empty() {
147                println!("   Analysis results (JSON format):");
148                print_report(&report, &OutputFormat::Json, None)?;
149            } else {
150                println!("   No security issues found in Windows executables/DLLs!");
151            }
152        } else {
153            println!("   No Windows executables or DLLs found in current directory");
154        }
155    }
156
157    println!("\n=== Advanced Filtering Example Complete ===");
158    Ok(())
159}