Skip to main content

Crate cowfile

Crate cowfile 

Source
Expand description

§cowfile

A copy-on-write abstraction for working with binary data from files or memory.

cowfile provides CowFile, a type that wraps binary data with a pending write log. The committed buffer is backed by either a Vec<u8> or an OS-level copy-on-write memory map (MmapMut with MAP_PRIVATE). Modifications accumulate in a pending log and are applied to the buffer on commit.

§Use Case

This crate is designed for binary analysis and transformation pipelines where multiple passes modify a binary (e.g., deobfuscation, patching). A parser can hold a &[u8] reference to the committed state via data while writes accumulate in the pending log, and commit applies them cheaply (only OS pages touched by patches are copied).

§Architecture

 Committed Buffer               Pending Log
+---------------------+      +-------------------------+
| Vec<u8> or MmapMut  | <--- | Vec<PendingWrite>       |
| (OS-level CoW)      |      | (applied on commit)     |
+---------------------+      +-------------------------+
  • Committed buffer: Vec<u8> (owned) or MmapMut created with map_copy (MAP_PRIVATE on Unix, PAGE_WRITECOPY on Windows). Only pages touched by commits use extra RAM.
  • Pending log: Accumulated writes not yet applied to the buffer.

data returns &[u8] of the committed buffer. read, read_le, etc. composite pending writes over the committed state.

§Thread Safety

CowFile is Send and Sync. The committed buffer can be read concurrently via data from multiple threads. Writes to the pending log are serialised by an internal RwLock.

§Quick Start

use cowfile::CowFile;

let pf = CowFile::from_vec(vec![0u8; 1024]);

// Writes go to the pending log
pf.write(0x10, &[0xFF, 0xFE]).unwrap();
pf.write(0x20, &[0xAA, 0xBB, 0xCC]).unwrap();

// data() shows committed state (before writes)
assert_eq!(pf.data()[0x10], 0x00);

// read() composites pending writes
assert_eq!(pf.read_byte(0x10).unwrap(), 0xFF);

// Commit applies pending to the buffer
let mut pf = pf;
pf.commit().unwrap();

// Now data() shows the committed writes
assert_eq!(pf.data()[0x10], 0xFF);

§Memory-Mapped Files

For large binaries, use CowFile::open to create a copy-on-write memory map. The OS handles paging — only accessed regions are loaded into physical memory, and only pages modified by commit are copied:

use cowfile::CowFile;

let pf = CowFile::open("large_binary.exe").unwrap();
pf.write(0, &[0x4D, 0x5A]).unwrap(); // Pending

let mut pf = pf;
pf.commit().unwrap();                 // Only the first page is CoW'd
pf.to_file("patched.exe").unwrap();   // Write output

Structs§

CowFile
A copy-on-write file abstraction backed by memory or a file.
CowFileCursor
A cursor over a CowFile implementing Read, Write, and Seek.

Enums§

Error
Errors that can occur during cowfile operations.

Traits§

Primitive
Sealed trait for numeric primitives that support endian-aware byte I/O.
ReadFrom
Trait for types that can be deserialized from a CowFile at a given offset.
WriteTo
Trait for types that can be serialized into a CowFile at a given offset.

Type Aliases§

Result
Convenience type alias for Result<T, Error>.