m4b / goblin

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

Malformed entity: Cannot map ImageDebugDirectory rva 0x3ac into offset #385

Closed nix-enthusiast closed 8 months ago

nix-enthusiast commented 9 months ago

Hi,

I installed EFI file from netboot.xyz and tried to parse it but it throws the error given on the title.

File Name: netboot.xyz-arm64.efi

Output of file netboot.xyz-arm64.efi:

netboot.xyz-arm64.efi: MS-DOS executable PE32+ executable (DLL) (EFI application) Aarch64 Mono/.Net assembly, for MS Windows
nix-enthusiast commented 9 months ago

Here's the code to reproduce bug:

use goblin::{pe::PE, peek_bytes};
use std::fs::read;

fn main() {
    let file = read("netboot.xyz-arm64.efi").unwrap();
    let peek = peek_bytes(TryInto::<&[u8;16]>::try_into(&file[0..16]).unwrap()).unwrap();
    println!("Peek result: {:?}",peek);
    let parsed_file = PE::parse(&file).unwrap();
    println!("{:#?}",parsed_file)
}

Also put netboot.xyz-arm64-efi in project file:

reproduce-bugs
             ├── Cargo.lock
             ├── Cargo.toml
             ├── target
             ├── netboot.xyz-arm64.efi
             └── src
                   └── main.rs

Interestingly objdump -p is also complaining about ImageDebugDirectory

Virtual Address: 000b1000 Chunk size 32 (0x20) Number of fixups 12
    reloc    0 offset   70 [b1070] DIR64
    reloc    1 offset   78 [b1078] DIR64
    reloc    2 offset   80 [b1080] DIR64
    reloc    3 offset   88 [b1088] DIR64
    reloc    4 offset  430 [b1430] DIR64
    reloc    5 offset  438 [b1438] DIR64
    reloc    6 offset  440 [b1440] DIR64
    reloc    7 offset  448 [b1448] DIR64
    reloc    8 offset  450 [b1450] DIR64
    reloc    9 offset  458 [b1458] DIR64
    reloc   10 offset  460 [b1460] DIR64
    reloc   11 offset    0 [b1000] ABSOLUTE

There is a debug directory, but the section containing it could not be found

I also parsed it with Object library from rust and the result:

