rust_pwntools 0.1.0

A Rust crate inspired by Pwntools, providing powerful tools for binary exploitation, reverse engineering, and CTF challenges.
Documentation
use goblin::elf::Elf;
use goblin::Object;
use std::fs::File;
use std::io::{self, Read};
use std::path::Path;

pub struct ElfFile {
    elf: Elf<'static>,
}

impl ElfFile {
    /// Parses an ELF file from the given path.
    pub fn parse(path: &Path) -> io::Result<Self> {
        let mut file = File::open(path)?;
        let mut buffer = Vec::new();
        file.read_to_end(&mut buffer)?;

        // Ensure buffer lives long enough by leaking it
        let buffer = Box::leak(buffer.into_boxed_slice());

        match Object::parse(buffer) {
            Ok(Object::Elf(elf)) => Ok(ElfFile { elf }),
            _ => Err(io::Error::new(io::ErrorKind::Other, "Failed to parse ELF file")),
        }
    }

    /// Returns the symbols in the ELF file.
    pub fn symbols(&self) -> Vec<String> {
        self.elf.syms.iter().map(|sym| {
            self.elf.strtab.get_at(sym.st_name).unwrap_or("").to_string()
        }).collect()
    }

    /// Resolves the GOT and PLT entries in the ELF file.
    pub fn resolve_got_plt(&self) -> Vec<(String, u64)> {
        self.elf.dynsyms.iter().filter_map(|sym| {
            self.elf.dynstrtab.get_at(sym.st_name).map(|name| {
                (name.to_string(), sym.st_value)
            })
        }).collect()
    }

    /// Finds the address of a specific symbol.
    pub fn find_symbol(&self, symbol: &str) -> Option<u64> {
        self.elf.syms.iter().find_map(|sym| {
            if let Some(name) = self.elf.strtab.get_at(sym.st_name) {
                if name == symbol {
                    return Some(sym.st_value);
                }
            }
            None
        })
    }
}