diff --git a/src/elf.rs b/src/elf.rs index 735a05d..6c01bc8 100644 --- a/src/elf.rs +++ b/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 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 -// Offsets for file header entry points and table inforamtion. -// Arrayed offset are split by architecture: -// 0 : x86 -// 1 : x86_64 +/////////////////////////////////////////////////////////////////////////////// +/// +/// Offsets for file header entry points and table information. +/// Arrayed offset are split by architecture: +/// 0 : x86 +/// 1 : x86_64 +/// +/////////////////////////////////////////////////////////////////////////////// pub const ENTRYPOINT_OFFSET: u8 = 0x18; 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 +/////////////////////////////////////////////////////////////////////////////// +/// +/// 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)] -pub enum ArchitecureType { +pub enum ArchitectureType { X86, X86_64, Unknown @@ -40,10 +95,13 @@ pub enum EndianType { 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)] pub struct FileHeader { - pub arch: ArchitecureType, + pub arch: ArchitectureType, pub is_x86_64: bool, pub endian: EndianType, pub abi: u8, @@ -69,6 +127,7 @@ pub struct ProgramHeader { pub vaddr: u8, pub paddr: u8, pub filesz: u8, + pub memsz: u8, pub align: u8, } diff --git a/src/main.rs b/src/main.rs index 7474916..862811a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -43,11 +43,33 @@ fn main() { // Build the File Header data structure 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 - //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!("{:?}", program_header); + println!("{:?}", program_header); + println!("{:?}", section_header); } else { println!("[Error] Could not find magic number, is this an ELF executable?") @@ -91,15 +113,47 @@ fn build_file_header(data: &Vec) -> elf::FileHeader { } -// fn build_program_header(data: &Vec, is_x86_64: bool) -> elf::ProgramHeader { +fn build_program_header(data: &Vec, 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 { -// // arch: util::parse_architecture(data[elf::ARCH_OFFSET as usize]) -// // }; + return program_header; +} -// return program_header; -// } \ No newline at end of file + +fn build_section_header(data: &Vec, 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; +} \ No newline at end of file diff --git a/src/util.rs b/src/util.rs index 83c3735..eaf2b37 100644 --- a/src/util.rs +++ b/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 { @@ -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 { - 0x01 => return ArchitecureType::X86, - 0x02 => return ArchitecureType::X86_64, - _ => return ArchitecureType::Unknown + 0x01 => return ArchitectureType::X86, + 0x02 => return ArchitectureType::X86_64, + _ => return ArchitectureType::Unknown } }