Skip to content

Instantly share code, notes, and snippets.

@forensicmatt
Created October 3, 2018 06:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save forensicmatt/ecb9df32e888c02212d22a592c3c55d4 to your computer and use it in GitHub Desktop.
Save forensicmatt/ecb9df32e888c02212d22a592c3c55d4 to your computer and use it in GitHub Desktop.
Parse Windows FileTime with nanoseond resolution.
import struct
import datetime
import binascii
FILETIME = b"\x19\x81\xE5\xB2\x1F\xDB\xD3\x01"
class FileTime(datetime.datetime):
"""datetime.datetime object is immutable, so we will create a class to inherit
datetime.datetime so we can set a custom nanosecond.
"""
def __new__(cls, *args, **kwargs):
return datetime.datetime.__new__(cls, *args, **kwargs)
@staticmethod
def from_dt_object(dt_object, nanoseconds=0):
ft = FileTime(
dt_object.year,
dt_object.month,
dt_object.day,
dt_object.hour,
dt_object.minute,
dt_object.second,
dt_object.microsecond
)
ft.nanoseconds = nanoseconds
return ft
def __str__(self):
return "{0.year}-{0.month:02}-{0.day:02} {0.hour:02}:{0.minute:02}:{0.second:02}.{0.nanoseconds}".format(self)
def get_filetime(uint64):
le_timestamp = uint64
# get datetime object with microsecond resolution
dt_object = datetime.datetime(1601, 1, 1) + datetime.timedelta(
microseconds=le_timestamp // 10
)
# filetime is 100 nanosecond resolution
nanoseconds = str(le_timestamp % 10000000).zfill(7) + '00'
filetime = FileTime.from_dt_object(
dt_object, nanoseconds=nanoseconds
)
return filetime
def main():
uint_64 = struct.unpack("<Q", FILETIME)[0]
print("as raw hex: {}".format(binascii.b2a_hex(FILETIME)))
print("as uint64: {}".format(uint_64))
filetime = get_filetime(uint_64)
print("as string with isoformat: {}".format(filetime.isoformat(" ")))
print("as string with nanoseconds: {}".format(filetime))
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment