Add beginning program and section header parsing, slight cleanup and comments
This commit is contained in:
parent
0b6fc85612
commit
80d346ae03
73
src/elf.rs
73
src/elf.rs
|
|
@ -1,5 +1,15 @@
|
||||||
|
// elf.rs
|
||||||
|
// Author: Garrett Dickinson
|
||||||
|
// Created: 02/02/2023
|
||||||
|
// Description: Provides constant and struct definitions for data
|
||||||
|
// structures related to the ELF binary specification
|
||||||
|
|
||||||
// Generic ELF information offsets.
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
///
|
||||||
|
/// Generic ELF information offsets.
|
||||||
|
///
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
pub const MAGIC_NUMBER: &[u8] = &[0x7F,0x45,0x4C,0x46];
|
pub const MAGIC_NUMBER: &[u8] = &[0x7F,0x45,0x4C,0x46];
|
||||||
pub const ARCH_OFFSET: u8 = 0x04; // x86 or x64 indiicator; 1 byte
|
pub const ARCH_OFFSET: u8 = 0x04; // x86 or x64 indiicator; 1 byte
|
||||||
|
|
@ -9,10 +19,14 @@ pub const TYPE_OFFSET: u8 = 0x10; // Object type identifier; 2 bytes
|
||||||
pub const MACHINE_OFFSET: u8 = 0x12; // Instruction set type; 2 bytes
|
pub const MACHINE_OFFSET: u8 = 0x12; // Instruction set type; 2 bytes
|
||||||
|
|
||||||
|
|
||||||
// Offsets for file header entry points and table inforamtion.
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// Arrayed offset are split by architecture:
|
///
|
||||||
// 0 : x86
|
/// Offsets for file header entry points and table information.
|
||||||
// 1 : x86_64
|
/// Arrayed offset are split by architecture:
|
||||||
|
/// 0 : x86
|
||||||
|
/// 1 : x86_64
|
||||||
|
///
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
pub const ENTRYPOINT_OFFSET: u8 = 0x18;
|
pub const ENTRYPOINT_OFFSET: u8 = 0x18;
|
||||||
pub const PHOFF_OFFSET: [u8; 2] = [0x1C, 0x20]; // Program header table pointer; 2 bytes
|
pub const PHOFF_OFFSET: [u8; 2] = [0x1C, 0x20]; // Program header table pointer; 2 bytes
|
||||||
|
|
@ -25,8 +39,49 @@ pub const SHNUM_OFFSET: [u8; 2] = [0x30, 0x3C]; // Number of entries in s
|
||||||
pub const SHSTRNDX_OFFSET: [u8; 2] = [0x32, 0x3E]; // Index of section header that contains names; 2 bytes
|
pub const SHSTRNDX_OFFSET: [u8; 2] = [0x32, 0x3E]; // Index of section header that contains names; 2 bytes
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
///
|
||||||
|
/// Offsets for program header information.
|
||||||
|
/// Arrayed offset are split by architecture:
|
||||||
|
/// 0 : x86
|
||||||
|
/// 1 : x86_64
|
||||||
|
///
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
pub const PH_TYPE_OFFSET: u8 = 0x00;
|
||||||
|
pub const PH_FLAGS_OFFSET: [u8; 2] = [0x18, 0x04];
|
||||||
|
pub const PH_OFFSET_OFFSET: [u8; 2] = [0x04, 0x08];
|
||||||
|
pub const PH_VADDR_OFFSET: [u8; 2] = [0x08, 0x10];
|
||||||
|
pub const PH_PADDR_OFFSET: [u8; 2] = [0x0C, 0x18];
|
||||||
|
pub const PH_FILESZ_OFFSET: [u8; 2] = [0x10, 0x20];
|
||||||
|
pub const PH_MEMSZ_OFFSET: [u8; 2] = [0x14, 0x28];
|
||||||
|
pub const PH_ALIGN_OFFSET: [u8; 2] = [0x1C, 0x30];
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
///
|
||||||
|
/// Offsets for section header information.
|
||||||
|
/// Arrayed offset are split by architecture:
|
||||||
|
/// 0 : x86
|
||||||
|
/// 1 : x86_64
|
||||||
|
///
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
pub const SH_NAME_OFFSET: u8 = 0x00;
|
||||||
|
pub const SH_TYPE_OFFSET: u8 = 0x04;
|
||||||
|
pub const SH_FLAGS_OFFSET: u8 = 0x08;
|
||||||
|
pub const SH_ADDR_OFFSET: [u8; 2] = [0x0C, 0x10];
|
||||||
|
pub const SH_OFFSET_OFFSET: [u8; 2] = [0x10, 0x18];
|
||||||
|
pub const SH_SIZE_OFFSET: [u8; 2] = [0x14, 0x20];
|
||||||
|
pub const SH_LINK_OFFSET: [u8; 2] = [0x18, 0x28];
|
||||||
|
pub const SH_INFO_OFFSET: [u8; 2] = [0x1C, 0x2C];
|
||||||
|
pub const SH_ADDRALIGN_OFFSET: [u8; 2] = [0x20, 0x30];
|
||||||
|
pub const SH_ENTSIZE_OFFSET: [u8; 2] = [0x24, 0x38];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum ArchitecureType {
|
pub enum ArchitectureType {
|
||||||
X86,
|
X86,
|
||||||
X86_64,
|
X86_64,
|
||||||
Unknown
|
Unknown
|
||||||
|
|
@ -40,10 +95,13 @@ pub enum EndianType {
|
||||||
Unknown
|
Unknown
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Types in structs for holding addresses are most likely
|
||||||
|
// too small, increase to u32 maybe?
|
||||||
|
// Refer to structs in /usr/include/elf.h for this
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct FileHeader {
|
pub struct FileHeader {
|
||||||
pub arch: ArchitecureType,
|
pub arch: ArchitectureType,
|
||||||
pub is_x86_64: bool,
|
pub is_x86_64: bool,
|
||||||
pub endian: EndianType,
|
pub endian: EndianType,
|
||||||
pub abi: u8,
|
pub abi: u8,
|
||||||
|
|
@ -69,6 +127,7 @@ pub struct ProgramHeader {
|
||||||
pub vaddr: u8,
|
pub vaddr: u8,
|
||||||
pub paddr: u8,
|
pub paddr: u8,
|
||||||
pub filesz: u8,
|
pub filesz: u8,
|
||||||
|
pub memsz: u8,
|
||||||
pub align: u8,
|
pub align: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
74
src/main.rs
74
src/main.rs
|
|
@ -43,11 +43,33 @@ fn main() {
|
||||||
// Build the File Header data structure
|
// Build the File Header data structure
|
||||||
let file_header: elf::FileHeader = build_file_header(bytes);
|
let file_header: elf::FileHeader = build_file_header(bytes);
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: This is fundamentally wrong. Using the phentsize and phnum
|
||||||
|
// values from the file header, iterate over the program header
|
||||||
|
// table to find all of the individual program headers. There is
|
||||||
|
// not just one over-arching program header
|
||||||
|
|
||||||
// Build Program Header data structure
|
// Build Program Header data structure
|
||||||
//let program_header: elf::ProgramHeader = build_program_header(bytes, file_header.is_x86_64);
|
let program_header: elf::ProgramHeader = build_program_header(
|
||||||
|
bytes,
|
||||||
|
file_header.phoff,
|
||||||
|
file_header.is_x86_64
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: Same thing applies for the Section Headers...
|
||||||
|
|
||||||
|
// Build Section Header data structure
|
||||||
|
let section_header: elf::SectionHeader = build_section_header(
|
||||||
|
bytes,
|
||||||
|
file_header.shoff,
|
||||||
|
file_header.is_x86_64
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
println!("{:?}", file_header);
|
println!("{:?}", file_header);
|
||||||
//println!("{:?}", program_header);
|
println!("{:?}", program_header);
|
||||||
|
println!("{:?}", section_header);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
println!("[Error] Could not find magic number, is this an ELF executable?")
|
println!("[Error] Could not find magic number, is this an ELF executable?")
|
||||||
|
|
@ -91,15 +113,47 @@ fn build_file_header(data: &Vec<u8>) -> elf::FileHeader {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// fn build_program_header(data: &Vec<u8>, is_x86_64: bool) -> elf::ProgramHeader {
|
fn build_program_header(data: &Vec<u8>, phoffset: u8, is_x86_64: bool) -> elf::ProgramHeader {
|
||||||
|
|
||||||
// let arch: i8 = if is_x86_64 { 1 } else { 0 };
|
// Cast the supplied is_x86_64 bool to an array offset
|
||||||
|
// 0 : x86
|
||||||
|
// 1 : x64
|
||||||
|
let arch: usize = is_x86_64.into();
|
||||||
|
|
||||||
// let mut program_header: elf::ProgramHeader;
|
let program_header: elf::ProgramHeader = elf::ProgramHeader {
|
||||||
|
program_type: data[(elf::PH_TYPE_OFFSET + phoffset) as usize],
|
||||||
|
flags: data[(elf::PH_FLAGS_OFFSET[arch] + phoffset) as usize],
|
||||||
|
offset: data[(elf::PH_OFFSET_OFFSET[arch] + phoffset) as usize],
|
||||||
|
vaddr: data[(elf::PH_VADDR_OFFSET[arch] + phoffset) as usize],
|
||||||
|
paddr: data[(elf::PH_PADDR_OFFSET[arch] + phoffset) as usize],
|
||||||
|
filesz: data[(elf::PH_FILESZ_OFFSET[arch] + phoffset) as usize],
|
||||||
|
memsz: data[(elf::PH_MEMSZ_OFFSET[arch] + phoffset) as usize],
|
||||||
|
align: data[(elf::PH_ALIGN_OFFSET[arch] + phoffset) as usize],
|
||||||
|
};
|
||||||
|
|
||||||
// // let mut program_header: elf::ProgramHeader = elf::ProgramHeader {
|
return program_header;
|
||||||
// // arch: util::parse_architecture(data[elf::ARCH_OFFSET as usize])
|
}
|
||||||
// // };
|
|
||||||
|
|
||||||
// return program_header;
|
|
||||||
// }
|
fn build_section_header(data: &Vec<u8>, shoffset: u8, is_x86_64: bool) -> elf::SectionHeader {
|
||||||
|
|
||||||
|
// Cast the supplied is_x86_64 bool to an array offset
|
||||||
|
// 0 : x86
|
||||||
|
// 1 : x64
|
||||||
|
let arch: usize = is_x86_64.into();
|
||||||
|
|
||||||
|
let section_header: elf::SectionHeader = elf::SectionHeader {
|
||||||
|
name: data[(elf::SH_NAME_OFFSET + shoffset) as usize],
|
||||||
|
section_type: data[(elf::SH_TYPE_OFFSET + shoffset) as usize],
|
||||||
|
flags: data[(elf::SH_FLAGS_OFFSET + shoffset) as usize],
|
||||||
|
addr: data[(elf::SH_ADDR_OFFSET[arch] + shoffset) as usize],
|
||||||
|
offset: data[(elf::SH_OFFSET_OFFSET[arch] + shoffset) as usize],
|
||||||
|
size: data[(elf::SH_SIZE_OFFSET[arch] + shoffset) as usize],
|
||||||
|
link: data[(elf::SH_LINK_OFFSET[arch] + shoffset) as usize],
|
||||||
|
info: data[(elf::SH_INFO_OFFSET[arch] + shoffset) as usize],
|
||||||
|
addralign: data[(elf::SH_ADDRALIGN_OFFSET[arch] + shoffset) as usize],
|
||||||
|
entsize: data[(elf::SH_ENTSIZE_OFFSET[arch] + shoffset) as usize],
|
||||||
|
};
|
||||||
|
|
||||||
|
return section_header;
|
||||||
|
}
|
||||||
16
src/util.rs
16
src/util.rs
|
|
@ -1,4 +1,10 @@
|
||||||
use crate::elf::{self, EndianType, ArchitecureType};
|
// util.rs
|
||||||
|
// Author: Garrett Dickinson
|
||||||
|
// Created: 02/02/2023
|
||||||
|
// Description: Utility script for storing common-use and helper
|
||||||
|
// functions.
|
||||||
|
|
||||||
|
use crate::elf::{self, EndianType, ArchitectureType};
|
||||||
|
|
||||||
|
|
||||||
pub fn parse_endian(endian: u8) -> elf::EndianType {
|
pub fn parse_endian(endian: u8) -> elf::EndianType {
|
||||||
|
|
@ -10,11 +16,11 @@ pub fn parse_endian(endian: u8) -> elf::EndianType {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn parse_architecture(arch: u8) -> elf::ArchitecureType {
|
pub fn parse_architecture(arch: u8) -> elf::ArchitectureType {
|
||||||
match arch {
|
match arch {
|
||||||
0x01 => return ArchitecureType::X86,
|
0x01 => return ArchitectureType::X86,
|
||||||
0x02 => return ArchitecureType::X86_64,
|
0x02 => return ArchitectureType::X86_64,
|
||||||
_ => return ArchitecureType::Unknown
|
_ => return ArchitectureType::Unknown
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user