PICBLOBS // guide

picblobs-cli

picblobs-cli is a companion package that bundles the non-Linux cross-compiled test runners and verifier-only test binaries alongside a click-based command-line interface. Linux payloads run as temporary ELF executables produced by picblobs itself. It depends on picblobs for blob data and the builder API. Install picblobs-cli when you want to build, run, or verify blobs from the shell -- if all you need is the blob bytes, stick with picblobs on its own.

See ADR-026 and REQ-020 for the architecture and full contract.

Installation

pip install picblobs-cli      # pulls in picblobs + click, ships non-Linux runners/fixtures

QEMU user-static must be on PATH for cross-architecture execution:

# Debian / Ubuntu
sudo apt install qemu-user-static

# Fedora / RHEL
sudo dnf install qemu-user-static

From a source checkout, source sourceme installs both packages in editable mode.

Commands

picblobs-cli --help
picblobs-cli COMMAND --help

Top-level commands are build, disasm, extract, info, list, list-runners, listing, run, test, and verify.

info

Print versions, the runner bundle directory, QEMU availability, and a one-line summary of every staged target.

$ picblobs-cli info
picblobs:     0.1.3
picblobs-cli: 0.1.3
runner bundle: /.../picblobs_cli/_runners
qemu found:    aarch64, armv5_arm, armv5_thumb, armv7_thumb, i686, mipsbe32, mipsel32, powerpc, ppc64le, riscv64, s390x, sparcv8, x86_64

Targets:
  freebsd:aarch64  (14 blob types)
  freebsd:armv5_arm  (14 blob types)
  ...
  linux:x86_64  (15 blob types)
  windows:x86_64  (6 blob types)

list-runners

List every bundled (runner_type, arch) runner binary. Linux has no bundled runner; run wraps Linux blobs into ELF executables instead.

picblobs-cli list-runners
picblobs-cli list-runners --os windows
picblobs-cli list-runners --arch x86_64

build

Use the picblobs.Blob(...) builder API to assemble a ready-to-run blob and write it as raw bytes, or wrap Linux output as an ELF executable.

# hello (no config)
picblobs-cli build hello linux:x86_64 -o hello.bin
picblobs-cli build hello linux:x86_64 --wrap-elf -o hello

# alloc_jump with an inner payload
picblobs-cli build alloc_jump linux:x86_64 \
    --payload inner_shellcode.bin \
    -o aj.bin

# stager_tcp with a target
picblobs-cli build stager_tcp linux:aarch64 \
    --address 10.0.0.1 \
    --port 4444 \
    -o stage.bin

# stager_pipe / stager_mmap
picblobs-cli build stager_pipe linux:x86_64 --path /tmp/my.fifo -o sp.bin
picblobs-cli build stager_mmap linux:x86_64 \
    --path /tmp/payload.img --offset 0 --size 4096 \
    -o sm.bin

# reflective_pe (Windows only)
picblobs-cli build reflective_pe windows:x86_64 \
    --pe image.dll --call-dll-main \
    -o refl.bin

# ul_exec — reflective ELF loader
picblobs-cli build ul_exec linux:x86_64 \
    --elf /usr/bin/ls --argv ls --argv -la \
    --envp PATH=/usr/bin \
    -o uex.bin

Options not applicable to the chosen blob type are rejected before any bytes are written, with a hint listing the options that are valid.

run

run has two modes:

Registry mode — look a blob up by type

picblobs-cli run hello linux:x86_64
picblobs-cli run hello linux:aarch64                # cross-arch via QEMU
picblobs-cli run stager_fd linux:x86_64 --config-hex 00000000 --stdin payload_stream.bin

Options:

  • --config-hex HEX — use the hex bytes as the serialized config struct.
  • --payload FILE — read the serialized config struct from a file.
  • --stdin FILE — feed file contents to the blob on fd 0.
  • --timeout SECONDS (default 30).
  • --runner-type TYPE — override the runner type.
  • --runner-path FILE — use an explicit runner binary.
  • --debug — print command, paths, keep temp files.
  • --dry-run — print the runner command without executing it.

File mode — execute an already-assembled blob

# Build once, run anywhere
picblobs-cli build alloc_jump linux:x86_64 --payload inner.bin -o aj.bin
picblobs-cli run --file aj.bin linux:x86_64

# Cross-architecture: target selects the runner + QEMU binary
picblobs-cli build stager_tcp linux:aarch64 \
    --address 127.0.0.1 --port 4444 -o stage.bin
picblobs-cli run --file stage.bin linux:aarch64

# Stdin still works; the file is handed to the runner as-is.
picblobs-cli run --file stage_fd.bin linux:x86_64 --stdin payload.bin

Because the file is assumed to be a complete (code + config) blob, --config-hex and --payload are rejected in file mode — assemble the blob first with build.

Passing both a positional <blob_type> and --file is a usage error: the two modes are mutually exclusive. A missing target or missing file is caught by click before execution.

verify

Exercise every staged blob end-to-end with the appropriate fixtures (TCP server, FIFO, temp file, stdin piping, inner-payload packing for alloc_jump, staged ul_exec ELFs, paired NaCl handshake).

# full sweep
picblobs-cli verify

# filters
picblobs-cli verify --os linux
picblobs-cli verify --type hello
picblobs-cli verify --os freebsd --arch x86_64

Exits non-zero if any blob fails; prints a PASSED / FAILED / SKIPPED summary listing the failing combinations by name.

Typical workflows

Iterating on a payload during development

# Edit src/payload/my_blob.c, then
./buildall

# Single-shot run
picblobs-cli run my_blob linux:x86_64

# Full sweep across every staged target
picblobs-cli verify --type my_blob

Producing artifacts for an external system

# Generate the blob once
picblobs-cli build stager_tcp linux:aarch64 \
    --address 10.0.0.1 --port 4444 -o stage.bin

# Ship stage.bin to the target environment, or sanity-check it locally
picblobs-cli run --file stage.bin linux:aarch64 --timeout 5

Scripting around the CLI

The exit code is the blob's exit code (or the CLI's own error code). Stdout and stderr are passed through verbatim, so scripting idioms work:

if output=$(picblobs-cli run my_blob linux:x86_64); then
    echo "blob said: $output"
fi

Relationship to picblobs

Need Package
Assemble blobs from the Python builder picblobs
Read blob metadata / config layouts picblobs
Run / verify blobs under bundled runners picblobs-cli
Get cross-compiled runner binaries picblobs-cli

The runtime catalog also includes PIC_PLATFORM_HOSTED NaCl variants (nacl_client_hosted, nacl_server_hosted). Those are staged artifacts for the hosted platform code path, not high-level builder methods.

If you install only picblobs, picblobs.runner.find_runner() raises FileNotFoundError with a message pointing at picblobs-cli. The data library itself remains fully usable — it just can't execute.