Home > Computer forensics > Using Python to parse and present Windows 64 bit timestamps

Using Python to parse and present Windows 64 bit timestamps

I’m working on learning Python since Perl, even after 20 years, still doesn’t stick in my head. The phrase “like a duck to water” doesn’t quite apply to my experience with Python, but I’m certainly swimming along nicely.

Since I learn languages and tools more effectively when I have a real problem to work on, I set out to parse the NTFS MFT record using Python. This was going swimmingly until I hit the file MAC times. According to Microsoft:

“A file time is a 64-bit value that represents the number of 100-nanosecond intervals that have elapsed since 12:00 A.M. January 1, 1601 Coordinated Universal Time (UTC).”

So, two problems: 1) It is a 64 bit value and python only has 32 bit longs and b) it doesn’t use the Unix definition of epoch.

After a lot of false starts, I learned the power of dictionaries and classes and came up with the following:

from datetime import date, datetime
class WindowsTime:
    def __init__(self, low, high):
        self.low = long(low)
        self.high = long(high)
        self.unixtime = self.GetUnixTime()
        self.utc = datetime.utcfromtimestamp(self.unixtime)
        self.utcstr = self.utc.strftime("%Y/%m/%d %H:%M:%S.%f")
# Windows NT time is specified as the number of 100 nanosecond intervals since January 1, 1601. 
# UNIX time is specified as the number of seconds since January 1, 1970. 
# There are 134,774 days (or 11,644,473,600 seconds) between these dates.
    def GetUnixTime(self):
        t=float(self.high)*2**32 + self.low
        return (t*1e-7 - 11644473600)

I have a module that defines a dictionary and parses chunks of data read from the MFT:

# Decodes the Standard Information attribute in a MFT record
def decodeSIrecord(s):

 d = {}
 d['crtime'] = WindowsTime(struct.unpack("<L",s[:4])[0],
                           struct.unpack("<L",s[4:8])[0])
 ...

Then just do:

SIobject = decodeSIrecord(data)

And you can print the times out directly from the dictionary:

print "CRTime: %s" % (SIobject['crtime'].utcstr)

This isn’t rocket science, and there’s probabaly a better way to do it, but if you’re trying to use Python to work with Windows filesystems and metadata, this could come in handy.

Advertisements
  1. Syd P
    February 19, 2010 at 12:37 am

    Try using the unsigned long long ‘Q’ for 64-bit values.

    i.e. ft = struct.unpack(‘<Q',fh.read(8))[0]

    Cheers,
    Syd

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: