use std::{env::args, fs::File, io::Read};
fn main() {
let args: Vec<String> = args().collect();
if args.len() != 2 {
panic!("usage: demo <elf-filepath>")
}
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!(" 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());
}
}
}
}