Recovering Deleted-File Evidence from the $LogFile
What the NTFS $LogFile keeps after a deletion: name, folder, MFT entry, times, sizes, data runs, sometimes content. How to find it and what it cannot prove.
TL;DR. A deletion in $LogFile is typically a DeleteIndexEntry* (name removed from the parent folder) followed by DeallocateFileRecordSegment (FILE record freed). Those records — plus the file's creation, if still in the log — give you the name, parent folder, MFT entry and sequence number, $FILE_NAME times, sizes, often the last $STANDARD_INFORMATION values, sometimes data runs and, for tiny files, content. The log does not give you a deletion time; the best you get is "at or after the last known timestamp". Files sent to the Recycle Bin are renames, not deletions.
Short-lived files are the attacker's favourite: download, unpack, run, delete. By the time you image the disk, the FILE record has been reused, the $I30 slack has been overwritten and the USN journal says FILE_DELETE with a name and nothing else. $LogFile can still hold the structure of the file as NTFS last saw it — for the last minutes to hours.
What a deletion writes to the log
| Step | Operation | What the bytes contain |
|---|---|---|
| Name removed from folder | DeleteIndexEntryRoot or DeleteIndexEntryAllocation | The removed index entry: file reference (entry + sequence), and an embedded $FILE_NAME with parent reference, name, four times, allocated and real size, flags |
| FILE record freed | DeallocateFileRecordSegment | Target entry; the undo side lets NTFS restore the record |
| MFT bitmap bit cleared | ClearBitsInNonresidentBitMap | Which MFT entry became free |
| Clusters freed | ClearBitsInNonresidentBitMap on $Bitmap | Which clusters became free (non-resident files) |
Which of redo or undo holds the removed index entry is one of the details that parsers handle differently; the in-browser parser tries both. The operations themselves are covered in redo/undo operations explained.
What you can reconstruct
Name and location. From the index entry, even if the creation fell outside the log. The parent is an MFT reference; resolve it with the $MFT of the same volume, or you will see [MFT #n] for unknown folders.
Identity. MFT entry and sequence number. When an entry is reused, NTFS increments its sequence number (as the LogFileParser readme notes for its filename history), so entry + sequence distinguishes the deleted file from whatever lives in that entry today.
Times. The $FILE_NAME times from the index entry and, if the log still holds earlier records for the entry, the last $STANDARD_INFORMATION values. Neither is the deletion time.
Sizes. Allocated and real size from $FILE_NAME in the index entry. Treat them with care: $FILE_NAME sizes in directory entries are not always kept current.
Data runs. If the file's creation (InitializeFileRecordSegment, CreateAttribute) and later UpdateMappingPairs records are still in the log, its cluster runs can be rebuilt. LogFileParser implements this and documents recovering fragmented deleted files whose FILE record was overwritten, provided the clusters themselves were not reused.
Content (small files only). A file small enough to be resident stores its content inside the FILE record. If the record image or the CreateAttribute for its $DATA survives in the log, so does the content. This is opportunistic: LogFileParser's author notes that on modern Windows, later changes to resident data generally log only that a change happened, not the new bytes.
Deletion time: what you can and cannot say
Log records have no clock. For a deletion, the best bound from the log alone is "at or after the newest timestamp known for that file" — usually its last $SI modified/changed value. The in-browser parser labels such events "last known time — deleted at or after it".
For a real time, correlate:
- USN journal
FILE_DELETErecord for the same file reference (USN journal parser); - a neighbouring event in the log that does carry a time (order by LSN);
- Security or Sysmon events for process activity around it (EVTX parser).
Recycle Bin: a move, not a deletion
Deleting from Explorer without Shift moves the file into $Recycle.Bin\<SID>\ under a $R… name and creates a matching $I… file with the original path and deletion time. In $LogFile this shows up as a rename/move into $Recycle.Bin plus a creation of the $I file, not as a deallocation. The actual deallocation only comes when the bin is emptied. The $I file is small and resident, so its content can appear in the log too; parse it properly with the Recycle Bin parser.
Worked example (synthetic sample)
In the parser's sample (synthetic, fictional host FIN-WKS-07):
| LSN | Event | Detail |
|---|---|---|
| 117494 | Create | \Users\svc_backup\Desktop\creds.txt, $FN created 10:38:10.5119430 |
| 117577 | Resident data written | First bytes of the file (a fake credential note marked SYNTHETIC) |
| 117610 | $SI change | Modified / changed / accessed → 10:38:27.7024018 |
| 117804 | Delete | Same entry; time "last known — deleted at or after" 10:38:27.7024018 |
Between creation and deletion, the log also shows a .lnk created in Recent — a lead for the LNK parser. In a real case you would now look for the USN FILE_DELETE record to date the deletion, and for the content in any other copy (backups, cloud sync, memory: RAM parser).
The same sample shows an innocent deletion too: \Windows\Temp\~DF3A1B7C2E.TMP, created and deleted within one minute. Temporary files churn constantly; the deletion flag is a triage aid, not a finding.
Where it breaks
- Retention. A deletion from yesterday on a system volume is almost certainly gone. See how far back the $LogFile goes.
- Grouping. A deletion whose creation is outside the log has fewer facts; a parser grouping by proximity (as the in-browser parser currently does) may attach neighbouring records wrongly. Check the raw records.
- Reused entries. Resolving paths from an
$MFTtaken later can name the new occupant of an entry or parent. Compare sequence numbers; the in-browser parser does not yet check them when resolving paths from the$MFT. - Validation. The in-browser parser is validated on synthetic logs only; confirm deletions that matter with LogFileParser or NTFS Log Tracker (comparison).
Frequently asked questions
Can the $LogFile show deleted files?
Yes, if the deletion is recent enough to still be in the circular log. The index entry removal and the FILE record deallocation carry the file's name, parent folder, MFT entry and sequence number, $FILE_NAME times and sizes.
Can I recover a deleted file's content from the $LogFile?
Rarely, and only for small resident files whose content appears in a FILE record image or attribute creation still in the log. For larger files, the log may hold data runs that point to clusters, which can help carving if the clusters were not reused.