An open API service indexing awesome lists of open source software.

https://github.com/denoland/sui

Embed custom RO data into precompiled executables
https://github.com/denoland/sui

Last synced: 14 days ago
JSON representation

Embed custom RO data into precompiled executables

Awesome Lists containing this project

README

        

# `libsui`

[![Crates.io](https://img.shields.io/crates/v/libsui.svg)](https://crates.io/crates/libsui)

_Sui (सुई)_ is a injection tool for executable formats (ELF, PE, Mach-O) that
allows you to embed files into existing binary and extract them at runtime.

It produces valid executables that can be code signed on macOS and Windows.

[Documentation](https://docs.rs/libsui) | [Usage](cli.rs)

## Usage

```
cargo add libsui
```

Embedding data into binaries:

```rust
use libsui::{Macho, PortableExecutable};

let exe = std::fs::read("tests/exec_mach64")?;
let mut out = std::fs::File::create("out")?;

Macho::from(exe)?
.write_section("__hello", b"Hello, World!".to_vec())?
.build(&mut out)?;

let exe = std::fs::read("tests/exec_pe64")?;
let mut out = std::fs::File::create("out.exe")?;

PortableExecutable::from(exe)?
.write_resource("hello.txt", b"Hello, World!".to_vec())?
.build(&mut out)?;
```

Extracting from self:

```rust
use libsui::find_section;

let data = find_section("hello.txt")?;
```

## Design

### Mach-O

Resource is added as section in a new segment, load commands are updated and
offsets are adjusted. `__LINKEDIT` is kept at the end of the file.

It is similar to linker's `-sectcreate,__FOO,__foo,hello.txt` option.

Note that `Macho::build` will invalidate existing code signature. on Apple
sillicon, kernel refuses to run executables with bad signatures.

Use `Macho::build_and_sign` to re-sign the binary with ad-hoc signature. See
[`apple_codesign.rs`](./apple_codesign.rs) for details. This is similar to
`codesign -s - ./out` command.

```rust
Macho::from(exe)?
.write_section("__sect", data)?
.build_and_sign(&mut out)?;
```

```
$ codesign -d -vvv ./out

Executable=/Users/divy/gh/sui/out
Identifier=a.out
Format=Mach-O thin (arm64)
CodeDirectory v=20400 size=10238 flags=0x20002(adhoc,linker-signed) hashes=317+0 location=embedded
Hash type=sha256 size=32
CandidateCDHash sha256=6b1abb20f2291dd9b0dbcd0659a918cb2d0e6b18
CandidateCDHashFull sha256=6b1abb20f2291dd9b0dbcd0659a918cb2d0e6b1876153efa17f90dc8b3a8f177
Hash choices=sha256
CMSDigest=6b1abb20f2291dd9b0dbcd0659a918cb2d0e6b1876153efa17f90dc8b3a8f177
CMSDigestType=2
CDHash=6b1abb20f2291dd9b0dbcd0659a918cb2d0e6b18
Signature=adhoc
Info.plist=not bound
TeamIdentifier=not set
Sealed Resources=none
Internal requirements=none
```

### PE

Resource is added into a new PE resource directory as `RT_RCDATA` type and
extracted using `FindResource` and `LoadResource` at run-time.

### ELF

Data is simply appended to the end of the file and extracted from
`current_exe()` at run-time.

This is subject to change and may use ELF linker notes (`PT_NOTE`) in the
future.

## Testing

This crate is fuzzed with LLVM's libFuzzer. See [fuzz/](fuzz/).

`exec_*` executables in `tests/` are compiled from `tests/exec.rs`:
```
rustc exec.rs -o exec_elf64 --target x86_64-unknown-linux-gnu
```

## License

MIT