Add program/section header parser

This commit is contained in:
mii
2021-11-28 23:19:02 +09:00
parent 06a254df2f
commit fad3a21b1f
3 changed files with 204 additions and 22 deletions

View File

@ -1,16 +1,126 @@
use nom::{IResult, bytes::complete::tag, number::complete::{le_u16, le_u32, le_u64}}; use nom::{IResult, bytes::complete::{tag, take}, number::complete::{le_u16, le_u32, le_u64}};
use crate::elf_struct::ElfHeader; use crate::elf_struct::{Elf, ElfHeader, ProgramHeader, SectionHeader};
pub struct ElfParser { pub struct ElfParser {
pub file: Vec<u8> pub file: Vec<u8>
} }
impl ElfParser { impl ElfParser {
pub fn parse_header(input: &[u8]) -> IResult<&[u8], u64> {
let (input, ident) = le_u64(input)?; pub fn parse(&mut self) -> IResult<&[u8], Elf> {
let (input_headerless, elf_header) = ElfParser::parse_header(&self.file)?;
let (mut input, _) = take(elf_header.program_header_offset - 64)(input_headerless)?;
let mut program_header_counter = 0;
let mut program_headers: Vec<ProgramHeader> = vec![];
while program_header_counter < elf_header.program_header_num {
let (input_tmp, program_header) = ElfParser::parse_program_header(input)?;
program_headers.push(program_header);
input = input_tmp;
program_header_counter += 1;
}
let (mut input, _) = take(elf_header.section_header_offset - 64)(input_headerless)?;
let mut section_header_counter = 0;
let mut section_headers: Vec<SectionHeader> = vec![];
while section_header_counter < elf_header.section_header_num {
let (input_tmp, section_header) = ElfParser::parse_section_header(input)?;
section_headers.push(section_header);
input = input_tmp;
section_header_counter += 1;
}
Ok((input, Elf {
header: elf_header,
program_headers,
section_headers
}))
}
pub fn parse_section_header(input: &[u8]) -> IResult<&[u8], SectionHeader> {
let (input, name) = le_u32(input)?;
let (input, section_header_type) = le_u32(input)?;
let (input, flags) = le_u64(input)?;
let (input, address) = le_u64(input)?;
let (input, offset) = le_u64(input)?;
let (input, size) = le_u64(input)?;
let (input, link) = le_u32(input)?;
let (input, info) = le_u32(input)?;
let (input, align) = le_u64(input)?;
let (input, entry_size) = le_u64(input)?;
Ok((input, SectionHeader {
name,
section_header_type,
flags,
address,
offset,
size,
link,
info,
align,
entry_size
}))
}
pub fn parse_program_header(input: &[u8]) -> IResult<&[u8], ProgramHeader> {
let (input, program_type) = le_u32(input)?;
let (input, flags) = le_u32(input)?;
let (input, offset) = le_u64(input)?;
let (input, virtual_address) = le_u64(input)?;
let (input, physical_address) = le_u64(input)?;
let (input, file_size) = le_u64(input)?;
let (input, memory_size) = le_u64(input)?;
let (input, align) = le_u64(input)?;
Ok((input, ProgramHeader {
program_type,
flags,
offset,
virtual_address,
physical_address,
file_size,
memory_size,
align
}))
}
pub fn parse_header(input: &[u8]) -> IResult<&[u8], ElfHeader> {
let (input, ident_1) = le_u64(input)?;
let (input, ident_2) = le_u64(input)?;
let (input, elf_type) = le_u16(input)?; let (input, elf_type) = le_u16(input)?;
let (input, machine) = le_u16(input)?;
let (input, version) = le_u32(input)?; let (input, version) = le_u32(input)?;
Ok((input, ident)) let (input, entry) = le_u64(input)?;
let (input, program_header_offset) = le_u64(input)?;
let (input, section_header_offset) = le_u64(input)?;
let (input, flags) = le_u32(input)?;
let (input, elf_header_size) = le_u16(input)?;
let (input, program_header_entry_size) = le_u16(input)?;
let (input, program_header_num) = le_u16(input)?;
let (input, section_header_entry_size) = le_u16(input)?;
let (input, section_header_num) = le_u16(input)?;
let (input, section_header_name_index) = le_u16(input)?;
Ok((input, ElfHeader {
ident: (ident_1, ident_2),
elf_type,
machine,
version,
entry,
program_header_offset,
section_header_offset,
flags,
elf_header_size,
program_header_entry_size,
program_header_num,
section_header_entry_size,
section_header_num,
section_header_name_index
}))
} }
} }
// 192

