Analyze and Display Windows restore point information
From KnowWiki
This Perl script allows you to see contents of a restore point for Windows. It is very useful in analyzing windows information on a disk from a failed machine. Run this script from a working station after mounting the disk from a broken system.
There is also a script to Restore files from a Windows Restore Point.
#!/bin/perl # this code will parse up the Windows Restore point information and display it use warnings; use Switch; use IO::Seekable qw(SEEK_SET SEEK_CUR SEEK_END); $dir=shift; defined ($dir) || die "Just give me a folder like C:\\System Volume Information\\_restore{...}\\RP28 as a parameter and I will do the rest\n"; $ops=shift; $verbose=0; $verbose=1 if (defined($ops) && $ops eq "-v"); $|=1; # autoflush stdio open(F, "$dir/rp.log") || die "cant open rp.log"; binmode(F); sysseek(F,4,SEEK_SET); sysread(F,$type,4); sysseek(F,8,SEEK_CUR); sysread(F,$name,512); sysread(F,$datetime,8); print unidecode($name); print "Restore point type:".unpack("h4",$type)." date:".unpack("h16",$datetime)."\n" if $verbose; close(F); opendir(DIR, "$dir") || die "cant open $dir"; my @entities=grep(/change\.log.*/i, readdir DIR); foreach my $entity (@entities) { print "Changes in $entity:\n" if $verbose; open (F,"$dir/$entity") || die "$dir/$entity"; $i=0; while (sysread(F,$temp,4) != 0){ $len=unpack("l",$temp); sysread(F,$temp,4); $type=unpack("l",$temp); sysread(F,$temp,4); $sig=unpack("h8",$temp); if ($sig ne "21fedcba"){ print "invalid signature $sig\n"; exit 1; } sysread(F,$payload,$len-16); sysseek(F,4,1); print "Rec $i len:$len type:$type" if $verbose; if ($type == 0){ # changelog name $reclen=unpack("l",substr($payload,4,4)); print " len:$reclen change log:".unidecode(substr($payload,12,length($payload)-12))."\n" if $verbose; } elsif ($type == 1){ # file name $changetype=unpack("l",substr($payload,0,4)); print " type:" if $verbose; switch ($changetype){ case 0x00000001 {print "Modify File "} case 0x00000002 {print "Update ACL "} case 0x00000004 {print "Update Attributes"} case 0x00000010 {print "Delete File "} case 0x00000020 {print "Create File "} case 0x00000040 {print "Rename File "} case 0x00000080 {print "Create directory "} case 0x00000100 {print "Rename directory "} case 0x00000200 {print "Delete directory "} case 0x00000400 {print "MNT-CREATE"} } $flags=unpack("h8",substr($payload,4,4)); $attributes=unpack("h8",substr($payload,8,4)); $eventid=unpack("l",substr($payload,12,4)); print " flags:$flags attr:$attributes eventid:$eventid\n" if $verbose; $offset=52; $j=0; while ($offset < $len-16){ $fieldlen=unpack("l",substr($payload,$offset,4)); if ($fieldlen==0) { print "ups"; exit 1; } $fieldtype=unpack("l",substr($payload,$offset+4,4)); $field=substr($payload,$offset+8,$fieldlen-8); print "> Field $j subtype:" if $verbose; if ($verbose){ switch ($fieldtype){ case 0x00000003 {print "long original filename"} case 0x00000004 {print "long new filename "} case 0x00000005 {print "backup filename "} case 0x00000006 {print "ACL "} case 0x00000009 {print "short orig filename "} case 0x0000000A {print "short new filename "} } print " contents:".(($fieldtype == 0x00000006)?unpack("h*",$field):unidecode($field))."\n"; } else { switch ($fieldtype){ case 0x00000003 {print "O:"} case 0x00000004 {print "N:"} case 0x00000005 {print "b:"} case 0x0000000A {print "n:"} } print unidecode($field)." " if ($fieldtype != 0x00000006 && $fieldtype !=0x00000009); } $offset+=$fieldlen; $j++; } print "\n" if not $verbose; } $i++; } close F; } sub unidecode { $data=shift; $off=0; $result=""; while ($off < length($data) && (substr($data,$off,1) ne "\0")){ $result.=substr($data,$off,1); $off+=2; # print substr($data,$offset,1)."-".$offset."\n"; } $result; }