Skip to content

Static Analysis

Static Analysis shows the report for the executable that a run started. It analyses only the initial executable, not later executables or descendants. Nothing is run: the file is read, never executed. This page describes Antinomie 0.8.0, which is in development; the current release is 0.7.1.

Static Analysis of /tmp/dropper — run run-1 (Partial): the Report dropdown, dropper 4096 bytes (4.0 KB) with Run, Export report… and Open result directory; the tabs File Info, Content, Strings 2048, Regex matches, FLOSS, Binwalk, Unpacking, YARA, Capa Matrix, Disassembly, Decompilation and Symbols; on File Info › Summary the Identity card (State Partial, Path, Report, with a Triage › Properties link) and the Categories card with Metadata Complete, Structures Unavailable, Strings Partial 2048 rows, and the other categories Not requested with a Run button each.
A report with some categories done and the rest Not requested. Antinomie 0.8.0, synthetic data.

Turn it on in Run program with Static Analysis and pick the categories, or press Analyze Only to analyse without launching. When you run a file you just sent with Upload and Run, the analysis uses the copy still on the host, but only if the guest’s own hash of the file that ran equals that copy’s; the Specimen source row of the Identity card says which was used.

The Run program dialog with the Analysis tree open: Static Analysis ticked, Triage with File metadata and hashes and Headers, sections, imports and exports ticked, and Strings, Regex matches, Entropy, Hardening indicators, Rule matches, Compiler and packer identification, Capabilities, Embedded content and Unpacking (packer and unpacked layers) unticked; Deep analysis with Disassembly and Decompilation; Cancel, Analyze Only and Run at the bottom.
Choosing the categories in Run program. Antinomie 0.8.0, synthetic data.
Group Categories
Triage File metadata and hashes, Headers, sections, imports and exports, Strings, Regex matches, Entropy, Hardening indicators, Rule matches, Compiler and packer identification, Capabilities, Embedded content, Unpacking (packer and unpacked layers)
Deep analysis Disassembly, Decompilation, FLOSS strings (decoded, stack, tight)

A category whose tool is missing says Needs Ghidra, not installed (or the tool it needs) with an Install… button, which opens Library › Analysis tools.

Analysis runs in a bubblewrap sandbox with the file read-only. While it runs, each category shows its progress, and Cancel analysis stops it.

Static Analysis with no report: No static analysis report for this run, a short explanation, and To get a report with four steps: Start the VM; Open Run → Launch program; Tick Static Analysis, choose the analyses, then Run; Select the run in Run History.
With no report, the panel lists the steps to get one. Antinomie 0.8.0, synthetic data.

The Report dropdown picks the report: the selected run’s, an Analyze Only report, or an unpacked layer’s own report. Under it are the file’s name and size, Run (opens the run the report belongs to in Run History), Export report… and Open result directory.

Tab Shows
File Info A segmented control with Summary, Headers, Sections, Segments, Hardening, Identification and Entropy
Content The retained file as a hex dump, text, C array, Python bytes, Base64 or a hex string; type an offset, such as 0x1f00, and Go to jump to it. Text size buttons and Ctrl+wheel zoom it.
Strings Strings found in the file, with their file offset, encoding and length
Regex matches Pattern matches in the Strings and FLOSS strings, by category and type
FLOSS Strings the program builds on the stack or decodes at run time (needs FLOSS)
Binwalk Embedded-content signatures with their file offsets (nothing is extracted)
Unpacking The unpack chain, one layer at a time (needs UPX)
YARA Built-in YARA-X rule matches
Capa Matrix Capabilities by ATT&CK tactic or MBC objective, or as a table (needs capa)
Disassembly A function sidebar and the full listing (Address, Bytes, Instruction), searchable
Decompilation A function sidebar and the decompiled code (Line, Code; needs Ghidra)
Symbols Symbols, imports and exports

Tabs show their row counts. A tab the report does not have is greyed, with the tooltip Not part of this analysis; Run in Overview > Categories adds it without starting over.

File Info › Summary of a 64 KB object: the Identity card with State, Path and Report, and the Categories card listing Metadata Not requested with Run, Structures Complete 22 rows, Strings Partial 1024 rows, Regex matches, Entropy and Hardening Not requested, Rules Unavailable 0 rows, Identification and Capabilities Not requested, Disassembly Complete 105 rows, and Decompilation, Binwalk, FLOSS and Unpacking Not requested, each Run button beside them and an open-in-pane button beside each finished category.
Antinomie 0.8.0, synthetic data.

The Summary view has two cards. Identity lists the report state, the path, the MD5, SHA-1 and SHA-256, the format and architecture, the specimen source and the report ID, each with a copy button, and links to Triage › Properties. Categories lists every category with its state (Complete, Partial, Unavailable, Pending, Not requested, or Queued… / Running… while the analysis runs) and its row count; click one to open its tab, or use its icon to open it in a separate pane. Sizes read like 4096 bytes (4.0 KB).

A category the analysis was not started with shows Not requested and a Run button. Run adds that check to the same report without starting the analysis again: the specimen kept with the report is analysed by the one check, and its tab fills in when it ends. The button waits while the analysis is still being made. No VM has to be running, and the result is saved with the report like the others.

