archive |
|
|
elf |
|
|
error.rs |
A custom Goblin error
|
1936 |
lib.rs |
# libgoblin
![say the right
words](https://s-media-cache-ak0.pinimg.com/736x/1b/6a/aa/1b6aaa2bae005e2fed84b1a7c32ecb1b.jpg)
`libgoblin` is a cross-platform trifecta of binary parsing and loading fun. It supports:
* An ELF32/64 parser, and raw C structs
* A 32/64-bit, zero-copy, endian aware, Mach-o parser, and raw C structs
* A PE32/PE32+ (64-bit) parser, and raw C structs
* A Unix archive parser and loader
Goblin requires at least `rustc` 1.36.0, uses the 2018 rust edition, and is developed on stable.
Goblin primarily supports the following important use cases:
1. Core, std-free `#[repr(C)]` structs, tiny compile time, 32/64 (or both) at your leisure
2. Type punning. Define a function once on a type, but have it work on 32 or 64-bit variants - without really changing anything, and no macros! See `examples/automagic.rs` for a basic example.
3. `std` mode. This throws in read and write impls via `Pread` and `Pwrite`, reading from file, convenience allocations, extra methods, etc. This is for clients who can allocate and want to read binaries off disk.
4. `Endian_fd`. A truly terrible name :laughing: this is for binary analysis like in [panopticon](https://github.com/das-labor/panopticon) which needs to read binaries of foreign endianness, _or_ as a basis for constructing cross platform foreign architecture binutils, e.g. [cargo-sym](https://github.com/m4b/cargo-sym) and [bingrep](https://github.com/m4b/bingrep) are simple examples of this, but the sky is the limit.
# Example
```rust
use goblin::{error, Object};
use std::path::Path;
use std::env;
use std::fs;
fn run () -> error::Result<()> {
for (i, arg) in env::args().enumerate() {
if i == 1 {
let path = Path::new(arg.as_str());
let buffer = fs::read(path)?;
match Object::parse(&buffer)? {
Object::Elf(elf) => {
println!("elf: {:#?}", &elf);
},
Object::PE(pe) => {
println!("pe: {:#?}", &pe);
},
Object::COFF(coff) => {
println!("coff: {:#?}", &coff);
},
Object::Mach(mach) => {
println!("mach: {:#?}", &mach);
},
Object::Archive(archive) => {
println!("archive: {:#?}", &archive);
},
Object::Unknown(magic) => { println!("unknown magic: {:#x}", magic) },
_ => { }
}
}
}
Ok(())
}
```
# Feature Usage
`libgoblin` is engineered to be tailored towards very different use-case scenarios, for example:
* a no-std mode; just simply set default features to false
* a endian aware parsing and reading
* for binary loaders which don't require this, simply use `elf32` and `elf64` (and `std` of course)
For example, if you are writing a 64-bit kernel, or just want a barebones C-like
header interface which defines the structures, just select `elf64`, `--cfg
feature=\"elf64\"`, which will compile without `std`.
Similarly, if you want to use host endianness loading via the various `from_fd` methods, `--cfg
feature=\"std\"`, which will not use the `byteorder` extern crate, and read the bytes
from disk in the endianness of the host machine.
If you want endian aware reading, and you don't use `default`, then you need to opt in as normal
via `endian_fd` |
13188 |
mach |
|
|
pe |
|
|
strtab.rs |
A byte-offset based string table.
Commonly used in ELF binaries, Unix archives, and even PE binaries. |
9765 |