libyal / libfsntfs

Library and tools to access the Windows New Technology File System (NTFS)
GNU Lesser General Public License v3.0
186 stars 51 forks source link

How to analyze "file_entry.get_name()" and "get_name_attribute_index()" from MFT metadata? #20

Closed ta-b0 closed 3 years ago

ta-b0 commented 4 years ago

I want to analyze "file_entry.get_name()" and "get_name_attribute_index()" from MFT metadata but ALL entry are return it 'None'. Sample code (program.py) is here:

#! python3
import sys
import pyfsntfs # Using libfsntfs-experimental-20200921
class mft_record():
    def __init__(self,mft_file,index):
        self.mft_file = mft_file
        self.index = index 
        self.fsntfs = pyfsntfs.mft_metadata_file()
        self.fsntfs.open(mft_file)
        self.file_entry = self.fsntfs.get_file_entry(self.index) 
        # self.attribute = self.file_entry.get_attribute()

    def file(self):
        file = {
            'name' : self.file_entry.get_name(), 
            'name_attribute_index' : self.file_entry.get_name_attribute_index(),
            'file_reference' : self.file_entry.get_file_reference(),
            'file_entry_No' : self.fsntfs.get_number_of_file_entries(),
            'file_reference' : hex(self.file_entry.get_file_attribute_flags()),
            'file_attribute_flags' : hex(self.file_entry.get_file_attribute_flags()),
            'journal_sequence_number' : self.file_entry.get_journal_sequence_number(),
            'number_of_attributes' : self.file_entry.get_number_of_attributes(),
            'mtime' : self.file_entry.get_modification_time(),
            'atime' : self.file_entry.get_access_time(),
            'ctime' : self.file_entry.get_creation_time(),
        }
        return file

def analyze(mft_file):
    for i in range(0,5):
        mft = mft_record(mft_file,i)
        print(mft.file())

def main():
    args = sys.argv
    analyze(args[1])

if __name__ == '__main__':
    main()

And run it in Windows10: python program.py <MFT metadata path>

MFT metadata is extracted by FTK imager.

Top of this MFT metadata is below:

46 49 4C 45 30 00 03 00 B0 3D D3 0B 00 00 00 00
00 00 00 00 00 00 00 00 07 00 00 00 00 00 00 00
45 00 00 00 00 00 00 00 10 00 00 00 60 00 00 00
00 00 18 00 00 00 00 00 48 00 00 00 18 00 00 00
19 8F CB 9F DB 79 D6 01 19 8F CB 9F DB 79 D6 01 (Following is omitted)

Result of this program is below:

{'name': None, 'name_attribute_index': None, 'file_reference': '0x6', 'file_entry_No': 98304, 'file_attribute_flags': '0x6', 'journal_sequence_number': 198393264, 'number_of_attributes': 4, 'mtime': datetime.datetime(2020, 8, 24, 5, 58, 43, 972482), 'atime': datetime.datetime(2020, 8, 24, 5, 58, 43, 972482), 'ctime': datetime.datetime(2020, 8, 24, 5, 58, 43, 972482)}
{'name': None, 'name_attribute_index': None, 'file_reference': '0x6', 'file_entry_No': 98304, 'file_attribute_flags': '0x6', 'journal_sequence_number': 16783067, 'number_of_attributes': 3, 'mtime': datetime.datetime(2020, 8, 24, 5, 58, 43, 972482), 'atime': datetime.datetime(2020, 8, 24, 5, 58, 43, 972482), 'ctime': datetime.datetime(2020, 8, 24, 5, 58, 43, 972482)}
{'name': None, 'name_attribute_index': None, 'file_reference': '0x6', 'file_entry_No': 98304, 'file_attribute_flags': '0x6', 'journal_sequence_number': 16783137, 'number_of_attributes': 3, 'mtime': datetime.datetime(2020, 8, 24, 5, 58, 43, 972482), 'atime': datetime.datetime(2020, 8, 24, 5, 58, 43, 972482), 'ctime': datetime.datetime(2020, 8, 24, 5, 58, 43, 972482)}
{'name': None, 'name_attribute_index': None, 'file_reference': '0x6', 'file_entry_No': 98304, 'file_attribute_flags': '0x6', 'journal_sequence_number': 143282914, 'number_of_attributes': 6, 'mtime': datetime.datetime(2020, 8, 24, 5, 58, 43, 972482), 'atime': datetime.datetime(2020, 8, 24, 5, 58, 43, 972482), 'ctime': datetime.datetime(2020, 8, 24, 5, 58, 43, 972482)}
{'name': None, 'name_attribute_index': None, 'file_reference': '0x6', 'file_entry_No': 98304, 'file_attribute_flags': '0x6', 'journal_sequence_number': 16783277, 'number_of_attributes': 3, 'mtime': datetime.datetime(2020, 8, 24, 5, 58, 43, 972482), 'atime': datetime.datetime(2020, 8, 24, 5, 58, 43, 972482), 'ctime': datetime.datetime(2020, 8, 24, 5, 58, 43, 972482)}

I confirmed that it can run some functions but "get_name()" and "get_name_attribute_index()" can't run.

I want to help how to analyze "get_name()" and "get_name_attribute_index()" from MFT metadata file?

ta-b0 commented 4 years ago

I'm sorry to poor English and edit sentence many time.

joachimmetz commented 3 years ago

I'm sorry to poor English and edit sentence many time.

Thx for that context, it is indeed challenging to determine what you are asking me

'ctime' : self.file_entry.get_creation_time(),

'ctime' is change time or for NTFS MFT entry modification time, 'crtime' is creation time

The following code is very inefficient:

class mft_record():
    def __init__(self,mft_file,index):
        self.mft_file = mft_file
        self.index = index 
        self.fsntfs = pyfsntfs.mft_metadata_file()
        self.fsntfs.open(mft_file)
        self.file_entry = self.fsntfs.get_file_entry(self.index) 
        # self.attribute = self.file_entry.get_attribute()

...

def analyze(mft_file):
    for i in range(0,5):
        mft = mft_record(mft_file,i)
        print(mft.file())

It parses the full $MFT for every MFT entry (or record). Instead open the $MFT metadata file at the start of analyze (before your for-loop)

I want to help how to analyze "get_name()" and "get_name_attribute_index()" from MFT metadata file?

When parsing stand-alone $MFT file_entry.get_name() will return None since there is corresponding $I30 directory entry. Since a MFT entry can represent multiple directory entries you'll have to iterate over the attributes.

for attribute in file_entry.attributes: 
  if attribute.attribute_type == 48: 
    print(attribute.name) 
ta-b0 commented 3 years ago

Thank you for your reply. I solve its problem and it run faster than before!