Last active
February 17, 2024 04:10
-
-
Save n4sm/bde3e34afac9de5713819d01bb1b02b9 to your computer and use it in GitHub Desktop.
A very small elf parser developped in rust (only the executable header for now)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::fs::File; | |
use std::fs::{OpenOptions}; | |
use std::io::{Read}; | |
//use std::mem::{size_of, transmute}; | |
/* | |
typedef struct | |
{ | |
unsigned char e_ident[EI_NIDENT]; // Magic number and other info | |
Elf64_Half e_type; // Object file type | |
Elf64_Half e_machine; //Architecture | |
Elf64_Word e_version; // Object file version | |
Elf64_Addr e_entry; // Entry point virtual address | |
Elf64_Off e_phoff; // Program header table file offset | |
Elf64_Off e_shoff; // Section header table file offset | |
Elf64_Word e_flags; // Processor-specific flags | |
Elf64_Half e_ehsize; // ELF header size in bytes | |
Elf64_Half e_phentsize; // Program header table entry size | |
Elf64_Half e_phnum; // Program header table entry count | |
Elf64_Half e_shentsize; // Section header table entry size | |
Elf64_Half e_shnum; // Section header table entry count | |
Elf64_Half e_shstrndx; // Section header string table index | |
} Elf64_Ehdr; | |
*/ | |
type Elf64_Half = u16; | |
type Elf64_Word = u32; | |
type Elf64_Addr = u64; | |
type Elf64_Off = u64; | |
#[repr(C, packed)] | |
struct Elf64_Ehdr { | |
e_ident: [u8; 16], | |
e_type: Elf64_Half, | |
e_machine: Elf64_Half, | |
e_version: Elf64_Word, | |
e_entry: Elf64_Addr, | |
e_phoff: Elf64_Off, | |
e_shoff: Elf64_Off, | |
e_flags: Elf64_Word, | |
e_ehsize: Elf64_Half, | |
e_phentsize: Elf64_Half, | |
e_phnum: Elf64_Half, | |
e_shentsize: Elf64_Half, | |
e_shnum: Elf64_Half, | |
e_shstrndx: Elf64_Half | |
} | |
trait Elf_structs { | |
fn clone(&self) -> Self; | |
} | |
impl Elf64_Ehdr { | |
fn new() -> Result<Self, ()> { | |
Ok( | |
Elf64_Ehdr { | |
e_ident: [0; 16], | |
e_type: 0, | |
e_machine: 0, | |
e_version: 0, | |
e_entry: 0, | |
e_phoff: 0, | |
e_shoff: 0, | |
e_flags: 0, | |
e_ehsize: 0, | |
e_phentsize: 0, | |
e_phnum: 0, | |
e_shentsize: 0, | |
e_shnum: 0, | |
e_shstrndx: 0 | |
} | |
) | |
} | |
} | |
impl Elf_structs for Elf64_Ehdr { | |
fn clone(&self) -> Self { | |
Elf64_Ehdr { | |
e_ident: self.e_ident.clone(), | |
e_type: self.e_type, | |
e_machine: self.e_machine, | |
e_version: self.e_version, | |
e_entry: self.e_entry, | |
e_phoff: self.e_phoff, | |
e_shoff: self.e_shoff, | |
e_flags: self.e_flags, | |
e_ehsize: self.e_ehsize, | |
e_phentsize: self.e_phentsize, | |
e_phnum: self.e_phnum, | |
e_shentsize: self.e_shentsize, | |
e_shnum: self.e_shnum, | |
e_shstrndx: self.e_shstrndx | |
} | |
} | |
} | |
fn parse_ehdr(fbuf: &[u8]) -> Result<Elf64_Ehdr, ()> { | |
let p: *const [u8; std::mem::size_of::<Elf64_Ehdr>()] = fbuf.as_ptr() as *const [u8; std::mem::size_of::<Elf64_Ehdr>()]; | |
Ok ( unsafe { std::mem::transmute(*p) } ) | |
} | |
fn open_wrapper(filename: &str) -> Result<(Vec<u8>, File), ()> { | |
let mut fd_w: File = OpenOptions::new() | |
.read(true) | |
.open(&filename) | |
.expect("Unable to open file"); | |
let mut tbytes: Vec<u8> = Vec::<u8>::new(); | |
match fd_w.read_to_end(&mut tbytes) { | |
Ok(_) => Ok((tbytes, fd_w)), | |
Err(_) => Err(()) | |
} | |
} | |
fn main() { | |
let ret = open_wrapper("/bin/id").unwrap(); | |
let fbuf: Vec<u8> = ret.0; | |
unsafe { println!("Entry Point: {:x}", parse_ehdr(&fbuf[0..64]).unwrap().e_entry) }; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment