Skip to content

Instantly share code, notes, and snippets.

@n4sm
Last active February 17, 2024 04:10
Show Gist options
  • Save n4sm/bde3e34afac9de5713819d01bb1b02b9 to your computer and use it in GitHub Desktop.
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)
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