m4b / goblin

An impish, cross-platform binary parsing crate, written in Rust
MIT License
1.18k stars 158 forks source link

Unable to parse ELF SectionHeader from raw bytes #390

Closed lissyx closed 7 months ago

lissyx commented 8 months ago

I am unsure if this is a side effect of something else or done on purpose but let's imagine the following code:

            let mut fs = fs::File::open(path)?;
            let section_header_bytes = copy_array(
                fs,
                elf_head.e_shoff as usize,
                (elf_head.e_shnum as usize) * (elf_head.e_shentsize as usize),
            );
            // println!("SectionHeaderBytes: {:?}", section_header_bytes);

            let mut elf = elf::Elf::lazy_parse(elf_head)?;
            let context = goblin::container::Ctx {
                container: elf.header.container()?,
                le: elf.header.endianness()?,
            };

            elf.section_headers = SectionHeader::parse(
                &section_header_bytes,
                0,
                elf_head.e_shnum as usize,
                context,
            )?;

            println!("SectionHeaders: {:#?}", elf.section_headers);

The SectionHeader::parse() will fail because of https://github.com/m4b/goblin/blob/5b67d29bee4fa31766cdb9ec04062503b836701e/src/elf/section_header.rs#L449-L451

It likely makes sense when parsing the whole complete file, but in my case I want to just parse this section, and the offset for that section is e.g., at 0xc8e912a0 so that's quite a few bytes to read from the file for nothing. Locally just avoiding this works very well.

lissyx commented 8 months ago

Would adding a SectionHeader::parse_raw() that basically is actual parse without the check, and make parse() call it after the offset check be a valid fix ?