PeFile {
    dos_header: ImageDosHeader {
        e_magic: U16(4d, 5a),
        e_cblp: U16(0, 0),
        e_cp: U16(0, 0),
        e_crlc: U16(0, 0),
        e_cparhdr: U16(0, 0),
        e_minalloc: U16(0, 0),
        e_maxalloc: U16(0, 0),
        e_ss: U16(0, 0),
        e_sp: U16(0, 0),
        e_csum: U16(0, 0),
        e_ip: U16(0, 0),
        e_cs: U16(0, 0),
        e_lfarlc: U16(0, 0),
        e_ovno: U16(0, 0),
        e_res: [
            U16(0, 0),
            U16(0, 0),
            U16(0, 0),
            U16(0, 0),
        ],
        e_oemid: U16(0, 0),
        e_oeminfo: U16(0, 0),
        e_res2: [
            U16(0, 0),
            U16(0, 0),
            U16(0, 0),
            U16(0, 0),
            U16(0, 0),
            U16(0, 0),
            U16(0, 0),
            U16(0, 0),
            U16(0, 0),
            U16(0, 0),
        ],
        e_lfanew: U32(40, 0, 0, 0),
    },
    nt_headers: ImageNtHeaders64 {
        signature: U32(50, 45, 0, 0),
        file_header: ImageFileHeader {
            machine: U16(64, aa),
            number_of_sections: U16(6, 0),
            time_date_stamp: U32(84, a8, d1, 10),
            pointer_to_symbol_table: U32(0, 0, 0, 0),
            number_of_symbols: U32(0, 0, 0, 0),
            size_of_optional_header: U16(b0, 0),
            characteristics: U16(22, 20),
        },
        optional_header: ImageOptionalHeader64 {
            magic: U16(b, 2),
            major_linker_version: 42,
            minor_linker_version: 42,
            size_of_code: U32(68, f4, a, 0),
            size_of_initialized_data: U32(23, 1f, 5, 0),
            size_of_uninitialized_data: U32(3c, 4f, a, 0),
            address_of_entry_point: U32(b0, 5c, 2, 0),
            base_of_code: U32(0, 10, 0, 0),
            image_base: U64(0, 0, 0, 0, 0, 0, 0, 0),
            section_alignment: U32(0, 10, 0, 0),
            file_alignment: U32(0, 2, 0, 0),
            major_operating_system_version: U16(0, 0),
            minor_operating_system_version: U16(0, 0),
            major_image_version: U16(0, 0),
            minor_image_version: U16(0, 0),
            major_subsystem_version: U16(0, 0),
            minor_subsystem_version: U16(0, 0),
            win32_version_value: U32(0, 0, 0, 0),
            size_of_image: U32(0, d0, 1a, 0),
            size_of_headers: U32(0, 4, 0, 0),
            check_sum: U32(0, 0, 0, 0),
            subsystem: U16(a, 0),
            dll_characteristics: U16(0, 1),
            size_of_stack_reserve: U64(0, 0, 0, 0, 0, 0, 0, 0),
            size_of_stack_commit: U64(0, 0, 0, 0, 0, 0, 0, 0),
            size_of_heap_reserve: U64(0, 0, 0, 0, 0, 0, 0, 0),
            size_of_heap_commit: U64(0, 0, 0, 0, 0, 0, 0, 0),
            loader_flags: U32(0, 0, 0, 0),
            number_of_rva_and_sizes: U32(8, 0, 0, 0),
        },
    },
    data_directories: DataDirectories {
        entries: [
            ImageDataDirectory {
                virtual_address: U32(0, 0, 0, 0),
                size: U32(0, 0, 0, 0),
            },
            ImageDataDirectory {
                virtual_address: U32(0, 0, 0, 0),
                size: U32(0, 0, 0, 0),
            },
            ImageDataDirectory {
                virtual_address: U32(0, 0, 0, 0),
                size: U32(0, 0, 0, 0),
            },
            ImageDataDirectory {
                virtual_address: U32(0, 0, 0, 0),
                size: U32(0, 0, 0, 0),
            },
            ImageDataDirectory {
                virtual_address: U32(0, 0, 0, 0),
                size: U32(0, 0, 0, 0),
            },
            ImageDataDirectory {
                virtual_address: U32(0, a0, 1a, 0),
                size: U32(20, 20, 0, 0),
            },
            ImageDataDirectory {
                virtual_address: U32(ac, 3, 0, 0),
                size: U32(1c, 0, 0, 0),
            },
            ImageDataDirectory {
                virtual_address: U32(0, 0, 0, 0),
                size: U32(0, 0, 0, 0),
            },
        ],
    },
    common: CoffCommon {
        sections: SectionTable {
            sections: [
                ImageSectionHeader {
                    name: [
                        46,
                        116,
                        101,
                        120,
                        116,
                        0,
                        0,
                        0,
                    ],
                    virtual_size: U32(68, f4, a, 0),
                    virtual_address: U32(0, 10, 0, 0),
                    size_of_raw_data: U32(0, f6, a, 0),
                    pointer_to_raw_data: U32(0, 4, 0, 0),
                    pointer_to_relocations: U32(0, 0, 0, 0),
                    pointer_to_linenumbers: U32(0, 0, 0, 0),
                    number_of_relocations: U16(0, 0),
                    number_of_linenumbers: U16(0, 0),
                    characteristics: U32(20, 0, 0, 68),
                },
                ImageSectionHeader {
                    name: [
                        46,
                        114,
                        111,
                        100,
                        97,
                        116,
                        97,
                        0,
                    ],
                    virtual_size: U32(40, e0, 2, 0),
                    virtual_address: U32(0, 10, b, 0),
                    size_of_raw_data: U32(0, e2, 2, 0),
                    pointer_to_raw_data: U32(0, fa, a, 0),
                    pointer_to_relocations: U32(0, 0, 0, 0),
                    pointer_to_linenumbers: U32(0, 0, 0, 0),
                    number_of_relocations: U16(0, 0),
                    number_of_linenumbers: U16(0, 0),
                    characteristics: U32(40, 0, 0, 48),
                },
                ImageSectionHeader {
                    name: [
                        46,
                        100,
                        97,
                        116,
                        97,
                        0,
                        0,
                        0,
                    ],
                    virtual_size: U32(60, 3e, 2, 0),
                    virtual_address: U32(0, 0, e, 0),
                    size_of_raw_data: U32(0, 40, 2, 0),
                    pointer_to_raw_data: U32(0, dc, d, 0),
                    pointer_to_relocations: U32(0, 0, 0, 0),
                    pointer_to_linenumbers: U32(0, 0, 0, 0),
                    number_of_relocations: U16(0, 0),
                    number_of_linenumbers: U16(0, 0),
                    characteristics: U32(40, 0, 0, c8),
                },
                ImageSectionHeader {
                    name: [
                        46,
                        98,
                        115,
                        115,
                        0,
                        0,
                        0,
                        0,
                    ],
                    virtual_size: U32(3c, 4f, a, 0),
                    virtual_address: U32(0, 40, 10, 0),
                    size_of_raw_data: U32(0, 0, 0, 0),
                    pointer_to_raw_data: U32(0, 0, 0, 0),
                    pointer_to_relocations: U32(0, 0, 0, 0),
                    pointer_to_linenumbers: U32(0, 0, 0, 0),
                    number_of_relocations: U16(0, 0),
                    number_of_linenumbers: U16(0, 0),
                    characteristics: U32(80, 0, 0, c8),
                },
                ImageSectionHeader {
                    name: [
                        46,
                        115,
                        98,
                        97,
                        116,
                        0,
                        0,
                        0,
                    ],
                    virtual_size: U32(83, 0, 0, 0),
                    virtual_address: U32(0, 90, 1a, 0),
                    size_of_raw_data: U32(0, 2, 0, 0),
                    pointer_to_raw_data: U32(0, 1c, 10, 0),
                    pointer_to_relocations: U32(0, 0, 0, 0),
                    pointer_to_linenumbers: U32(0, 0, 0, 0),
                    number_of_relocations: U16(0, 0),
                    number_of_linenumbers: U16(0, 0),
                    characteristics: U32(40, 0, 0, 48),
                },
                ImageSectionHeader {
                    name: [
                        46,
                        114,
                        101,
                        108,
                        111,
                        99,
                        0,
                        0,
                    ],
                    virtual_size: U32(20, 20, 0, 0),
                    virtual_address: U32(0, a0, 1a, 0),
                    size_of_raw_data: U32(0, 22, 0, 0),
                    pointer_to_raw_data: U32(0, 1e, 10, 0),
                    pointer_to_relocations: U32(0, 0, 0, 0),
                    pointer_to_linenumbers: U32(0, 0, 0, 0),
                    number_of_relocations: U16(0, 0),
                    number_of_linenumbers: U16(0, 0),
                    characteristics: U32(40, 0, 0, 4a),
                },
            ],
        },
        symbols: SymbolTable {
            symbols: [],
            strings: StringTable {
                data: None,
                start: 0,
                end: 0,
                marker: PhantomData<&()>,
            },
        },
        image_base: 0,
    },
}

I hope these will help you!

nix-enthusiast commented 8 months ago

Forget to say: I realize it's my bad. dumpbin /dependents command also throws error with this executable. Sorry for false alert.