use std::{env::args, fs::File, io::Read}; fn main() { let args: Vec = args().collect(); if args.len() != 2 { panic!("usage: demo ") } let mut f = File::open(&args[1]).expect("failed to open elf-file"); let mut buf = Vec::with_capacity(4096); let _ = f.read_to_end(&mut buf).expect("failed to read elf-file"); let parser = pelf::parser::ElfParserConfig::new().build(); let elf = parser .parse_elf_file(&buf) .expect("failed to parse elf-file"); match elf { pelf::file::ElfFile::Elf64(elf64) => { dump_elf64_file(elf64); } _ => unimplemented!(), } } fn dump_elf64_file(elf: pelf::file::Elf64File) { dump_elf64_header(&elf.header); dump_elf64_program_header_table(&elf.program_headers); dump_elf64_section_header_table(&elf.sections); dump_elf64_sections(&elf.sections); } fn dump_elf64_header(header: &pelf::header::Elf64Header) { println!("ELF Header:"); println!(" Class: {}", header.ident.class); println!(" Data: {}", header.ident.data); println!(" File Version: {}(Current)", header.ident.version); println!(" Type: {}", header.elf_type); println!(" Machine: {}", header.machine); println!(" Version: 0x{:x}", header.version); println!(" Entry: 0x{:x}", header.entry); println!(" PHT Offset: 0x{:x}", header.phoff); println!(" SHT Offset: 0x{:x}", header.shoff); // println!(" Flags: 0b{:b}", header.e_flags); println!(" PHT Entry Size: 0x{:x}", header.phentsize); println!(" PHT Entries: {}", header.phnum); println!(" SHT Entry Size: 0x{:x}", header.shentsize); println!(" SHT Entries: {}", header.shnum); println!(" Section Header String Table Index: {}", header.shstrndx); } fn dump_elf64_program_header_table(phdrs: &pelf::program_header::Elf64ProgramHeaderTable) { if phdrs.len() == 0 { println!("there is no program header table"); return; } println!("Program Header Table:"); for (i, phdr) in phdrs.iter().enumerate() { println!(" [{}]:", i); println!(" Type: {}", phdr.header_type); println!(" Flags: 0b{:b}", phdr.flags); println!(" Offset: 0x{:x}", phdr.offset); println!(" Virtual Address: 0x{:x}", phdr.vaddr); println!(" Physical Address: 0x{:x}", phdr.paddr); println!(" Size in File: 0x{:x}", phdr.filesz); println!(" Size in Memory: 0x{:x}", phdr.memsz); println!(" Alignment: 0x{:x}", phdr.align); } } fn dump_elf64_section_header_table(sections: &pelf::section::Elf64Sections) { if sections.len() == 0 { println!("there is no section header table"); return; } println!("Section Header Table:"); for (i, sct) in sections.iter().enumerate() { println!(" [{}]:", i); println!(" Name Index: 0x{:x}", sct.header.name); println!(" Type: {}", sct.header.section_type); println!(" Flags: 0b{:b}", sct.header.flags); println!(" Address: 0x{:x}", sct.header.addr); println!(" Offset: 0x{:x}", sct.header.offset); println!(" Size: 0x{:x}", sct.header.size); println!(" Link: 0x{:x}", sct.header.link); println!(" Info: 0x{:x}", sct.header.info); println!(" Address Alignment: 0x{:x}", sct.header.addralign); println!(" Entry Size: 0x{:x}", sct.header.entsize); } } fn dump_elf64_sections(sections: &pelf::section::Elf64Sections) { if sections.len() == 0 { println!("there is no sections"); return; } println!("Sections:"); for (i, sct) in sections.iter().enumerate() { match &sct.data { pelf::section::Elf64SectionData::RawSymbolTable { symbols } => { println!( " Sections[{}] Symbol Table Entries: {}", i, symbols.len() ); } pelf::section::Elf64SectionData::StringTable { table } => { println!( " Sections[{}] String Table Entries: {}", i, table.entries.len() ); } pelf::section::Elf64SectionData::Raw { bytes } => { println!(" Sections[{}] Raw Data Length : {}", i, bytes.len()); } } } }