Skip to content

Dynamic Analysis

Ryan edited this page Jul 18, 2026 · 1 revision

Dynamic Analysis

Dynamic analysis observes a binary's behavior rather than only its structure. In RE-Toolkit it is opt-in, tiered by risk, and always layered on top of static analysis.

Read this page before using --allow-real-execution. Tiers 2 through 4 execute malicious code on your machine.

Contents

How static and dynamic interact

Static analysis always runs. --dynamic does not replace it; it adds execution-based stages after the static pipeline completes for each target.

There is no dynamic-only mode, and this is a design decision rather than an omission. Dynamic stages cross-reference the strings, imports, signatures, and indicators that static analysis produces. An observed network connection is far more useful when it can be matched against a hardcoded address recovered from the binary's strings. Running dynamic alone would degrade the dynamic results.

Both modalities feed the same _summary.json and the same report.

# Static only, the default
analyze-binaries.sh -t sample.exe -o ./out

# Static, then dynamic
analyze-binaries.sh -t sample.exe -o ./out --dynamic

The tier model

Four tiers, in increasing order of fidelity and of risk.

Tier Mechanism Executes the target Requires
1 qiling emulation over Unicorn No Nothing
2 firejail namespace sandbox Yes --allow-real-execution, ELF target, firejail
3 Docker container Yes --allow-real-execution, image built
4 cuckoo sandbox Yes --allow-real-execution, configured deployment

The single most important distinction is Tier 1 against everything else. Tier 1 emulates instructions in userspace and never issues a real syscall to the host kernel, so it carries no execution risk and needs no consent flag. Tiers 2 through 4 genuinely run the binary, and their isolation reduces risk without eliminating it.

--allow-real-execution exists as an explicit consent gate. Without it, the real-execution tiers skip cleanly and record why.

Auto-tier and legacy mode

With --dynamic alone, RE-Toolkit runs every tier that is applicable to the target type and available on the host. Each tier reports its own status, so the report shows which ran and why the others did not.

# Auto-tier: Tier 1 only, since real execution was not authorized
analyze-binaries.sh -t sample.exe -o ./out --dynamic

# Auto-tier: every applicable and available tier
analyze-binaries.sh -t sample.elf -o ./out --dynamic --allow-real-execution

Setting --dynamic-mode restricts the run to exactly one tier. This is the behavior automation usually wants, where a predictable single-tier result is more useful than best-effort coverage.

analyze-binaries.sh -t sample.exe -o ./out --dynamic --dynamic-mode=qiling

Individual tiers can be disabled while leaving auto-tier otherwise intact, with --no-dynamic-qiling, --no-dynamic-firejail, --no-dynamic-docker, and --no-dynamic-cuckoo.

Tier 1, qiling emulation

A pure CPython emulator running over the Unicorn engine. Instructions are interpreted and system calls are emulated, so nothing reaches the host kernel.

This makes Tier 1 both the safest tier and the most portable: it emulates Windows PE on a Linux host, along with Linux ELF and Mach-O, with the architecture detected from the binary.

Emulation requires an operating system root filesystem to emulate against, which the installer provisions into /opt/qiling-rootfs/. Without it, the tier skips and records the reason.

Its limitation is inherent to emulation. Coverage depends on how completely the emulator models the target platform, and a binary that exercises an unimplemented API will stop early rather than continue. Partial results are normal and are still useful: a truncated trace that shows the first several API calls often answers the question you had.

Tier 2, firejail sandbox

Real execution inside a Linux namespace sandbox with restricted filesystem and network access. Applies to ELF targets only, since firejail runs native Linux binaries.

Lighter weight than a container or a virtual machine, and correspondingly less isolated. Namespace escapes exist. Use it when you need real Linux execution and have accepted the risk at the host level.

Tier 3, Docker container

Real execution inside a container built for the purpose. Stronger isolation than namespaces alone, and applicable to a wider range of targets.

Requires --with-docker at install time, which installs Docker and builds the analysis image. Container escapes exist, and a container shares the host kernel, so this is isolation rather than separation.

Tier 4, cuckoo sandbox

Full sandbox detonation with the deepest behavioral instrumentation available here, typically inside a dedicated analysis virtual machine.

The installer does not attempt an automated cuckoo installation. A working deployment needs a hypervisor, a prepared analyst virtual machine, and agent configuration, all of which are environment-specific. --with-cuckoo checks whether cuckoo is present and provides guidance; the deployment itself is yours to build.

Because it executes inside a separate virtual machine, Tier 4 offers the strongest isolation of the real-execution tiers, at the highest setup cost.

Network exposure

Mode Behavior
none No network access. The default.
tap Isolated virtual interface
host Host network access
analyze-binaries.sh -t sample.exe -o ./out \
    --dynamic --allow-real-execution --dynamic-network none

--dynamic-network has no effect on Tier 1, which has no real network to expose.

Default to none. Malware that cannot reach the network still reveals a great deal: attempted connections are observable as attempts, which usually answers the question without granting the access.

Use host only when you have deliberately isolated the host itself, and understand that you are permitting a hostile sample to communicate with whatever that host can reach. Live infrastructure contact also signals to an adversary that their sample is being analyzed.

Timeouts

--dynamic-timeout sets a hard limit per binary, defaulting to 60 seconds. When it expires the run stops regardless of completion state, and partial results are retained.

analyze-binaries.sh -t sample.exe -o ./out --dynamic --dynamic-timeout 300

Short timeouts are a feature rather than a limitation. Much malware performs its interesting behavior early, and a bounded run prevents a sample that deliberately sleeps from consuming the analysis window. Extend the timeout when you suspect delayed execution and have the isolation to justify a longer run.

Operational practice

Use a disposable virtual machine. Snapshot before the run, revert after. This is the single most effective control, and it makes every other consideration on this page a second line of defense rather than the only one.

Assume sandbox awareness. Malware routinely detects emulation, containers, and analysis environments, and alters behavior when it does. Benign observed behavior is not proof of a benign sample; it may mean the sample recognized where it was running.

Assume escape is possible. Every isolation mechanism here has had escapes found in it. Isolation reduces the probability and the blast radius; it does not make execution safe.

Do not run dynamic analysis on a machine with credentials or network reach you care about. No credentials mounted, no shared filesystems, no path to production.

Start at Tier 1. It costs nothing in risk and often answers the question. Escalate only when you need behavior that emulation cannot produce.

Interpreting results

Dynamic findings appear under the dynamic key in _summary.json and in the report's dynamic tab, alongside the tier that produced them.

Read them with three cautions.

Absence of behavior is weak evidence. A sample that did nothing observable may be benign, may have detected the sandbox, may have failed to run in the environment, or may have been waiting longer than the timeout allowed. The tier status and any error output distinguish these.

Emulated behavior is not identical to real behavior. Tier 1 results reflect what the emulator modeled, which may diverge from what a real host would do.

Cross-reference against static findings. A connection attempt to an address that also appears in the binary's strings is a much stronger finding than either observation alone. This cross-referencing is the reason static analysis always runs first.

Clone this wiki locally