rowingdude / analyzeMFT

MIT License
423 stars 117 forks source link

Investigate update sequence numbers #9

Open dkovar opened 10 years ago

dkovar commented 10 years ago

http://msdn.microsoft.com/en-us/library/bb470124(v=vs.85).aspx

Google MFT update sequence number

ghost commented 10 years ago

Hope this helps:

Quick MFT Entry Structure from http://www.cse.scu.edu/~tschwarz/coen252_07Fall/Lectures/NTFS.html. entry_struct

The 'Offset to the update sequence' points to the array. The 'Number of entries in fixup array' tells you how many update values are replaced. The update sequence array (or fixup values) contains the replacement bytes for every 511th and 512th byte of the entry. The first two bytes of the array are the value of every 511th and 512th byte, every two bytes after that are the replacement values. This is used by Microsoft for error checking.

The following is an example where the entry (36 [offset 0x9000]) has a very long file name and where the second filename attribute exceeds the first 511 and 512th byte of the entry. Note that the name of the file is testfile_with_long_name_to_get_name_along_the_512th_byte_of_the_mft_entry_to_test_the_uptdate_sequence_array_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test.txt and that the update value replaces the 't' in to of the ‘…mft_entry_totest...’ part of the name.

entry_example

The following is how AnalyseMFT outputs the name: testfile_with_long_name_to_get_name_along_the_512th_byte_of_the_mft_entry_0x02o_test_the_uptdate_sequence_array_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test.txt

Where the 0x02 is used to represent the unprintable update sequence value. This should be an easy fix. While I'm not to great at Python. It looks like you can update this at the following location in your code where you parse the mft record in mft.py:

def parse_record(raw_record, options):

    record = {}
    record['filename'] = ''
    record['notes'] = ''

    decodeMFTHeader(record, raw_record);

    record_number = record['recordnum']

    if options.debug:
        print '-->Record number: %d\n\tMagic: %s Attribute offset: %d Flags: %s Size:%d' % (record_number, record['magic'],
            record['attr_off'], hex(int(record['flags'])), record['size'])

You could create another function here that would replace every 511th and 512th byte of the raw_record with the update sequence replacement values.