Skip to content

Commit

Permalink
Merge pull request #38 from dfir-dd/37-error-in-hivescan-unexpectedeof
Browse files Browse the repository at this point in the history
37 error in hivescan unexpectedeof
  • Loading branch information
janstarke authored Apr 18, 2024
2 parents ab5808f + aad73f9 commit 706bb48
Show file tree
Hide file tree
Showing 19 changed files with 65 additions and 22 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
target
!Cargo.lock
.vscode
.idea
tmp
temp
7 changes: 4 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,8 @@ strum = { version = "0", features = ["derive"], optional=true }
strum_macros = {version="0", optional=true}

# nt-hive2
nt_hive2 = {version="4.1.0", optional=true}
nt_hive2 = {version="4.2.1", optional=true}
#nt_hive2 = {path="../nt-hive2", optional=true}

# lnk2bodyfile
lnk = {version="0.5.1", optional=true}
Expand Down
18 changes: 11 additions & 7 deletions src/bin/hivescan/hivescanapplication.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,26 @@ use anyhow::Result;
use dfir_toolkit::common::bodyfile::Bodyfile3Line;
use indicatif::{ProgressBar, ProgressStyle};
use nt_hive2::*;
use std::fs::File;
use std::time::Duration;
use std::{io::Read, io::Seek};

use crate::regtreebuilder::RegTreeBuilder;

pub(crate) struct HiveScanApplication {
pub(crate) struct HiveScanApplication<RS>
where
RS: Read + Seek,
{
#[allow(dead_code)]
cli: Cli,

root_offset: Offset,
hive: Option<Hive<File, CleanHive>>,
hive: Option<Hive<RS, CleanHive>>,
}

impl HiveScanApplication {
pub fn new(cli: Cli, hive: Hive<File, CleanHive>) -> Self {
impl<RS> HiveScanApplication<RS>
where
RS: Read + Seek,
{
pub fn new(cli: Cli, hive: Hive<RS, CleanHive>) -> Self {
Self {
cli,
root_offset: hive.root_cell_offset(),
Expand All @@ -34,7 +39,6 @@ impl HiveScanApplication {
.unwrap();
let bar = ProgressBar::new(self.hive.as_ref().unwrap().data_size().into());
bar.set_style(progress_style);
bar.enable_steady_tick(Duration::from_millis(100));
bar.set_message("scanning cells");

let builder = RegTreeBuilder::from_hive(self.hive.take().unwrap(), |p| bar.set_position(p));
Expand Down
3 changes: 2 additions & 1 deletion src/bin/hivescan/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use anyhow::{bail, Result};
use cli::Cli;
use dfir_toolkit::common::FancyParser;
use nt_hive2::{ContainsHive, Hive, HiveParseMode};
use std::fs::File;
use std::{fs::File, io::BufReader};

mod hivescanapplication;
mod regtreebuilder;
Expand All @@ -15,6 +15,7 @@ fn main() -> Result<()> {

match File::open(&cli.hive_file) {
Ok(data) => {
let data = BufReader::new(data);
let hive = Hive::new(data, HiveParseMode::NormalWithBaseBlock).unwrap();

let clean_hive = match cli.logfiles.len() {
Expand Down
19 changes: 10 additions & 9 deletions src/bin/hivescan/regtreebuilder.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
use std::{
cell::RefCell,
collections::{hash_map, HashMap},
rc::Rc,
cell::RefCell, cmp::max, collections::{hash_map, HashMap}, rc::Rc
};

use binread::BinReaderExt;
Expand Down Expand Up @@ -48,25 +46,28 @@ impl RegTreeBuilder {
B: BinReaderExt,
C: Fn(u64),
{
let iterator = hive.into_cell_iterator(progress_callback);
let mut me = Self {
subtrees: HashMap::new(),
entries: HashMap::new(),
missing_parents: HashMap::new(),
};

let mut last_offset = Offset(0);
for cell in iterator {
let mut last_cell_end = 0;
for cell in hive.hivebins().flat_map(|hivebin| hivebin.cells()) {
let my_offset = *cell.offset();
let my_size = cell.header().size();
let is_deleted = cell.header().is_deleted();
assert_ne!(last_offset, my_offset);
log::trace!("found new cell at offset 0x{:x}", my_offset.0);

if let Ok(nk) = TryInto::<KeyNode>::try_into(cell) {
me.insert_nk(my_offset, nk, is_deleted)
};

me.insert_nk(my_offset, nk, is_deleted);
}
last_offset = my_offset;

last_cell_end = max(last_cell_end, u64::from(last_offset.0) + u64::try_from(my_size).unwrap());
progress_callback(last_cell_end);
}
me
}
Expand All @@ -78,7 +79,7 @@ impl RegTreeBuilder {
}

fn insert_nk(&mut self, nk_offset: Offset, nk: KeyNode, is_deleted: bool) {
assert!(!self.subtrees.contains_key(&nk_offset));
assert!(!self.subtrees.contains_key(&nk_offset), "KeyNode at offset 0x{:08x} is already in the set of subtrees", nk_offset.0);
assert!(!self.entries.contains_key(&nk_offset));

let parent_offset = nk.parent;
Expand Down
Binary file added tests/data/hivescan/NewDirtyHive1/NewDirtyHive
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added tests/data/hivescan/NewDirtyHive2/NewDirtyHive
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added tests/data/hivescan/testhive
Binary file not shown.
2 changes: 2 additions & 0 deletions tests/hivescan/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
mod testhive;
mod new_dirty_hive1;
15 changes: 15 additions & 0 deletions tests/hivescan/new_dirty_hive1.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
use std::path::PathBuf;

use assert_cmd::Command;

#[test]
fn scan_new_dirty_hive1() {
let mut cmd = Command::cargo_bin("hivescan").unwrap();
let mut data_path = PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").unwrap());
data_path.push("tests");
data_path.push("data");
data_path.push("hivescan");
data_path.push("NewDirtyHive1");
data_path.push("NewDirtyHive");
cmd.arg(data_path).assert().success();
}
14 changes: 14 additions & 0 deletions tests/hivescan/testhive.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use std::path::PathBuf;

use assert_cmd::Command;

#[test]
fn scan_testhive() {
let mut cmd = Command::cargo_bin("hivescan").unwrap();
let mut data_path = PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").unwrap());
data_path.push("tests");
data_path.push("data");
data_path.push("hivescan");
data_path.push("testhive");
cmd.arg(data_path).assert().success();
}
3 changes: 2 additions & 1 deletion tests/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
mod mactime2;
mod ts2date;
mod lnk2bodyfile;
mod lnk2bodyfile;
mod hivescan;

0 comments on commit 706bb48

Please sign in to comment.