Static Analysis in a narrow window: the Report dropdown on /fixture/REPORT B — analysis only (Partial), the tab row wrapped onto two lines with Disassembly and Decompilation greyed, and the Summary with the Identity card beside the Categories card (Metadata Complete, Structures Unavailable, Strings Partial, Regex matches Not requested with Run).
An Analyze Only report in a narrow window; categories the report lacks are greyed. Antinomie 0.8.0, synthetic data.
The Strings tab on Partial · 1024 rows with Export category… and an open-in-pane button, the note 1024 retained synthetic strings; text bounded, a filter box, 1024 matching / 1024 retained, and columns File offset, Encoding, Byte length, Retained and Value.
Antinomie 0.8.0, synthetic data.

Strings lists ASCII and UTF-16LE strings of four or more characters with their file offset, encoding and length. It sorts over the whole listing, not just the page on screen: the filter applies first, then every matching row is ordered and the page you are on is read. The rows on screen stay while the new order is read (Sorting…).

Regex matches shows every pattern match in the Strings and FLOSS strings, by category (Network, Crypto, Keys, Linux behaviour, Attribution, Encoded) with a type for each match, such as IPv4 public or private, URL, Bitcoin address or persistence path. Matches are checked to cut false positives: a domain must end in a real public suffix, libc.so and install.sh are files, a version number is not an IP address, and a Bitcoin address, Tox ID or token must pass its checksum or structure. Base64 and hex text is decoded and scanned again, two levels deep; the Inside column says which. Switch patterns off or add your own in Detection rules › Strings regex. The same list opens from Core dumps › Strings › Regex matches….

FLOSS (off by default, under Deep analysis) recovers the strings a program builds on the stack or decodes at run time, which Strings cannot see, one row per string with its type (decoded, stack, tight, or language for Go and Rust), its encoding and the address FLOSS reports for the routine. FLOSS reads the file with its own disassembler and emulates snippets of it; the program is never run. It can take several minutes, has an 8-minute limit, and does not take files over 16 MiB.

Unpacking looks for UPX packing. A packed file is unpacked, without running it, and the result is a layer with its own hash and its own static analysis. The Layer drop-down chooses the file As it came or a layer UPX recovered from the one before; below it are that layer’s size, SHA-256 and the packer found in it, and Show its analysis opens the layer’s own report. A file packed twice gives two layers. Files whose UPX headers were tampered with are repaired on a copy first, and the layer says so (UPX (header repaired)). The original file is never changed, layers are plain files that are not executable, at most three layers of 64 MiB each are kept, and unpacking stops after 4 minutes. Other packers are not unpacked.

When the program the run started is such a packed file, Triage shows the Suspicious activity row evasion.packed_image as a fact about the file.

The Disassembly tab on Complete · 105 rows with Export category…, a filter box with the hint mnemonic == call, Functions · 6 with Export text, the function sidebar _start, main, beacon_loop, fetch_stage2, decrypt_config and persist with their addresses and line counts, and the listing with Address, Bytes and Instruction, each function starting with a heading row such as main · 0x401100, 9 lines.
Antinomie 0.8.0, synthetic data.

Disassembly and Decompilation are full listings with search. They keep their address and line order, so their headers do not sort; hovering one says why. Their function sidebar is shared with Core dumps, and a function reads like 0x401c20 · 12 lines: its instructions in Disassembly, its source lines in Decompilation.

  • Click a row to select it. Its full values appear in Details, which says Nothing selected. until then. A row with a file offset can open in Content.
  • Right-click a row for Copy of any column, Copy row, Show details…, Show bytes… and Show in Content. Show details… and Show bytes… open their own movable windows.
  • The open-in-pane button beside a category opens it in a separate dockable pane.

Each category finishes on its own. While the worker runs, a category shows what it is doing (waiting for the worker, running, or its result). If the worker is stopped at its deadline or crashes, the categories that had finished keep their results, including their full listings, and only the unfinished ones are marked as not finished. The worker’s deadline is the sum of its categories’ own budgets, so a slow capa run does not use up the time decompilation needs.

capa analyses the whole bundled C library of a statically linked program and often runs out of its 4 minutes. The Capabilities category then says that capa ran out of time and that statically linked programs take it much longer.

Export report… (or Export category… on one tab) offers Plain text (.txt), Structured results (.json), Native Ghidra project (.gpr + .rep) and Open in Ghidra (after a Ghidra analysis that kept its project). Exports include all retained rows. Open result directory shows the saved report, the specimen, full listings and any native artifacts.

A failed or missing tool is shown as unavailable while the program still ran. A match or identification is evidence to investigate, not a verdict. Tools are managed in Library › Analysis tools; see also Installation and requirements.

Static Analysis of a real run of /tmp/triage-sample in Antinomie 0.6.2: File Info › Summary with State Partial, the path, MD5, SHA-1, SHA-256, format Elf, architecture X86_64 and class 64-bit, and the categories Metadata, Structures, Strings, Entropy, Hardening and Identification Complete with their row counts, and Rules and Capabilities Unavailable.
A real report of an ELF executable, from a 0.6.2 recording. Antinomie 0.6.2, a recorded run.