Quick start
Three commands cover 90% of usage. The rest of this page is the full reference.
Pack an EXE with the recommended Release defaults
AkiProtect_builder.exe --i myapp.exe --lz4 --vm --ulam-layout
Pack a DLL with a startup export
AkiProtect_builder.exe --i my.dll --o my_packed.exe ^
--lz4 --vm --dll-export RunMe
Maximum protection for the algorithms you can't afford to lose
AkiProtect_builder.exe --i secret.exe --lz4 --vm --vm-passes 8 --ulam-layout
Compression
Compression shrinks the payload bytes and reshapes the on-disk image. Only one mode active at a time.
Classic LZ77 dictionary-based compression.
What it doesStandard LZ77 encoder. The decoder is embedded in the runtime stub and runs before your code starts.
EffectBest compression ratio of the CLI codecs. ~20 ms startup decoder cost on typical hardware.
DefaultOff (no compression).
Mutually exclusive with--lz4
When to useSize-sensitive distribution — downloads, bandwidth-billed channels, app-store packaging.
LZ4 block-format compression.
What it doesLZ4 is a high-throughput compression codec. Smaller ratio than LZ77 but ~4× faster decoder.
EffectLower compression ratio. ~5 ms startup decoder cost.
DefaultOff.
Mutually exclusive with--lz77
When to useStartup-latency-sensitive applications, GUI apps that need fast cold start, large payloads where decoder time dominates.
AkiProtect also supports LZNT1 and LZMS through the runtime stub config; those are activated by choosing a prebuilt stub config rather than a CLI flag.
Code virtualization
The VM replaces straight-line code with custom bytecode running on a 9-register virtual CPU. Opcode mapping is randomized per build so two copies of the same source execute completely different bytecode.
Enable one VM transformation pass.
What it doesRuns the payload through one VM transformation: opcodes are remapped using a per-build randomized table, bytecode is appended to the tail along with the opcode map.
EffectDecoder runs at startup before your code. Decoder size: ~3 KB in the stub.
DefaultOff.
Apply N independent VM transformations, each with its own opmap.
What it doesStacks N separate VM transformation passes — each pass has its own randomized opcode table. At startup the runtime peels them off in reverse order.
EffectImplies --vm. Protection scales linearly with N; startup overhead scales linearly with N.
Accepted values- 1 — single VM pass (same as --vm)
- 2-4 — strong virtualization, ~20-50 ms extra startup
- 5-8 — maximum virtualization for sensitive algorithms, ~80-300 ms extra startup
Default1 when --vm is set, otherwise unset.
When to useSet ≥ 4 for algorithms with high IP value: DRM, license enforcement, novel optimization code, anti-cheat hot paths.
Block layout
After encryption, the payload is split into blocks, scattered via a deterministic Ulam-spiral order, and bound with SHA-256 integrity groups. Tampering breaks a group hash and the runtime silently exits.
Enable the Ulam-spiral block permutation.
What it doesAdds an Ulam metadata section to the tail describing the spiral order. SHA-256 hashes bind groups of blocks together. At startup the runtime reverses the permutation, verifies every group hash, and only then proceeds to decryption.
EffectActs as the anti-tamper layer. Any modification to the packed file invalidates a SHA-256 group hash and the runtime exits silently.
DefaultOff.
When to useRecommended for all production builds. The runtime cost is small (~5 ms) and the protection is total against bytewise patching.
Debug: export the spiral layout for inspection.
What it doesWrites the chosen Ulam permutation to a file as JSON for verification or debugging.
Requires--ulam-layout
When to useDebug only — never on a production build.
Example
--dump-ulam-map ulam.json
Anti-debug toggles
Six anti-debug probes run at startup. Each is independently togglable so you can switch off a single probe that misfires on a specific customer machine without weakening the other five.
Master kill switch — disable every anti-debug probe at runtime.
What it doesSkips all six anti-debug probes and the staging-encryption check. The encryption layers (compression / VM / Ulam) still apply — only the runtime checks are bypassed.
EffectReduces startup overhead by ~3-5 ms.
When to useDebug your unpack pipeline. Never on a production build.
Skip IsDebuggerPresent + CheckRemoteDebuggerPresent.
What it doesTwo classic Win32 calls that detect attached debuggers. Trivial to bypass for skilled reversers but stops casual tampering with Visual Studio or x64dbg.
When to useDisable if a customer's legitimate tool (e.g. a profiler) is mistakenly flagged. Otherwise keep enabled.
Skip PEB NtGlobalFlag + heap flags scan.
What it doesReads the Process Environment Block directly: NtGlobalFlag at PEB+0x68 and the heap flag values. Bits set there during debugging.
When to useDisable if your customer uses a tool that initializes the heap with debug flags during normal operation.
Skip Dr0–Dr3 hardware breakpoint scan.
What it doesInspects the four hardware breakpoint registers (Dr0-Dr3) via GetThreadContext. Hardware breakpoints are commonly used by reversers because they don't modify your code.
When to useDisable on systems where another security tool legitimately uses hardware breakpoints (some kernel-level anti-cheat solutions do).
Skip RDTSC timing check.
What it doesTimes a tight loop with RDTSC. A debugger single-stepping the loop produces a measurable delay.
When to useDisable on virtualized hosts where the clock can be unreliable (some hypervisors). False positives on heavily loaded shared hosts.
Skip OutputDebugString / exception filter trick.
What it doesRaises an exception and uses OutputDebugString to detect behavioural differences between an attached and a detached process.
When to useDisable in environments where a logging or APM agent intercepts OutputDebugString.
Skip NtSetInformationThread(ThreadHideFromDebugger).
What it doesCalls NtSetInformationThread with ThreadHideFromDebugger (0x11). Removes the running thread from any debugger's event stream so single-step events stop being delivered.
When to useDisable only if you're actively debugging the protected binary in development.
Hardening (build-time)
Build-time switches that change how the runtime stub is constructed. All four are on by default in the default Release profile.
Use the fixed legacy tail signature.
What it doesDisables the per-build random 8-byte tail signature and reverts to the legacy fixed "TINYLD46" marker.
EffectMakes the file fingerprintable by any AV signature that knows the marker.
DefaultOff — random per-build signature is on.
When to useInternal QA where you need a deterministic file layout for comparison.
Use mt19937 + GetTickCount64 instead of BCryptGenRandom for keys.
What it doesFalls back from the Windows CSPRNG to a software PRNG seeded by the tick counter for all key material (VM opmap permutation, Ulam layout seed, per-stage XOR keys).
EffectDramatically lower entropy. Faster build (no CSPRNG calls).
DefaultOff — BCryptGenRandom is on.
When to useSandboxes without Windows CSPRNG. Never recommended for production.
Switch to the classic dual stub (visible imports, plain strings).
What it doesReplaces the import-less stealth stub with a classic stub that has standard CRT entry, visible kernel32/user32/psapi imports, and plain string literals.
EffectLarger output. Visible import table. Easier to debug, much easier to fingerprint.
DefaultOff — stealth stub is on.
When to useInvestigating loader issues during initial integration. Production should always use the stealth stub.
Disable inter-stage payload XOR.
What it doesTurns off the per-stage memory XOR that protects the payload buffer between Ulam → VM → LZ decoders. Each transition normally leaves only ciphertext in process memory briefly.
EffectMemory scanners get a window where plaintext payload is visible.
DefaultOff — staging encryption is on.
When to useDebug only.
Diagnostics
Commands that inspect or verify without producing a packed output. Useful in CI gates and pre-flight checks.
Print PE compatibility info for the input and exit.
What it doesInspects the input PE without packing it. Prints architecture, file size, sections, imports, delay imports, and a compatibility verdict.
When to usePre-flight check before adding a new binary to your build pipeline.
Example
AkiProtect_builder.exe --i myapp.exe --dump-info
Print compatibility verdict + reason + suggested action.
What it doesIf the input would be rejected, prints why (e.g. "CLR section detected") and what to change (e.g. "remove managed code or use a different protector").
Example
AkiProtect_builder.exe --i candidate.exe --explain-unsupported
Write JSON compatibility report.
What it doesMachine-readable variant of --explain-unsupported. Includes verdict, reason category, summary, suggested action, plus the full PE diagnostics block.
When to useCI gates that need a structured Yes/No on whether a build will succeed before attempting it.
Example
--compat-report ci/compat.json
Offline-verify a previously-packed file without running it.
What it doesReads the tail metadata, verifies the integrity hashes (tail hash, VM bytecode hash, payload hash, Ulam group hashes), and prints a verdict.
When to useAfter downloading a build from a release server — confirm it matches the manifest. Or in CI to gate uploads.
Example
AkiProtect_builder.exe --verify-packed dist/myapp_packed.exe
Machine-readable verifier output.
What it doesWhen combined with --verify-packed, writes the verifier's findings as JSON instead of human-readable text.
Example
--verify-packed dist/myapp_packed.exe --json verify.json
Print builder version and tail format version.
What it doesTwo version numbers: the AkiProtect builder version, and the tail format version (incremented on format-breaking changes).
Example
AkiProtect_builder.exe --version