Turn any dynamically linked Linux program into a single, self-contained executable.
dlfreeze resolves a program's full shared-library dependency tree, bundles everything — binary, runtime linker, libraries, and optional data files — into one portable file, and provides two runtime strategies: extraction to a tmpdir (default) or a fast in-process loader that maps objects directly from the frozen binary's memory (direct-load mode).
makeFreeze ls:
./build/dlfreeze -o ls.frozen /bin/ls
./ls.frozen -la /etcFreeze Python with traced dlopen() dependencies and data files:
./build/dlfreeze -d -t -f '/usr/lib/python3*' -o python3.frozen -- python3 -c 'import sqlite3'
./python3.frozen -c 'import sqlite3; print(sqlite3.sqlite_version)'- Dependency resolution — BFS walk over
DT_NEEDEDentries, with ldconfig cache lookup,$ORIGIN/DT_RPATH/DT_RUNPATHexpansion, and automatic inclusion of glibc NSS libraries. - dlopen tracing (
-t) — Runs the program under anLD_PRELOADshim that interceptsdlopen()and records the resolved paths. - Packing — Concatenates the statically-linked bootstrap stub, every collected object (page-aligned), a string table, a manifest, and a 64-byte footer (
DLFREEZmagic) into a single ELF. - Runtime — extraction mode (default) — The bootstrap reads
/proc/self/exe, extracts files to a tmpdir, and execs the program through the bundledld.so. - Runtime — direct-load mode (
-d) — The bootstrap invokes an in-process ELF loader that maps segments from the payload, resolves relocations, sets up TLS, and jumps to_start.
Frozen binaries are compatible with UPX and should mostly work with other packing tools: the payload lives in a PT_LOAD segment so compressors preserve it, and a DLFRZLDR sentinel in .data lets the bootstrap find the payload in virtual memory if the footer is no longer at EOF.
dlfreeze [options] [--] <executable> [args...]
Options:
-o <path> Output file (default: <name>.frozen)
-d Direct-load mode (in-process loader, no tmpdir)
-t Trace dlopen calls by running the program
-f <glob> Embed data files matching glob (requires -t, repeatable)
-v Verbose
-h Help
When -t is used, [args...] are passed to the traced run so the program exercises the code paths that trigger dlopen().
Requires Linux and a C compiler. musl-gcc is preferred for smaller static binaries but the build falls back to the system gcc.
make # builds build/dlfreeze, build/dlfreeze-bootstrap, build/dlfreeze-preload.so
make test # runs the test suite
make bench # startup benchmarks (requires perf)
make cleanThe majority of code for this project was written by LLMs. Although I've read through the code to make sure there's nothing obviously stupid, do not use this project in a production or security-sensitive environment without vetting it yourself.
This project is licensed under the GNU Lesser General Public License version 3.