A portable volatile memory acquisition tool for Linux.
AVML is a Linux userland volatile memory acquisition tool written in Rust, intended to be deployed as a static binary. AVML can be used to acquire memory without knowing the target OS distribution or kernel a priori. No on-target compilation or fingerprinting is needed.
Release builds are produced for x86-64, AArch64, ARMv7 little-endian hard-float, and legacy ARMv6-compatible big-endian systems. ARMv7 acquisition currently assumes 4096-byte memory pages.
- Save recorded images to external locations via Azure Blob Store or HTTP PUT
- Azure Blob Storage uploads retry transient failures via the Azure SDK's default exponential backoff policy (8 attempts, capped at one minute total elapsed).
- Optional page level compression using Snappy.
- Uses LiME output format (when not using compression).
- /dev/crash
- /proc/kcore
- /dev/mem
Before producing output, AVML validates the source's memory ranges and reads
its first chunk (up to 16 MiB). If no source is specified, it tries /proc/kcore,
then /dev/crash, then /dev/mem until validation succeeds. The selected source
handle and buffered chunk are retained for acquisition. A later read or write
failure ends acquisition; AVML does not switch sources after validation.
Local acquisition and conversion outputs must not already exist. AVML creates
them exclusively and refuses existing files, hard links, and destination
symlinks. On Unix only, exactly /dev/null and /dev/stdout are opened for
writing without creation or truncation. A failed acquisition can leave a partial
local output; use a new path or remove that file before retrying.
NOTE: If the kernel feature kernel_lockdown is enabled, AVML will not be able to acquire memory.
The Azure VM test matrix is defined in eng/images.txt and currently covers:
- Ubuntu: 16.04, 18.04, 20.04, 22.04, 24.04, 26.04
- CentOS: 7.9
- RHEL: 7.9, 8.5, 8.10, 9.0, 9.8, 10.2
- Debian: 11, 12, 13
- Oracle Linux: 8.10, 9.8, 10.2
- CBL-Mariner: 2.0
- Azure Linux: 3.0
- SUSE Linux Enterprise Server: 12 SP5, 15 SP7, 16.0
- AlmaLinux: 8, 9, 10
avml is a single binary with subcommands. Each subcommand is gated by
a Cargo feature so a minimal build only includes the capability you need:
| Subcommand | Feature | Default | What it does |
|---|---|---|---|
acquire |
(always) | yes | Snapshot memory to a local file (optional upload after). |
convert |
convert |
yes | Convert between AVML / LiME / raw formats. |
upload |
upload |
yes | Upload a local file via HTTP PUT or to Azure Block Blob. |
stream |
stream |
yes | Stream a snapshot directly to a destination, no local file. |
Build a minimal acquire-only binary with cargo build --release --no-default-features.
On the target host:
avml acquire --compress output.lime.compressed
On the target host:
avml acquire output.lime
On a secure host with az cli credentials, generate a SAS URL.
EXPIRY=$(date -d '1 day' '+%Y-%m-%dT%H:%MZ')
SAS_URL=$(az storage blob generate-sas --account-name ACCOUNT --container CONTAINER test.lime --full-uri --permissions c --output tsv --expiry ${EXPIRY})
On the target host, execute avml with the generated SAS token.
avml acquire --sas-url ${SAS_URL} --delete output.lime
For hosts where writing the snapshot to a local file first is undesirable
(read-only root, limited disk, forensic chain-of-custody concerns), use
the stream subcommand. It uses the same source validation and selection as
acquire (pass --source to override) and writes bytes sequentially to the
chosen destination. Sources are tried only during validation, before any output
bytes are sent. The source cannot be changed mid-stream.
avml stream blob ${SAS_URL}
- The block size is derived automatically so the snapshot fits within
Azure's per-blob 50,000-block limit.
--sas-block-size(MiB) acts as a floor; if the derived minimum is larger, the larger value wins. --sas-block-concurrencycaps the number of in-flightstage_blockcalls. Peak RAM is approximately(concurrency + 1) * block_size.- If the snapshot fails mid-upload, staged blocks are abandoned without being committed; Azure discards them automatically per its standard policy.
On the collector host:
nc -l 9000 > snapshot.lime
On the target host:
avml stream tcp collector.example.com:9000
avml connects once and writes the snapshot sequentially. If the connection drops mid-stream, the snapshot aborts; there is no resume. No TLS — pair with an SSH tunnel or stunnel for confidentiality and integrity if needed.
avml upload put ./output.lime ${URL} # HTTP PUT
avml upload blob ./output.lime ${SAS_URL} # Azure Block Blob
On a secure host with az cli credentials, do the following:
- Generate a SAS URL (see above)
- Create
config.jsoncontaining the following information:
{
"commandToExecute": "./avml acquire --compress --sas-url <GENERATED_SAS_URL> --delete",
"fileUris": ["https://FULL.URL.TO.AVML.example.com/avml"]
}
- Execute the customScript extension with the specified
config.json
az vm extension set -g RESOURCE_GROUP --vm-name VM_NAME --publisher Microsoft.Azure.Extensions -n customScript --settings config.json
On a secure host, generate a S3 pre-signed URL or generate a GCP pre-signed URL.
On the target host, execute avml with the generated pre-signed URL.
avml acquire --url ${URL} --delete output.lime
avml convert ./compressed.lime ./uncompressed.lime
avml convert --source-format lime --format lime_compressed ./uncompressed.lime ./compressed.lime
A portable volatile memory acquisition tool for Linux
Usage: avml <COMMAND>
Commands:
acquire Acquire a memory snapshot to a local file (and optionally upload it)
convert Convert between AVML and LiME snapshot formats and a raw memory image
upload Upload an already-acquired snapshot file to remote storage
stream Stream a memory snapshot directly to remote storage, without writing it to a local file
help Print this message or the help of the given subcommand(s)
Run avml <COMMAND> --help for per-command options.
# Install MUSL
sudo apt-get install musl-dev musl-tools musl
# Install Rust via rustup
curl https://sh.rustup.rs -sSf | sh -s -- -y
# Add the MUSL target for Rust
rustup target add x86_64-unknown-linux-musl
# Build
cargo build --release --target x86_64-unknown-linux-musl
# Build without upload functionality
cargo build --release --target x86_64-unknown-linux-musl --no-default-features
ARMv7 hard-float artifacts require an ARM musl cross-toolchain. The repository build script creates the pinned toolchain and builds both full and minimal static binaries:
eng/build-armv7.sh
The testing scripts will create, use, and cleanup a number of resource groups, virtual machines, and a storage account.
- Install az cli
- Login to your Azure subscription using:
az login - Build avml (see above)
- ./eng/test-on-azure.sh
This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.microsoft.com.
When you submit a pull request, a CLA-bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repositories using our CLA.
This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact opencode@microsoft.com with any additional questions or comments.
Security issues and bugs should be reported privately, via email, to the Microsoft Security Response Center (MSRC) at secure@microsoft.com. You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Further information, including the MSRC PGP key, can be found in the Security TechCenter.