use std::process::Command; use structopt::StructOpt; // TODO: Add validation function for `--partial=???` parameter. // TODO: `--partial` option needs better documentation on how to specify the list of checks to run. // TODO: Add module version printing function #[derive(Debug, StructOpt)] /// Find vulnerable patterns in binary executables struct CmdlineArgs { /// The path to the binary. #[structopt(required_unless("module-versions"), validator(check_file_existence))] binary: Option<String>, /// Path to a custom configuration file to use instead of the standard one. #[structopt(long, short, validator(check_file_existence))] config: Option<String>, /// Write the results to a file. #[structopt(long, short)] out: Option<String>, /// Specify a specific set of checks to be run. #[structopt(long, short)] partial: Option<String>, /// Generate JSON output. #[structopt(long, short)] json: bool, /// Do not print log messages. This prevents polluting STDOUT for json output. #[structopt(long, short)] quiet: bool, /// Checks if there is a path from an input function to a CWE hit. #[structopt(long)] check_path: bool, /// Prints out the version numbers of all known modules. #[structopt(long)] module_versions: bool, } fn main() { let cmdline_args = CmdlineArgs::from_args(); if cmdline_args.module_versions { println!("printing module versions"); todo!(); // TODO: implement! } else if let Some(exit_code) = build_bap_command(&cmdline_args).status().unwrap().code() { std::process::exit(exit_code); } } /// Build the BAP command corresponding to the given command line arguments. fn build_bap_command(args: &CmdlineArgs) -> Command { let mut command = Command::new("bap"); command.arg(args.binary.as_ref().unwrap()); command.arg("--pass=cwe-checker"); if let Some(ref string) = args.config { command.arg("--cwe-checker-config=".to_string() + string); } if let Some(ref string) = args.out { command.arg("--cwe-checker-out=".to_string() + string); } if let Some(ref string) = args.partial { command.arg("--cwe-checker-partial=".to_string() + string); } if args.json { command.arg("--cwe-checker-json"); } if args.quiet { command.arg("--cwe-checker-no-logging"); } if args.check_path { command.arg("--cwe-checker-check-path"); } if args.module_versions { command.arg("--cwe-checker-module-versions"); } command } /// Check the existence of a file fn check_file_existence(file_path: String) -> Result<(), String> { if std::fs::metadata(&file_path) .map_err(|err| format!("{}", err))? .is_file() { Ok(()) } else { Err(format!("{} is not a file.", file_path)) } }