Analyze and Display Windows restore point information

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;
}

@Tools @Windows




Backlinks: iamhow.com:Tools and Scripts:Restore files from a Windows Restore Point