def log(self, event_type, event_data): self.output.append(dict( type=event_type, data=event_data )) if event_type == 'table': print table(event_data['header'], event_data['rows']) else: getattr(out, 'print_{0}'.format(event_type))(event_data)
def resources(self): # Use this function to retrieve resources for the given PE instance. # Returns all the identified resources with indicators and attributes. def get_resources(pe): resources = [] if hasattr(pe, 'DIRECTORY_ENTRY_RESOURCE'): count = 1 for resource_type in pe.DIRECTORY_ENTRY_RESOURCE.entries: try: resource = {} if resource_type.name is not None: name = str(resource_type.name) else: name = str(pefile.RESOURCE_TYPE.get(resource_type.struct.Id)) if name is None: name = str(resource_type.struct.Id) if hasattr(resource_type, 'directory'): for resource_id in resource_type.directory.entries: if hasattr(resource_id, 'directory'): for resource_lang in resource_id.directory.entries: data = pe.get_data(resource_lang.data.struct.OffsetToData, resource_lang.data.struct.Size) filetype = get_type(data) md5 = get_md5(data) language = pefile.LANG.get(resource_lang.data.lang, None) sublanguage = pefile.get_sublang_name_for_lang(resource_lang.data.lang, resource_lang.data.sublang) offset = ('%-8s' % hex(resource_lang.data.struct.OffsetToData)).strip() size = ('%-8s' % hex(resource_lang.data.struct.Size)).strip() resource = [count, name, offset, md5, size, filetype, language, sublanguage] # Dump resources if requested to and if the file currently being # processed is the opened session file. # This is to avoid that during a --scan all the resources being # scanned are dumped as well. if (self.args.open or self.args.dump) and pe == self.pe: if self.args.dump: folder = self.args.dump else: folder = tempfile.mkdtemp() resource_path = os.path.join(folder, '{0}_{1}_{2}'.format(__sessions__.current.file.md5, offset, name)) resource.append(resource_path) with open(resource_path, 'wb') as resource_handle: resource_handle.write(data) resources.append(resource) count += 1 except Exception as e: self.log('error', e) continue return resources if not self.__check_session(): return # Obtain resources for the currently opened file. resources = get_resources(self.pe) if not resources: self.log('warning', "No resources found") return headers = ['#', 'Name', 'Offset', 'MD5', 'Size', 'File Type', 'Language', 'Sublanguage'] if self.args.dump or self.args.open: headers.append('Dumped To') print table(headers, resources) # If instructed, open a session on the given resource. if self.args.open: for resource in resources: if resource[0] == self.args.open: __sessions__.new(resource[8]) return # If instructed to perform a scan across the repository, start looping # through all available files. elif self.args.scan: self.log('info', "Scanning the repository for matching samples...") # Retrieve list of samples stored locally and available in the # database. db = Database() samples = db.find(key='all') matches = [] for sample in samples: # Skip if it's the same file. if sample.sha256 == __sessions__.current.file.sha256: continue # Obtain path to the binary. sample_path = get_sample_path(sample.sha256) if not os.path.exists(sample_path): continue # Open PE instance. try: cur_pe = pefile.PE(sample_path) except: continue # Obtain the list of resources for the current iteration. cur_resources = get_resources(cur_pe) matched_resources = [] # Loop through entry's resources. for cur_resource in cur_resources: # Loop through opened file's resources. for resource in resources: # If there is a common resource, add it to the list. if cur_resource[3] == resource[3]: matched_resources.append(resource[3]) # If there are any common resources, add the entry to the list # of matched samples. if len(matched_resources) > 0: matches.append([sample.name, sample.md5, '\n'.join(r for r in matched_resources)]) self.log('info', "{0} relevant matches found".format(bold(len(matches)))) if len(matches) > 0: self.log('table', dict(header=['Name', 'MD5', 'Resource MD5'], rows=matches))
def resources(self): # Use this function to retrieve resources for the given PE instance. # Returns all the identified resources with indicators and attributes. def get_resources(pe): resources = [] if hasattr(pe, 'DIRECTORY_ENTRY_RESOURCE'): count = 1 for resource_type in pe.DIRECTORY_ENTRY_RESOURCE.entries: try: resource = {} if resource_type.name is not None: name = str(resource_type.name) else: name = str( pefile.RESOURCE_TYPE.get( resource_type.struct.Id)) if name is None: name = str(resource_type.struct.Id) if hasattr(resource_type, 'directory'): for resource_id in resource_type.directory.entries: if hasattr(resource_id, 'directory'): for resource_lang in resource_id.directory.entries: data = pe.get_data( resource_lang.data.struct. OffsetToData, resource_lang.data.struct.Size) filetype = get_type(data) md5 = get_md5(data) language = pefile.LANG.get( resource_lang.data.lang, None) sublanguage = pefile.get_sublang_name_for_lang( resource_lang.data.lang, resource_lang.data.sublang) offset = ('%-8s' % hex(resource_lang.data.struct .OffsetToData)).strip() size = ( '%-8s' % hex(resource_lang.data.struct.Size) ).strip() resource = [ count, name, offset, md5, size, filetype, language, sublanguage ] # Dump resources if requested to and if the file currently being # processed is the opened session file. # This is to avoid that during a --scan all the resources being # scanned are dumped as well. if (self.args.open or self.args.dump ) and pe == self.pe: if self.args.dump: folder = self.args.dump else: folder = tempfile.mkdtemp() resource_path = os.path.join( folder, '{0}_{1}_{2}'.format( __sessions__.current.file. md5, offset, name)) resource.append(resource_path) with open(resource_path, 'wb') as resource_handle: resource_handle.write(data) resources.append(resource) count += 1 except Exception as e: self.log('error', e) continue return resources if not self.__check_session(): return # Obtain resources for the currently opened file. resources = get_resources(self.pe) if not resources: self.log('warning', "No resources found") return headers = [ '#', 'Name', 'Offset', 'MD5', 'Size', 'File Type', 'Language', 'Sublanguage' ] if self.args.dump or self.args.open: headers.append('Dumped To') print table(headers, resources) # If instructed, open a session on the given resource. if self.args.open: for resource in resources: if resource[0] == self.args.open: __sessions__.new(resource[8]) return # If instructed to perform a scan across the repository, start looping # through all available files. elif self.args.scan: self.log('info', "Scanning the repository for matching samples...") # Retrieve list of samples stored locally and available in the # database. db = Database() samples = db.find(key='all') matches = [] for sample in samples: # Skip if it's the same file. if sample.sha256 == __sessions__.current.file.sha256: continue # Obtain path to the binary. sample_path = get_sample_path(sample.sha256) if not os.path.exists(sample_path): continue # Open PE instance. try: cur_pe = pefile.PE(sample_path) except: continue # Obtain the list of resources for the current iteration. cur_resources = get_resources(cur_pe) matched_resources = [] # Loop through entry's resources. for cur_resource in cur_resources: # Loop through opened file's resources. for resource in resources: # If there is a common resource, add it to the list. if cur_resource[3] == resource[3]: matched_resources.append(resource[3]) # If there are any common resources, add the entry to the list # of matched samples. if len(matched_resources) > 0: matches.append([ sample.name, sample.md5, '\n'.join(r for r in matched_resources) ]) self.log('info', "{0} relevant matches found".format(bold(len(matches)))) if len(matches) > 0: self.log( 'table', dict(header=['Name', 'MD5', 'Resource MD5'], rows=matches))