#![allow(dead_code)]
use crate::evtx_parser::ReadSeek;
use std::cmp;
use std::error::Error;
use std::fmt::Write;
use std::io::SeekFrom;
pub fn dump_stream<T: ReadSeek>(cursor: &mut T, lookbehind: i32) -> Result<String, Box<dyn Error>> {
let mut s = String::new();
cursor.seek(SeekFrom::Current(lookbehind.into()))?;
let mut data = vec![0; 100_usize];
let _ = cursor.read(&mut data)?;
writeln!(
s,
"\n\n---------------------------------------------------------------------------"
)?;
writeln!(s, "Current Value {:02x}", data[0])?;
writeln!(s, " --")?;
write!(s, "{}", hexdump(&data, 0, 'C')?)?;
writeln!(
s,
"\n----------------------------------------------------------------------------"
)?;
Ok(s)
}
pub fn hexdump(
data: &[u8],
offset: usize,
display: char,
) -> Result<String, Box<dyn std::error::Error>> {
let mut s = String::new();
let mut address = 0;
let number_of_bytes = match display {
'b' => 1,
'c' => 1,
'C' => 1,
'd' => 2,
'o' => 2,
_ => 2,
};
while address <= data.len() {
let end = cmp::min(address + 16, data.len());
write!(
s,
"{}",
print_line(
&data[address..end],
address + offset,
display,
number_of_bytes,
)?
)?;
address += 16;
}
Ok(s)
}
fn print_line(
line: &[u8],
address: usize,
display: char,
bytes: usize,
) -> Result<String, Box<dyn std::error::Error>> {
let mut s = String::new();
write!(s, "\n{:08x}:", address)?;
let words = if line.len().is_multiple_of(bytes) {
line.len() / bytes
} else {
(line.len() / bytes) + 1
};
for b in 0..words {
let word = match bytes {
1 => u16::from(line[b]),
_ => {
if line.len() == bytes * b + 1 {
u16::from_be(u16::from(line[bytes * b]) << 8)
} else {
u16::from_be((u16::from(line[bytes * b]) << 8) + u16::from(line[bytes * b + 1]))
}
}
};
match display {
'b' => write!(s, " {:03o}", word)?,
'c' => {
if ((word as u8) as char).is_control() {
write!(s, " ")?
} else {
write!(s, " {:03}", (word as u8) as char)?
}
}
'C' => write!(s, " {:02x}", word)?,
'x' => write!(s, " {:04x}", word)?,
'o' => write!(s, " {:06o} ", word)?,
'd' => write!(s, " {:05} ", word)?,
_ => write!(s, " {:04x}", word)?,
}
}
if display != 'c' {
if !line.len().is_multiple_of(16) {
let words_left = (16 - line.len()) / bytes;
let word_size = match display {
'b' => 4,
'c' => 4,
'C' => 3,
'x' => 5,
'o' => 8,
'd' => 8,
_ => 5,
};
for _ in 0..word_size * words_left {
write!(s, " ")?;
}
}
write!(s, " ")?;
for c in line {
if (*c as char).is_control() {
write!(s, ".")?
} else {
write!(s, "{}", (*c as char))?
}
}
}
Ok(s)
}