ewf-forensic 0.2.0

Forensic integrity analysis and repair for EWF (Expert Witness Format / E01) images
Documentation
use crate::integrity::{adler32, EwfIntegrity, EwfIntegrityAnomaly, SECTION_DESCRIPTOR_SIZE};

pub struct EwfRepair {
    data: Vec<u8>,
}

pub struct RepairReport {
    pub data: Vec<u8>,
    pub repairs: Vec<Repaired>,
    pub cannot_repair: Vec<CannotRepair>,
}

#[derive(Debug, Clone)]
pub enum Repaired {
    SectionDescriptorCrc { offset: u64, section_type: String },
}

#[derive(Debug, Clone)]
pub enum CannotRepair {
    HashMismatch {
        computed: [u8; 16],
        stored: [u8; 16],
    },
}

impl EwfRepair {
    pub fn new(data: Vec<u8>) -> Self {
        Self { data }
    }

    pub fn repair(mut self) -> RepairReport {
        let mut repairs = Vec::new();
        let mut cannot_repair = Vec::new();

        let anomalies = EwfIntegrity::new(&self.data).analyse();

        for anomaly in anomalies {
            match anomaly {
                EwfIntegrityAnomaly::SectionDescriptorCrcMismatch {
                    offset,
                    section_type,
                    ..
                } => {
                    let off = offset as usize;
                    if off + SECTION_DESCRIPTOR_SIZE <= self.data.len() {
                        let correct = adler32(&self.data[off..off + 72]);
                        self.data[off + 72..off + 76].copy_from_slice(&correct.to_le_bytes());
                        repairs.push(Repaired::SectionDescriptorCrc {
                            offset,
                            section_type,
                        });
                    }
                }
                EwfIntegrityAnomaly::HashMismatch { computed, stored } => {
                    cannot_repair.push(CannotRepair::HashMismatch { computed, stored });
                }
                _ => {}
            }
        }

        RepairReport {
            data: self.data,
            repairs,
            cannot_repair,
        }
    }
}