Tuesday, October 20, 2009

Processing Vista $RECYCLE.BIN

The MS Windows recycle bin differs in Vista from XP. In XP, an deleted file is moved to the "\Recycler\$SID\ folder where "$SID" is the security identifier of the user deleting the file. The file is renamed, in the format "D" An "info2" file is created containing the file's original name, file deleted time, and original file size. In Linux, the command line tool rifuiti can be used to parse the info2 file. More information about the XP recycle bin can be found here.

Vista has a different schema, however. Deleted files are moved to the "\$RECYCLE.BIN\$SID\" folder, but this time no info2 file is created. Instead, a pair of files is created: the file itself is renamed randomly beginning with "$R" and an information file containing the 16-bit filename with the same name as the data file only beginning instead with "$I". Both files take on the extension of the original file. Deleted folders are subjected to the same deletion scheme, but the files and subdirectories within the deleted folders retain their original names and paths within the directory and are not otherwise represented in the recycle bin. The original file size and date of deletion are also contained in hex within the file. More information about the Vista recycle bin can be found here.

In Linux, one can quickly examine all the filenames of deleted files found in the Vista recycle bin. In the command line, simply change to the "/$RECYLE.BIN/$SID/" directory and issue this simple command:
# strings -el -f \$I*
The -el flag tells the command to look for 16-bit encoding and "-f" to print the filename of each processed file. The output resembles the following:
# strings -el -f \$I*
$I3XJZSP.docx: C:\Users\957630\Documents\1234567.docx
$I42NQXL.lnk: C:\Users\Public\Desktop\HP Total Care Advisor.lnk
$I4ULAZJ.url: C:\Users\957630\Desktop\Videos.url
$I96F8EZ.txt: C:\Users\957630\Documents\dm123.txt
$IA7VIFO.lnk: C:\Users\957630\Desktop\Mini400.lnk
...

File size and deletion date of files of interest can be determined from a hex view of the file.
0000000: 0100 0000 0000 0000 da26 0000 0000 0000 .........&......
0000010: d02a 0401 4c5c c901 4300 3a00 5c00 5500 .*..L\..C.:.\.U.
0000020: 7300 6500 7200 7300 5c00 3900 3500 3700 s.e.r.s.\.9.5.7.
0000030: 3600 3300 3000 5c00 4400 6f00 6300 7500 6.3.0.\.D.o.c.u.
0000040: 6d00 6500 6e00 7400 7300 5c00 3100 3200 m.e.n.t.s.\.1.2.
0000050: 3300 3400 3500 3600 3700 2e00 6400 6f00 3.4.5.6.7...d.o.
0000060: 6300 7800 0000 0000 0000 0000 0000 0000 c.x.............
0000070: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0000080: 0000 0000 0000 0000 0000 0000 0000 0000 ................

The first 8-bits of the file is the file header, the second is the file size, and the third is the deletion date. Thus, for this file, the original file size was 0xda26 or 55846 bytes:
# echo $((0xda26))
55846

And, the file deletion date was 0xd02a04014c5cc901 or "Fri Dec 12 03:23:06 PST 2008." This determination is a little more difficult and would benefit from a script, but for now, I'll show how its done manually.

Windows Time is recorded in Little endian format, thus we start with 0x01c95c4c01042ad0 which is 128735545861090000 nanoseconds since January 1, 1601. We devide by 10,000,000 (to convert from nanoseconds to seconds), and then subtract 11644473600 (the number of seconds between Windows Time and Unix Time, which is the number of seconds since January 1, 1970). Finally we convert to standard notation with the "date" command.
# echo $((0x01c95c4c01042ad0))
128735545861090000

# echo $((128735545861090000/10000000))
12873554586

# echo $((12873554586-11644473600))
1229080986

# date -d @1229080986
Fri Dec 12 03:23:06 PST 2008
In one command, this looks like:
# date -d @$((((0x01c95c4c01042ad0)/10000000)-11644473600))
Fri Dec 12 03:23:06 PST 2008
I'll contemplate writing a script to automate the whole process--filename, file size, deletion date--in the future. But for now, this will work.