diff --git a/Cargo.lock b/Cargo.lock index 866b016..26691a0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -828,6 +828,7 @@ dependencies = [ "encoding_rs", "encoding_rs_io", "evtx", + "exitcode", "flate2", "forensic-rs", "frnsc-prefetch", @@ -1123,6 +1124,12 @@ dependencies = [ "winstructs", ] +[[package]] +name = "exitcode" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de853764b47027c2e862a995c34978ffa63c1501f2e15f987ba11bd4f9bba193" + [[package]] name = "fastrand" version = "2.1.0" diff --git a/Cargo.toml b/Cargo.toml index 6a99572..6367192 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -200,6 +200,7 @@ forensic-rs = {version="0.13", optional=true} # zip2bodyfile zip = {version="2.1.3", optional=true, features=["time"]} time = {version="0.3.36", optional=true} +exitcode = "1.1.2" [dev-dependencies] diff --git a/src/bin/evtxanalyze/main.rs b/src/bin/evtxanalyze/main.rs index 923d1d5..d6a3e9b 100644 --- a/src/bin/evtxanalyze/main.rs +++ b/src/bin/evtxanalyze/main.rs @@ -1,6 +1,7 @@ use cli::{Cli, Command}; -use pstree::display_pstree; use dfir_toolkit::common::FancyParser; +use log::log_enabled; +use pstree::display_pstree; mod cli; mod pstree; @@ -9,10 +10,25 @@ mod sessions; fn main() -> anyhow::Result<()> { let cli = Cli::parse_cli(); - match &cli.command { + let result = match &cli.command { //TODO: move `display_pstree` into `impl Cli` Command::PsTree { .. } => display_pstree(&cli), Command::Sessions { .. } => cli.display_sessions(), Command::Session { .. } => cli.display_single_session(), + }; + + if let Err(why) = result { + log::error!("{why}"); + if let Some(cause) = why.source() { + log::error!("caused by: {cause}"); + } + if log_enabled!(log::Level::Warn) { + for line in format!("{}", why.backtrace()).lines() { + log::warn!("{line}"); + } + } + std::process::exit(exitcode::DATAERR); } + + Ok(()) } diff --git a/src/bin/evtxanalyze/pstree/mod.rs b/src/bin/evtxanalyze/pstree/mod.rs index 09b027d..737ce69 100644 --- a/src/bin/evtxanalyze/pstree/mod.rs +++ b/src/bin/evtxanalyze/pstree/mod.rs @@ -42,21 +42,26 @@ pub(crate) fn display_pstree(cli: &Cli) -> anyhow::Result<()> { let mut parser = EvtxParser::from_path(evtx_file)?; let mut unique_pids = HashMap::new(); - let events: HashMap<_, _> = parser - .records_json_value() - .map(|r| r.expect("error reading event")) - .map(Process::try_from) - .filter_map(|r| r.expect("invalid event")) - .filter(has_username) - .map(|e| { - let pid = UniquePid::from(&e); - unique_pids - .entry(e.new_process_id) - .or_insert_with(HashSet::new) - .insert(pid.clone()); - (pid, Rc::new(RefCell::new(e))) - }) - .collect(); + let mut events = HashMap::new(); + for record in parser.records_json_value() { + match record { + Err(why) => log::warn!("{why}"), + Ok(record) => match Process::try_from(record) { + Err(why) => log::warn!("{why}"), + Ok(Some(process)) => { + if has_username(&process) { + let pid = UniquePid::from(&process); + unique_pids + .entry(process.new_process_id) + .or_insert_with(HashSet::new) + .insert(pid.clone()); + events.insert(pid, Rc::new(RefCell::new(process))); + } + } + Ok(None) => (), + }, + } + } log::warn!("found {} process creations", events.len());