mirror of
https://github.com/mii443/elf-parser.git
synced 2025-08-22 15:05:43 +00:00
Add program/section header parser
This commit is contained in:
@ -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
|
@ -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|
|
||||||
|
+-----------------------+
|
||||||
|
*/
|
||||||
|
|
||||||
|
24
src/main.rs
24
src/main.rs
@ -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.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 282584257676671
|
// 1236
|
Reference in New Issue
Block a user