RULE 0 — COPY WITH SIDE-CARS →
SQLite browser DBs are WAL-mode. Always collect the DB with its -wal and -shm
files — the newest (and many deleted) rows live only in the unmerged WAL. Opening a live DB checkpoints it and
destroys that evidence. Work on copies, read-only.
ENUMERATE EVERY PROFILE →
Chromium: Default, Profile 1, Profile 2… (one Local State key decrypts all).
Firefox: read profiles.ini — modern default is *.default-release, legacy is *.default.
Firefox splits Windows storage: DBs in Roaming (%APPDATA%), cache2 in Local (%LOCALAPPDATA%).
02Chromium (Chrome / Edge / Brave / Opera)
Artifacts (all SQLite unless noted; no file extension)
# recent history, WebKit time → human
sqlite3 -readonly History "SELECT
datetime(last_visit_time/1000000-11644473600,
'unixepoch') t,url,title FROM urls
ORDER BY last_visit_time DESC LIMIT 50;"# search terms typed by the user
sqlite3 History "SELECT term FROM keyword_search_terms;"# downloads
sqlite3 History "SELECT target_path,tab_url,
received_bytes FROM downloads;"
"They cleared history" — still recoverable
# Cleared History does NOT clear these:
- Top Sites, Favicons (icon_mapping)
- Shortcuts (typed omnibox text)
- Sessions / SNSS (open + last tabs)
- Cache_Data (viewed URLs)
- Local Storage / IndexedDB LevelDB
- the -wal + freelist of History itself (§07)
03Firefox / Gecko (+ Tor Browser)
Artifacts (profile root unless noted)
File
Key tables / content
places.sqlite
moz_places(url,title,visit_count,last_visit_date) + moz_historyvisits(place_id,visit_date,visit_type) + moz_bookmarks + moz_annos (downloads live here post-Fx21)
sqlite3 places.sqlite "SELECT
datetime(h.visit_date/1000000,'unixepoch') t,
p.url,p.title FROM moz_places p
JOIN moz_historyvisits h ON p.id=h.place_id
ORDER BY t;"# PRTime = µs since 1970 (NOT 1601!)# decompress recovered tabs (mozLz4)
dejsonlz4 sessionstore-backups/recovery.jsonlz4 out.json
WebView2 — standard Chromium artifacts under EBWebView (confirm package: MSTeams_* work vs consumer)
Signal
%APPDATA%\Signal\
sql\db.sqlite is SQLCipher; key wrapped in config.json via safeStorage (DPAPI) → unwrap in user ctx, then PRAGMA key
Parse app LevelDB
# forensicsim — Teams/Slack/Discord IndexedDB → messages
python dump_leveldb.py -i <...indexeddb.leveldb> -o out.json
# same simple-cache format as browsers:
ChromeCacheView.exe /CacheFolder "...\Cache\Cache_Data" /scomma c.csv
Note
# Tokens in LevelDB are recovery artifacts of an# authenticated session — treat as session/credential# recovery for the investigation. Full server-side# message history usually needs a provider/legal request.
kape.exe --tsource C: --target Chrome,Edge,FireFox --tdest out
# add Slack/Teams/Discord targets for chat data
unfurl "https://www.google.com/search?q=...&ei=..."# breaks a URL into search terms / embedded timestamps / IDs
WORKFLOW →
① Enumerate every profile (Chromium Profile N, Firefox profiles.ini)
② Copy each DB with -wal/-shm, work read-only
③ Timeline with hindsight / dumpzilla — mind the epoch per browser
④ Creds/cookies → Local State key (§05) or firefox_decrypt
⑤ "Cleared"? → Sessions/SNSS, Favicons, Cache, LevelDB, WAL/freelist
⑥ Chat app? → same engines, parse LevelDB/IndexedDB (§08)
⑦ Incognito? → memory/pagefile/hiberfil (§07)