pub fn analyze_files(
files: Vec<PathBuf>,
options: &ScanOptions,
) -> Result<SecurityReport>Expand description
Examples found in repository?
examples/custom_filter.rs (line 21)
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
examples/advanced_filtering.rs (line 144)
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}