Scanning
exav prints clamscan’s output format. The flags are exav’s own, and there is a
fourth exit code. This guide covers everyday scanning; see the
CLI reference for every flag.
Targets
Section titled “Targets”exav file.bin # scan one fileexav /var/www # scan a directory, recursivelyexav --no-recursive /var/www # just the directory's own filesexav --quiet /data # only print detections, partial results and errorsexav --files-from list.txt # paths from a file, one per linecat file.zip | exav - # scan stdinexav --allow-http-scan https://host/obj.zip # over HTTP range requests (an `http-scan` build)exav -d ./mydb /data # use a signature database (file or dir)Examples without -d load --sig-dir: /var/lib/exav by default, or
EXAV_SIG_DIR as set in the quick start. See
Signatures.
Stdin, and a FIFO given as a path, is held before it is scanned (in RAM, then in a temporary file past 16 MiB), then gets the same scan as a file. See buffering a stream for the bounds.
Scanning over HTTP
Section titled “Scanning over HTTP”The server must answer range requests. An object up to --max-object-bytes is
read once, in full; a larger one is read in ranges as the scan needs them, some
parts more than once (see
the block cache).
To pay in disk instead of transfer (metered egress, a slow link, per-request billing), download the object and scan the file:
curl -fsSO https://host/obj.zip && exav obj.zip-f matters: without it an error page is saved and scanned as OK.
Output format
Section titled “Output format”The human-readable output is one line per file, followed by a clamscan-style
summary:
/path/to/file: Win.Trojan.Agent-1234 FOUND/path/to/clean: OK/path/to/missing: No such file or directory (os error 2) ERROR/path/to/huge.bin: file size 9663676416 exceeds max-input-bytes 4294967296; scanned first 4294967296 bytes only LIMITS-EXCEEDED PARTIAL/path/to/secret.zip: encrypted ZIP member PASSWORD-PROTECTED PARTIALA file that could not be fully examined ends with the reason, then the
category of the condition, then the status PARTIAL.
(The huge.bin line comes from a run with --max-input-bytes 4G; by default
there is no input size limit.)
--quiet suppresses the OK lines and the summary, never an error; -v adds
detail.
JSON output
Section titled “JSON output”--json emits newline-delimited JSON: one object per scanned input, then a
summary object (left out under --quiet). Keys come out in alphabetical order,
and findings (the detected type, and more with --detect exav-heuristics) is
on every result that has any, with or without -v:
$ exav --json /data{"file":"/data/file","method":"pattern","offset":1234,"signature":"Win.Trojan.Agent-1234","status":"FOUND"}{"file":"/data/clean.txt","findings":[{"detail":"ASCII text","label":"type"}],"status":"OK"}{"category":"LIMITS-EXCEEDED","file":"/data/huge.bin","findings":[{"detail":"ASCII text","label":"type"}],"reason":"file size 9663676416 exceeds max-input-bytes 4294967296; scanned first 4294967296 bytes only","status":"PARTIAL"}{"summary":{"data_scanned_bytes":4294972634,"elapsed_secs":0.042,"errors":0,"infected":1,"partial":1,"scanned":3}}status is on every result object and is the word the human line ends with.
category only appears on a PARTIAL, so filter on status:
exav --json /data | jq 'select(.status=="PARTIAL" or .partial)' # not fully examinedexav --json /data | jq 'select(.status and .status != "OK")' # everything not clean.partial covers --all-matches, where a result lists its detections in
signatures and carries "partial":true and partial_reasons when the search
stopped short.
Verbose findings
Section titled “Verbose findings”-v / --verbose prints informational findings alongside the verdict: the
detected file type, and with --detect exav-heuristics also the imphash, section
entropy and the static score.
All-match mode
Section titled “All-match mode”By default exav stops at the first matching signature per file. --all-matches
reports every match (clamscan’s --allmatch):
exav --all-matches /dataFilters
Section titled “Filters”Include and exclude by path regex, repeatable, with clamscan’s semantics:
exav /data --exclude '\.log$' --exclude-dir 'node_modules' --include '\.exe$'--exclude-dir matches a directory’s own path, which has no trailing separator:
node_modules skips the directory, while /node_modules/ only skips what is
nested below it and lets files directly inside through. To anchor it, write
/node_modules($|/).
Exit codes
Section titled “Exit codes”0 OK, 1 FOUND, 2 ERROR (exav could not do its job), 3 PARTIAL (a
file could not be fully examined). 3 is kept apart from 2 so that “the
scanner broke” and “this file needs a decision” are different signals;
--partial-as maps it to
another status. See which code a run exits with.
Encrypted archives
Section titled “Encrypted archives”An encrypted member is reported PASSWORD-PROTECTED. Supply passwords to decrypt
it and scan inside:
exav --passwords secret --passwords hunter2 /data # tried in orderexav --passwords-from /etc/exav/passwords /data # kept out of `ps`Passwords also load from a ClamAV .pwdb database in the signature directory,
and a few common ones are tried without being asked. See
Encryption and passwords for the formats
exav decrypts and the passwords it tries by default.
An encrypted ZIP appended to a picture or a document (a polyglot that archive tools open by its trailing directory) is reported the same way once its structure is confirmed.
Heuristics
Section titled “Heuristics”A small set of low-false-positive heuristics runs by default, the ones ClamAV
itself reports: imphash matching, the PDF obfuscated-name check, overlapping ZIP
records and the XZ dictionary-size check.
--detect exav-heuristics adds exav’s own (TLSH fuzzy matching, a hand-weighted
static scorer, and a packed-with-injection-imports check), which carry more
false-positive risk and are opt-in:
exav --detect exav-heuristics -v sample.exe--detect takes all, none, or a comma-separated list of exav-heuristics,
macros, broken, broken-media, partition-intersection, phishing,
packed, pua.