1 unstable release

0.1.2 Sep 4, 2023

#2749 in Parser implementations

GPL-3.0-only

5.5MB
4.5K SLoC

Contains (ELF lib, 4MB) libqscintilla2_qt5.so.15.0.0, (ELF exe/lib, 1MB) assets/libjpeg/libjpeg.so.9, (ELF lib, 290KB) assets/libvpf/libvpf.so.4.1

Tests Docs GPL v3


DEAF

A Rust library for parsing and modifying ELF binaries
Contributions · Code Of Conduct · Report Bug · Request Feature

Table of Contents
  1. Introduction
  2. Getting Started
  3. Roadmap
  4. Contributing
  5. Contact

Introduction

This is a library for parsing and modifying ELF-format binaries. There are other libraries like elf, elfy, and elfkit for parsing the format, but they are either not able to modify the ELF binary (elf and elfy) or are limited/unmaintained (elfkit). DEAF is written with the explicit goal of allowing users to modify anything that they can see in the binary- you should be able to add symbols to the symbol tables, remove the body of a function, or change the name of a section, easily and intuitively. Some of the changes you can make will probably break the binary. For example, if you remove the body of a function then relative branch instructions after the gap will no longer point to the correct address.

As the development of the library progresses, there should be fewer and fewer ways that your changes break the ELF binary, and the end goal is to even handle updating branch instructions when code is removed from an executable section.

(back to top)

Getting Started

This project is still in the very early stages, so expect a lot of breaking changes, restructuring, and reorganization from one version to the next as we figure out where things belong. If you still want to try it out, include deaf in your project by using cargo add:

cargo add deaf

Or by manually updating your cargo toml:

deaf = "0.1.0"

Then use it in your project like so:

use deaf::{Binary,Section,common::SectionType};

let binary = Binary::load("assets/libjpeg/libjpeg.so.9").unwrap();

for section in binary.sections(SectionType::Strings).iter() {
    let name_offset = section.name();
    let name_value = binary.section_name(name_offset).unwrap();
    println!("{}",name_value);
}

For more details, refer to the documentation.

(back to top)

Roadmap

0.1.0

This version is mainly aimed at providing initial functionality.

  • Seamless, endian aware fields that can read/write
  • Update fields to seamlessly support 32 or 64-bit byte ranges
  • Create constants for enum-style header fields
  • Make FileHeader struct that can read and write from/to binary data
  • Make ProgramHeader struct that can read and write from/to binary data
  • Make SectionHeader struct that can read and write from/to binary data

0.2.0

This release is generally aimed at propagating changes to keep the binary useable.

  • Add mechanism to update sections globally on local changes
  • Make wrapper Table<TableItem> structs for sections
  • Make wrapper Array<ArrayItem> structs for sections
  • Turn the Segment struct into a wrapper struct
  • Make a super list of updates and when they should be applied
    • Update section offsets when items are added/removed from tables
    • Update section name indices when the section name string table changes
  • Add getter/setter methods to Binary

0.3.0

This release is going to be all about gathering context about executable code, if not outright disassembling it.

  • Add find-page-address page size calculation methods
  • Create Function wrapper struct for symbol that includes binary data
  • Investigate integrating (or writing) a disassembly crate for deaf
  • Add methods for interrogating the target platform of the binary
    • Use EI_OSABI and e_machine values in file header
    • Provide methods for lib user to specify binary platform
  • Create platform parsing context that varies depending on target platform
  • Add basic chunking and iteration methods for function bodies

Future

This is a haphazard collection of things that should be added to the library at some point but that aren't quite on the roadmap yet.

  • Make it possible to iter/iter_mut over instructions in functions without explicitly calling disassembly methods, inspecting the binary target etc. You should be able to iterate instructions as easily as you iterate symbols.

  • Provide integration tests that verify that modified binaries are still useable. I'm not sure how to do this without having some sort of third-party emulation platform for an ARM64 system set up.

(back to top)

Contributing

Anyone is welcome to contribute to DEAF, just try to follow the code of conduct and the contribution guidelines. If something is unclear or not covered in the guides, create an issue describing the problem and someone will get back to you as soon as possible.

(back to top)

Contact

Create an issue and @mjhouse to get my attention, or email me at mjhouse@protonmail.com.

(back to top)

Dependencies