View File

@ -1,6 +1,27 @@
#[derive(Debug)] #[derive(Debug)]
pub struct Elf {
pub header: ElfHeader,
pub program_headers: Vec<ProgramHeader>,
pub section_headers: Vec<SectionHeader>
}
#[derive(Debug)]
pub struct SectionHeader {
pub name: u32,
pub section_header_type: u32,
pub flags: u64,
pub address: u64,
pub offset: u64,
pub size: u64,
pub link: u32,
pub info: u32,
pub align: u64,
pub entry_size: u64
}
#[derive(Debug, Clone, Copy)]
pub struct ElfHeader { pub struct ElfHeader {
pub magic_number: u64, pub ident: (u64, u64),
pub elf_type: u16, pub elf_type: u16,
pub machine: u16, pub machine: u16,
pub version: u32, pub version: u32,
@ -15,3 +36,54 @@ pub struct ElfHeader {
pub section_header_num: u16, pub section_header_num: u16,
pub section_header_name_index: u16 pub section_header_name_index: u16
} }
/*
+-----------------------------------------------+
|e_ident[EI_NIDENT] |
+-----------------------------------------------+
|7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00|
+-----+-----+-----------+-----------------------+
|type |mach |ver |e_entry |
+-----+-----+-----------+-----------------------+
|02 00|3e 00|01 00 00 00|78 00 40 00 00 00 00 00|
+-----+-----+-----------+-----------------------+
|e_phoff |e_shoff |
+-----------------------+-----------------------+
|40 00 00 00 00 00 00 00|00 00 00 00 00 00 00 00|
+-----------+-----+-----+-----+-----+-----+-----+
|e_flags |ehsiz|phesi|phnum|shesi|shnum|shstr|
+-----------+-----+-----+-----+-----+-----+-----+
|00 00 00 00|40 00|38 00|01 00|40 00|00 00|00 00|
+-----------+-----+-----+-----+-----+-----+-----+
*/
#[derive(Debug)]
pub struct ProgramHeader {
pub program_type: u32,
pub flags: u32,
pub offset: u64,
pub virtual_address: u64,
pub physical_address: u64,
pub file_size: u64,
pub memory_size: u64,
pub align: u64
}
/*
+-----------+-----------+-----------------------+
|p_type |p_flags |p_offset |
+-----------+-----------+-----------------------+
|01 00 00 00|07 00 00 00|00 00 00 00 00 00 00 00|
+-----------+-----------+-----------------------+
|p_vaddr |p_paddr |
+-----------------------+-----------------------+
|00 00 40 00 00 00 00 00|00 00 40 00 00 00 00 00|
+-----------------------+-----------------------+
|p_filesz |p_memsz |
+-----------------------+-----------------------+
|90 00 00 00 00 00 00 00|90 00 00 00 00 00 00 00|
+-----------------------+-----------------------+
|p_align |
+-----------------------+
|00 00 20 00 00 00 00 00|
+-----------------------+
*/

View File

@ -5,23 +5,23 @@ use std::io::Read;
use crate::elf_parser::ElfParser; use crate::elf_parser::ElfParser;
fn main() { fn main() {
println!("Hello, world!");
let mut file = std::fs::File::open("./test.elf").expect("Failed to open a file."); let mut file = std::fs::File::open("./test.elf").expect("Failed to open a file.");
let mut buf = Vec::new(); let mut buf = Vec::new();
file.read_to_end(&mut buf).expect("Failed to read a file."); file.read_to_end(&mut buf).expect("Failed to read a file.");
let mut elf_parser = ElfParser { file: buf }; let mut elf_parser = ElfParser { file: buf };
match ElfParser::parse_header(&elf_parser.file) { match elf_parser.parse() {
Ok(input) => { Ok((_, elf)) => {
println!("{:?}", input.0[0]); println!("{:?}", elf.header);
println!("{:?}", input.0[1]); for program_header in elf.program_headers {
println!("{:?}", input.0[2]); println!("{:?}", program_header);
println!("{:?}", input.0[3]); }
println!("{:?}", input.1);
for section_header in elf.section_headers {
println!("{:?}", section_header);
}
}, },
Err(_) => { Err(_) => {}
println!("Error.");
} }
} }
} // 1236
// 282584257676671