backhand

repository·master·Indexed 41 days ago

https://github.com/wcampbell0x2a/backhand

A Rust library and set of CLI tools for reading, creating, and modifying SquashFS file systems. It supports standard Linux kernel formats and vendor-specific formats via a configurable 'Kind' system. Includes tools such as unsquashfs-backhand for extraction and listing, add-backhand for inserting files or directories, and replace-backhand for swapping files within images. Requires rustc 1.90+.

Tokens
18.6K
Snippets
60
Records
82
Agent score
50%

What's inside backhand

  1. Run tests for backhand and backhand-cli

    master

    To test the backhand library and the backhand-cli tool, you must first build the binaries and run the unit tests.

    1. Build the binaries with unit tests enabled: cargo build --release --bins
    2. Execute the test suite across the workspace with all features enabled: cargo test --workspace --release --all-features
    $ cargo build --release --bins
    $ cargo test --workspace --release --all-features
  2. Install development dependencies for backhand

    master

    To develop with backhand, you need to install the following tools:

    1. Rust: The project uses the Rust compiler. Follow the official instructions at rust-lang.org/tools/install.
    2. Just: The project uses a justfile to manage development tasks. Install it from github.com/casey/just.
    3. squashfs-tools: Required for running tests to ensure compatibility. Install this via your system's package manager.
  3. Run comparison benchmarks via bench.bash

    master

    To run the comparison benchmarks (which compare backhand against squashfs-tools), use the bench.bash script. Note that these benchmarks are generated from bench.bash and typically require the dl binary from the test-assets-ureq repository.

    $ ./bench.bash
  4. Generate code coverage reports

    master

    Use cargo llvm-cov to generate coverage reports. You can run coverage for specific binaries or for the entire workspace.

    To generate a full HTML coverage report for the workspace with all features enabled (skipping slow tests), use the following command:

    $ cargo llvm-cov run --bin replace --no-clean --release
    $ cargo llvm-cov run --bin add --no-clean --release
    $ cargo llvm-cov run --bin unsquashfs --no-clean --release
    $ cargo llvm-cov --html --workspace --all-features --release --no-clean -- --skip slow
  5. Read, write, and modify SquashFS images with the backhand library

    master

    The backhand library provides FilesystemReader for analyzing images and FilesystemWriter for creating or modifying them. You can convert a reader into a writer to perform modifications on an existing image.

    Common operations include:

    • Reading: Use FilesystemReader::from_reader.
    • Adding files: Use push_file with either a std::io::Read type (like a File) or a std::io::Seek type (like a Cursor) and a NodeHeader.
    • Replacing files: Use replace_file to swap an existing path with new data.
    • Writing: Use write to save the modified filesystem to an output stream.
    use std::fs::File;
    use std::io::{Cursor, BufReader};
    use backhand::{FilesystemReader, FilesystemWriter, NodeHeader};
    
    // read
    let file = BufReader::new(File::open("file.squashfs").unwrap());
    let read_filesystem = FilesystemReader::from_reader(file).unwrap();
    
    // convert to writer
    let mut write_filesystem = FilesystemWriter::from_fs_reader(&read_filesystem).unwrap();
    
    // add file with data from slice
    let d = NodeHeader::default();
    let bytes = Cursor::new(b"Fear is the mind-killer.");
    write_filesystem.push_file(bytes, "a/d/e/new_file", d);
    
    // add file with data from file
    let new_file = File::open("dune").unwrap();
    write_filesystem.push_file(new_file, "/root/dune", d);
    
    // modify file
    let bytes = Cursor::new(b"The sleeper must awaken.\n");
    write_filesystem.replace_file("/a/b/c/d/e/first_file", bytes).unwrap();
    
    // write into a new file
    let mut output = File::create("modified.squashfs").unwrap();
    write_filesystem.write(&mut output).unwrap();
  6. Measure peak heap memory consumption

    master

    To measure and compare the peak heap memory consumption of backhand against squashfs-tools, you can use heaptrack.

    First, build the backhand-cli with the dist profile:

    $ cargo +stable build -p backhand-cli --bins --locked --profile=dist

    Then, run heaptrack on the resulting binary against a target squashfs file. Example for 870D97.squashfs:

    # Measuring backhand
    $ heaptrack ./target/dist/unsquashfs-backhand --quiet -f -d $(mktemp -d) backhand-test/test-assets/test_re815_xev160/870D97.squashfs
    
    # Measuring squashfs-tools
    $ heaptrack unsquashfs -quiet -no-progress -d $(mktemp -d) backhand-test/test-assets/test_re815_xev160/870D97.squashfs
    $ cargo +stable build -p backhand-cli --bins --locked --profile=dist
    
    $ heaptrack ./target/dist/unsquashfs-backhand --quiet -f -d $(mktemp -d) backhand-test/test-assets/test_re815_xev160/870D97.squashfs
    
    $ heaptrack unsquashfs -quiet -no-progress -d $(mktemp -d) backhand-test/test-assets/test_re815_xev160/870D97.squashfs