m4b / m4b/goblin

Failing to parse section headers of MIPS LE 32-bit ELF correctly on 64-bit PPC BE host

Open
#420 2 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
1.5k
Forks
202
PR merge metrics
No merged PRs in 30d

Description

Hello, I seem to have stumbled upon some endian-awareness issues, unless you think I'm somehow misusing the library.

I have this goblin program (simplified from my actual usecase for ease of troubleshooting)

use std::fs;
use goblin::elf32::{header::Header, section_header::SectionHeader, section_header::SHT_REL};

fn main() {
    let elf_bytes = fs::read("psp-cube-example").unwrap();
    let header = Header::parse(&elf_bytes).unwrap();

    let section_headers = SectionHeader::from_bytes(
        &elf_bytes[header.e_shoff as usize..],
        header.e_shnum as usize,
    );

    let reloc_count = section_headers.iter().filter(|sh| sh.sh_type == SHT_REL).count();
    println!("reloc_count: {}", reloc_count);
    println!("section_headers: {:?}", section_headers);
}

and I have this 32-bit MIPS2 LE ELF file (uploaded as zip because github is dumb)
psp-cube-example.zip

When I run this program on x86_64 Little Endian - I get the correct result.
goblin_repro_x86_64.txt

When I run this program on 64-bit PowerPC - I do not.
goblin_repro_ppc64.txt

I am using the default endian_fd feature of goblin.

Here is the output of readelf -S

paul@ps3:~/goblin-repro$ readelf -S psp-cube-example
There are 34 section headers, starting at offset 0x46d44:

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .text             PROGBITS        00000000 000120 00af20 00  AX  0   0 16
  [ 2] .sceStub.text     PROGBITS        0000af20 00b040 0000b8 00   A  0   0  4
  [ 3] .lib.stub.top     PROGBITS        0000afd8 00b0f8 000004 00   A  0   0  4
  [ 4] .lib.stub         PROGBITS        0000afdc 00b0fc 000078 00   A  0   0  4
  [ 5] .lib.stub.btm     PROGBITS        0000b054 00b174 000004 00   A  0   0  4
  [ 6] .lib.ent.top      PROGBITS        0000b058 00b178 000004 00   A  0   0  4
  [ 7] .lib.ent          PROGBITS        0000b05c 00b17c 000010 00   A  0   0  1
  [ 8] .lib.ent.btm      PROGBITS        0000b06c 00b18c 000004 00   A  0   0  4
  [ 9] .eh_frame_hdr     PROGBITS        0000b070 00b190 0005cc 00   A  0   0  4
  [10] .eh_frame         PROGBITS        0000b63c 00b75c 0014d4 00   A  0   0  4
  [11] .rodata.sceR[...] PROGBITS        0000cb10 00cc30 000074 00   A  0   0  4
  [12] .rodata.sceM[...] PROGBITS        0000cb90 00ccb0 000040 00   A  0   0 16
  [13] .rodata.sceNid    PROGBITS        0000cbd0 00ccf0 00005c 00   A  0   0  4
  [14] .rodata           PROGBITS        0000cc30 00cd50 011e22 00 AMS  0   0 16
  [15] .data             PROGBITS        0001ea54 01eb74 000068 00  WA  0   0  4
  [16] .got              PROGBITS        0001eac0 01ebe0 000008 00 WAp  0   0 16
  [17] .gcc_except_table PROGBITS        0001eac8 01ebe8 000dd8 00   A  0   0  4
  [18] .bss              NOBITS          0001f8a0 01f9c0 1030a4 00  WA  0   0 16
  [19] .mdebug.abi32     PROGBITS        00000000 01f9c0 000000 00      0   0  1
  [20] .rel.text         REL             00000000 01f9c0 002f68 08   I 31   1  4
  [21] .pdr              PROGBITS        00000000 022928 0151a0 00      0   0  4
  [22] .rel.pdr          REL             00000000 037ac8 005468 08   I 31  21  4
  [23] .rel.rodata       REL             00000000 03cf30 000f78 08   I 31  14  4
  [24] .rel.rodata.[...] REL             00000000 03dea8 000028 08   I 31  12  4
  [25] .rel.lib.ent      REL             00000000 03ded0 000008 08   I 31   7  4
  [26] .rel.rodata.[...] REL             00000000 03ded8 000010 08   I 31  11  4
  [27] .rel.data         REL             00000000 03dee8 000048 08   I 31  15  4
  [28] .comment          PROGBITS        00000000 03df30 0000bf 01  MS  0   0  1
  [29] .rel.lib.stub     REL             00000000 03dff0 000090 08   I 31   4  4
  [30] .rel.sceStub.text REL             00000000 03e080 000170 08   I 31   2  4
  [31] .symtab           SYMTAB          00000000 03e1f0 002c20 10     33 504  4
  [32] .shstrtab         STRTAB          00000000 040e10 000197 00      0   0  1
  [33] .strtab           STRTAB          00000000 040fa7 005d9b 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  D (mbind), p (processor specific)

Let me know if there's any other details you need, I hope you may be able to reproduce using qemu-system-ppc64, but I have not explored it myself.

For extra background on what I'm actually doing, because it's kind of fun 😄
I'm trying to use rust-psp to compile a psp homebrew app on a ps3 running linux. And I hit this assertion in our psp executable repacker: https://github.com/overdrivenpotato/rust-psp/blob/bfaa487ea4881395cc64fdd82158745885222a29/cargo-psp/src/bin/prxgen.rs#L98

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the issue through elf32::header::Header::parse and section_header::SectionHeader::from_bytes using the provided MIPS LE ELF on a 64-bit PPC BE host. Compare the parsed section headers and relocation count with readelf -S and the x86_64 output, then confirm that the result is correct on both endiannesses. The related assertion is in cargo-psp/src/bin/prxgen.rs.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
reverse-engineering
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.