def get_content(self, partition): """Extract the content of the file. This method works by extracting the $DATA attribute.""" if self.is_ghost: logging.error(u'Cannot restore ghost file {}'.format(self)) return None image = DiskScanner.get_image(partition.scanner) dump = sectors(image, File.get_offset(self), FILE_size) parsed = parse_file_record(dump) if not parsed['valid'] or 'attributes' not in parsed: logging.error(u'Invalid MFT entry for {}'.format(self)) return None attrs = parsed['attributes'] if ('$ATTRIBUTE_LIST' in attrs and partition.sec_per_clus is not None): _integrate_attribute_list(parsed, partition, image) if '$DATA' not in attrs: attrs['$DATA'] = [] datas = [d for d in attrs['$DATA'] if d['name'] == self.ads] if not len(datas): if not self.is_directory: logging.error(u'Cannot restore $DATA attribute(s) ' 'for {}'.format(self)) return None # TODO implemented compressed attributes for d in datas: if d['flags'] & 0x01: logging.error(u'Cannot restore compressed $DATA attribute(s) ' 'for {}'.format(self)) return None elif d['flags'] & 0x4000: logging.warning(u'Found encrypted $DATA attribute(s) ' 'for {}'.format(self)) # Handle resident file content if len(datas) == 1 and not datas[0]['non_resident']: single = datas[0] start = single['dump_offset'] + single['content_off'] end = start + single['content_size'] content = dump[start:end] return str(content) else: if partition.sec_per_clus is None: logging.error(u'Cannot restore non-resident $DATA ' 'attribute(s) for {}'.format(self)) return None non_resident = sorted( (d for d in attrs['$DATA'] if d['non_resident']), key=lambda x: x['start_VCN'] ) if len(non_resident) != len(datas): logging.warning( u'Found leftover resident $DATA attributes for ' '{}'.format(self) ) return self.content_iterator(partition, image, non_resident)
def __init__(self, parsed, offset, is_ghost=False, ads=''): index = parsed['record_n'] ads_suffix = ':' + ads if ads != '' else ads if ads != '': index = unicode(index) + ads_suffix attrs = parsed['attributes'] filenames = attrs['$FILE_NAME'] datas = attrs.get('$DATA', []) size = None for attr in datas: if attr['name'] == ads: if 'real_size' in attr: size = attr['real_size'] elif not attr['non_resident']: size = attr['content_size'] break filtered = [ f for f in filenames if f.has_key('content') and f['content'] is not None and f['content']['name_length'] > 0 and f['content']['name'] is not None ] name = best_name([ (f['content']['namespace'], f['content']['name'] + ads_suffix) for f in filtered ]) hasname = name is not None if not hasname: name = 'File_%s' % index is_dir = (parsed['flags'] & 0x02) > 0 and not len(ads) is_del = (parsed['flags'] & 0x01) == 0 File.__init__(self, index, name, size, is_dir, is_del, is_ghost) # Additional attributes if hasname: first = filtered[0]['content'] parent_id = first['parent_entry'] File.set_parent(self, parent_id) File.set_offset(self, offset) File.set_mac( self, first['modification_time'], first['access_time'], first['creation_time'] ) self.ads = ads
def __init__(self, parsed, offset, is_ghost=False, ads=''): index = parsed['record_n'] ads_suffix = ':' + ads if ads != '' else ads if ads != '': index = unicode(index) + ads_suffix attrs = parsed['attributes'] filenames = attrs['$FILE_NAME'] datas = attrs['$DATA'] if '$DATA' in attrs else [] size = None for attr in datas: if attr['name'] == ads: if 'real_size' in attr: size = attr['real_size'] elif not attr['non_resident']: size = attr['content_size'] break filtered = [ f for f in filenames if f.has_key('content') and f['content'] is not None and f['content']['name_length'] > 0 and f['content']['name'] is not None ] name = best_name([ (f['content']['namespace'], f['content']['name'] + ads_suffix) for f in filtered ]) hasname = name is not None if not hasname: name = 'File_%s' % index is_dir = (parsed['flags'] & 0x02) > 0 and not len(ads) is_del = (parsed['flags'] & 0x01) == 0 File.__init__(self, index, name, size, is_dir, is_del, is_ghost) # Additional attributes if hasname: first = filtered[0]['content'] parent_id = first['parent_entry'] File.set_parent(self, parent_id) File.set_offset(self, offset) File.set_mac( self, first['modification_time'], first['access_time'], first['creation_time'] ) self.ads = ads