Read x bytes starting at pointer

I'm using the Goblin binary parsing library to get some forensic metadata from Windows PE binaries. I'm trying to figure out how to read each section of a PE file. Each section has these two values in the section's struct:

SectionTable in goblin::pe::section_table - Rust (docs.rs)

section.pointer_to_raw_data
section.size_of_raw_data

Trying to read each PE section's raw data so that I can hash it and do other things of forensic use. Can't figure it out and I'm not sure if I can use those two properties to read each PE section.

This is the function that is pulling some PE section forensic information in my code:

fmd/main.rs at main ยท theflakes/fmd (github.com)

fn get_sections(pex: &PE) -> io::Result<BinSections>{
    let mut bss = BinSections::default();
    for s in pex.sections.iter() {
        bss.total_sections += 1;
        bss.total_raw_bytes += s.size_of_raw_data;
        bss.total_virt_bytes += s.virtual_size;
        let mut bs: BinSection = BinSection::default();
        bs.name = s.name().unwrap_or("").to_string();
        bs.virt_address = format!("0x{:02x}", s.virtual_address);
        bs.raw_size = s.size_of_raw_data;
        bs.virt_size = s.virtual_size;
        bss.sections.push(bs);
    }
    Ok(bss)
}

Thanks for any help

You can get a slice from the pointer like this:

unsafe {
    std::slice::from_raw_parts(pointer, length)
}

Note that the actual length is bytes is size_of::<PointTargetType> * length, so give the pointer a target type of u8 to just read raw bytes.

Thanks for this.

This didn't work but it did get me started down the right path. Below is what worked.

fn read_section(file_path: &str, start: u32, size: u32) -> io::Result<Vec<u8>> {
    let mut f = File::open(file_path)?;
    f.seek(SeekFrom::Start(start as u64))?;
    let mut buf = vec![0; size as usize];
    f.read_exact(&mut buf)?;
    Ok(buf)
}

fn get_sections(pex: &PE, file_path: &str) -> io::Result<BinSections>{
    let mut bss = BinSections::default();
    for s in pex.sections.iter() {
        bss.total_sections += 1;
        bss.total_raw_bytes += s.size_of_raw_data;
        bss.total_virt_bytes += s.virtual_size;
        let mut bs: BinSection = BinSection::default();
        bs.name = s.name().unwrap_or("").to_string();
        bs.virt_address = format!("0x{:02x}", s.virtual_address);
        bs.raw_size = s.size_of_raw_data;
        bs.virt_size = s.virtual_size;
        let data = read_section(&file_path, s.pointer_to_raw_data, s.size_of_raw_data)?;
        bs.entropy = get_entropy(&data)?;
        bs.md5 = format!("{:x}", md5::compute(data)).to_lowercase();
        bss.sections.push(bs);
    }
    Ok(bss)
}

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.