Skip to content
github-actions[bot] edited this page Nov 7, 2026 · 3 revisions

comms

Exports every communication record of a case into one list: SMS, MMS, calls, contacts, calendar, WhatsApp (and its backups), Signal, Telegram, Messenger, Instagram, Snapchat, e-mail, browser history, locations, clipboard and typed text, crypto wallet addresses. Deleted records recovered are flagged.

Prerequisites

Requirement Why
A case acquired or imported with --mandate <ref> without it no communication was collected; comms exits with code 1 and says so
For app data (WhatsApp databases, Signal, Messenger…): a case from import of an after-first-unlock extraction a live phone without root gives SMS, MMS, calls, calendar and WhatsApp backup files only
For Signal: its database secret, found automatically in older versions; otherwise --signal-key <hex> from the lab newer Signal versions protect it with the Android Keystore
For WhatsApp backups: files/key or files/encrypted_backup.key in the extraction, or the 64-digit end-to-end key (--wa-key) on a live phone without root these key files are out of reach
For Signal backups (signal-*.backup): the 30-digit passphrase (--signal-passphrase) shown once, when chat backups are turned on in Signal

No phone, no network. Details per source: Communications and app data.

Usage

apex comms ./case-42                                  # → ./case-42_comms/
apex comms ./case-42 -o ./case-42-comms
apex comms ./case-42 --signal-key 9f8e7d…             # Signal secret recovered by the lab
apex comms ./case-42 --wa-key 3a1f…                   # WhatsApp 64-digit end-to-end key, no spaces
apex comms ./case-42 --signal-passphrase "12345 12345 12345 12345 12345 12345"
Option Effect
-o, --output <DIR> output directory (default <case>_comms)
--signal-key <HEX> Signal database secret
--wa-key <HEX> WhatsApp 64-digit end-to-end backup key (type it without the spaces WhatsApp shows)
--signal-passphrase <DIGITS> Signal backup passphrase, 30 digits (spaces allowed)

Prefer typing keys yourself in a terminal over pasting them into shared notes: they unlock everything the backup holds.

Output

The terminal shows the count per kind and how many were recovered from deleted records, and a ⚠ line for every source it could not open, with the reason (missing key, encrypted database…).

File Content
comms.db SQLite, table comms, indexed on time, kind and peer: query it with SQL
comms.csv time, kind, direction, peer, text, extra, source, recovered
comms.json the same, as JSON
locations.kml Google Maps destinations and saved places, when present
signal_files/<backup>/{attachment,avatar,sticker}/… files carried by Signal backups, extension from their content

comms.db

Column Content
time phone local time, ISO 8601 with UTC offset
time_ms epoch milliseconds (0 = unknown, e.g. contacts)
kind sms, mms, call, contact, calendar, whatsapp, signal, telegram, messenger, instagram, snapchat, email, web, download, location, clipboard, keyboard, wallet
direction in, out, missed, … or empty
peer number, JID, user ID with name
text, extra message text; duration, attachment, coordinates lat,lon
source database or backup file it comes from
recovered 1 = deleted record recovered
sqlite3 case-42_comms/comms.db "SELECT time, kind, peer, text FROM comms WHERE text LIKE '%colis%' ORDER BY time_ms"
sqlite3 case-42_comms/comms.db "SELECT peer, count(*) FROM comms GROUP BY peer ORDER BY 2 DESC LIMIT 10"

Contacts come from the shell, the extraction, or the APEX agent when the shell is refused. A bare number in any record gets the contact's name added (+33612345678 (Dédé)), matched on the last nine digits.

time is the phone's local time with its UTC offset. recovered = true marks a record deleted from the database and carved back, or a WhatsApp backup message no longer in the live database. See Deleted records.

Everything also goes into the timeline and search; the report and PV show counts only.

Clone this wiki locally