Chapter 06無料公開

Program Header Table

Drumato
Drumato
2021.08.29に更新
このチャプターの目次

Program Header Table

linkerが生成する,program header tableのparserもサクッと書いてしまいましょう.
実はこのheaderにはnameの情報が含まれていないので,
section header tableより大分かんたんだったりします.

readelfなどを使うとsectionとsegmentのmappingが見れたりしますが,
そういう機能は今回作りません.
実用的なtoolを作る場合はchallengeしてみてください.

やり方は全く同じです.

  • elf headerを読む
  • header.pht_offset から sizeof(Elf64_Phdr) * header.pht_entries 分読んでdeserialize

注意点として,relocatable object fileなどにprogram header tableは存在しません.

parser

// src/parser/program_header.rs
pub fn parse_64bit_program_header_table<'a>(
    entries: usize,
) -> impl Fn(&'a [u8]) -> IResult<&'a [u8], Vec<ProgramHeader64>> {
    move |raw: &'a [u8]| count(parse_64bit_program_header, entries)(raw)
}

fn parse_segment_type(raw: &[u8]) -> IResult<&[u8], SegmentType> {
    map(le_u32, |v| SegmentType::from(v))(raw)
}

fn parse_64bit_program_header(raw: &[u8]) -> IResult<&[u8], ProgramHeader64> {
    let (r, ty) = parse_segment_type(raw)?;
    let (r, flags) = le_u32(r)?;
    let (r, offset) = le_u64(r)?;
    let (r, virtual_addr) = le_u64(r)?;
    let (r, physical_addr) = le_u64(r)?;
    let (r, size_in_file) = le_u64(r)?;
    let (r, size_in_mem) = le_u64(r)?;
    let (r, align) = le_u64(r)?;

    Ok((
        r,
        ProgramHeader64 {
            ty,
            flags,
            offset,
            virtual_addr,
            physical_addr,
            size_in_file,
            size_in_mem,
            align,
        },
    ))
}

src/main.rs 等も適当に改変を加えます.
実行結果は次のようになります.

ProgramHeader[0]:
        Type: Phdr
        VirtAddr: 0x40
        PhysAddr: 0x40
        FileSize: 0x2a0
        MemSize: 0x2a0
ProgramHeader[1]:
        Type: Interp
        VirtAddr: 0x2e0
        PhysAddr: 0x2e0
        FileSize: 0x1c
        MemSize: 0x1c
ProgramHeader[2]:
        Type: Load
        VirtAddr: 0x0
        PhysAddr: 0x0
        FileSize: 0x6990
        MemSize: 0x6990
ProgramHeader[3]:
        Type: Load
        VirtAddr: 0x7000
        PhysAddr: 0x7000
        FileSize: 0x50069
        MemSize: 0x50069
# stripped