Support Forums

Welcome to Support Forums Sign in | Join | Help
in
Home Forums

Reading binary contents from a file

Last post 10-16-2006, 2:44 PM by Chris. 4 replies.
Sort Posts: Previous
  • Reading binary contents from a file

     10-12-2006, 4:56 PM

    • Joined on 04-20-2006
    • Northern VA
    • Posts 35
    • Top 10 Contributor
    I'm having trouble reading some data from files in PD 4.8.  Here's the issue:


    I'm trying to parse data from the rp.log files in the XP restore points.  I have no trouble locating the system drive, navigating to the necessary directories, and getting a list of files.  I'm also able to go to offset 0x210 in the file, read in 8 bytes, and compute the creation time.

    My problem now is getting the description from the file.  The description is a null-terminated Unicode string starting at offset 0x10.  I can get there easily enough and get the first letter, but after that, my code bombs (code pasted below).  Ideally what I want getRpDescr() to do is return the description string.  I'm trying to just get it to read the bytes now, and I'm having some trouble.  Here's what the output looks like for me (excerpt):

    RP25
        Offset = 16
        S
        Offset = 18
       
        Offset = 20
       
        Offset = 22
       
        Offset = 24
        e
        Offset = 26
       
        Offset = 28
       
        Offset = 30
       
        Offset = 32
        h
        Offset = 34
       
        Thu Jan 20 20:56:37 2005 (UTC)
    RP26
        Offset = 16
        S
        Offset = 18
       
        Offset = 20
       
        Offset = 22
       
        Offset = 24
        w
        Offset = 26
       
        Offset = 28
       
        Offset = 30
       
        Offset = 32
         
        Offset = 34
       
        Thu Jan 20 21:05:47 2005 (UTC)

    Thanks,

    Harlan

    -----------------------------------------------------------------------------------------
    #! c:\perl\bin\perl.exe
    #-------------------------------------------------------------
    # SysRestore.pl, version 0.1
    # ProScript to parse the System Restore subdirectories for rp.log files, and
    # then parse the files for description and creation time info                        
    #
    # Copyright 2006 H. Carvey, keydet89@yahoo.com
    #-------------------------------------------------------------
    use ProScript;
    PSDisplayText("SysRestore.pl v. 0.1");
    PSDisplayText("ProScript to parse through the System Restore subdirectories on Windows XP");
    PSDisplayText("systems and return the descriptions and creation times from the rp\.log files.");
    PSDisplayText("\n");
    #-------------------------------------------------------------
    # Get the SystemRoot value
    my %sysinfo = ();
    $numRegs = PSGetNumRegistries();

    if ($numRegs == 0) {
        PSDisplayText("No registries to process");
        return;
    }

    $regName = PSGetRegistryAt(0);
    PSRefreshRegistry($regName);
    my $keyName = "HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion";
    my $rHandle = PSOpenRegistry($regName, $keyName);

    if ($rHandle == 0) {
        PSDisplayText("Unable to locate registry key");
        return;
    }
    else {
    #    PSDisplayText("Registry opened succesfully.");
    }

    while (1) {
        $RegKeyInfo  = &ProScript::PSReadRegistry($rHandle);
      last if ($RegKeyInfo->{nType} == -1);
      next if ($RegKeyInfo->{nType} == PS_TYPE_KEY);
      my $value = $RegKeyInfo->{strRegName};
      my $data  = $RegKeyInfo->{strValueData};
    #  PSDisplayText($value." --> ".$data);
      $sysinfo{$value} = $data;
    }
    PSCloseHandle($rHandle);
    #-------------------------------------------------------------
    # Now we have a %sysinfo hash, and all we really want is the
    # "SystemRoot" value

    my $sysroot = $sysinfo{"SystemRoot"};
    my $drive   = (split(/:/,$sysinfo{"SystemRoot"},2))[0];
    # $drive should now just be a drive letter

    my $objectName = PSGetObjectName(0);
    my $path       = $objectName."\\".$drive.":\\System Volume Information";

    #---------------------------------------------------------
    # First, we need to get the name of the _restore directory
    #---------------------------------------------------------
    my $pHandle = PSOpenDir($path,0);
    if ($pHandle == NULL) {
        PSDisplayText("$path not opened.");
    }
    my $rest = "_restore";
    my $restoredir;
    my $tag = 1;
    while ($tag) {
        my $file = &ProScript::PSReadDirectory($pHandle);
        $tag = 0 if ($file == NULL || $file->{strName} eq "");
        $restoredir = $file->{strName} if ($file->{bIsDirectory} && $file->{strName} =~ m/^$rest/i);
    #    PSDisplayText("Name : $file->{strName}");
    }
    PSCloseHandle($pHandle);

    $path = $path."\\".$restoredir."\\";

    #---------------------------------------------------------
    # Now, we need to get the list of subdirectories
    #---------------------------------------------------------
    my @rpdirs = ();
    my $rpdir = "RP";

    my $pHandle = PSOpenDir($path,0);
    if ($pHandle == NULL) {
        PSDisplayText("$path not opened.");
    }
    my $tag = 1;
    while ($tag) {
        my $file = &ProScript::PSReadDirectory($pHandle);
        $tag = 0 if ($file == NULL || $file->{strName} eq "");
        push(@rpdirs,$file->{strName}) if ($file->{bIsDirectory} && $file->{strName} =~ m/^$rpdir/);
    #    PSDisplayText("Name : $file->{strName}");
    }
    PSCloseHandle($pHandle);
    foreach my $rp (@rpdirs) {
        $rp_path = $path.$rp."\\rp\.log";
        PSDisplayText($rp);
        getRpDescr($rp_path);
        my $creation = getCreationTime($rp_path);
        PSDisplayText("\t$creation (UTC)");
    }


    #---------------------------------------------------------
    # getCreationTime()
    # Read the rp.log file to get the description and creation
    # date
    #---------------------------------------------------------
    sub getCreationTime {
        my $path = shift;
        my $t_val = 0;
        if (my $oFile = PSOpen($path)) {
           
            if (PSSeek($oFile,0x210,0,PS_FILE_BEGIN)) {
    #            my $buffer = &ProScript::PSReadRaw($oFile,8);
                my $buffer = PSReadRaw($oFile,8);
    #            PSCloseHandle($oFile);
                my @vals = unpack("VV",$buffer);
                $t_val = getTime($vals[0],$vals[1]);
            }
            else {
                PSDisplayText("File seek to first offset failed.");
            }
        }
        else {
            PSDisplayText("File could not be opened.");
        }   
        PSClose($oFile);
        return gmtime($t_val);
    }

    #---------------------------------------------------------
    # getRpDescr()
    # Read the rp.log file to get the description and creation
    # date
    #---------------------------------------------------------
    sub getRpDescr {
        my $path = shift;
        my $buffer;
        my $tag = 1;
        my $offset = 0x10;
        my $str;
        if (my $oFile = PSOpen($path)) {
            foreach (0..9) {
                PSDisplayText("\tOffset = $offset");
                PSSeek($oFile,$offset,0,PS_FILE_BEGIN);
                $buffer = PSReadRaw($oFile,2);
                PSDisplayText("\t$buffer");
                $offset += 2;
            }
            PSClose($oFile);
        }
        else {
            PSDisplayText("File could not be opened.");
        }   
    }

    #---------------------------------------------------------
    # getTime()
    # Get Unix-style date/time from FILETIME object
    # Input : 8 byte FILETIME object
    # Output: Unix-style date/time
    # Thanks goes to Andreas Schuster for the below code, which he
    # included in his ptfinder.pl
    #---------------------------------------------------------
    sub getTime {
        my $lo = shift;
        my $hi = shift;
        my $t;

        if ($lo == 0 && $hi == 0) {
            $t = 0;
        } else {
            $lo -= 0xd53e8000;
            $hi -= 0x019db1de;
            $t = int($hi*429.4967296 + $lo/1e7);
        };
        $t = 0 if ($t < 0);
        return $t;
    }
  • Re: Reading binary contents from a file

     10-12-2006, 5:16 PM

    • Joined on 04-20-2006
    • Northern VA
    • Posts 35
    • Top 10 Contributor
    As a follow-up to this, I think there may be a problem with the documentation, or the PSReadRaw() function.  The docs say that after PSReadRaw() completes, the file pointer updated by the number of bytes read.  To test this, I altered the getRpDescr() function (pasted below), and ran the ProScript all over again.  The script read the same bytes, over and over.

    Thanks,

    Harlan

    ---------------------------------------------------------------------------------------------
    #---------------------------------------------------------
    # getRpDescr()
    # Read the rp.log file to get the description and creation
    # date
    #---------------------------------------------------------
    sub getRpDescr {
        my $path = shift;
        my $buffer;
        my $tag = 1;
        my $offset = 0x10;
        my $str;
        if (my $oFile = PSOpen($path)) {
            PSSeek($oFile,$offset,0,PS_FILE_BEGIN);
            foreach (0..9) {
                PSDisplayText("\tOffset = $offset");
                $buffer = PSReadRaw($oFile,2);
                PSDisplayText("\t$buffer");
            }
            PSClose($oFile);
        }
        else {
            PSDisplayText("File could not be opened.");
        }   
    }
  • Re: Reading binary contents from a file

     10-13-2006, 1:46 PM

    Harlan,

    As usual thanks for the post. You continue to write some great ProScipts. The team is looking into your issues and we should have an answer by Monday along with the NIST Hacking Case image you reported.

     

  • Re: Reading binary contents from a file

     10-14-2006, 5:04 AM

    • Joined on 04-20-2006
    • Northern VA
    • Posts 35
    • Top 10 Contributor
    Chris,

    Thanks, I'll check back then...

    Harlan
  • Re: Reading binary contents from a file

     10-16-2006, 2:44 PM

    Harlan,

    We think we found a fix to your issue. We've still got a little in house testing to do, and should have soemthing for you to test by tomorrow.

     

View as RSS news feed in XML