def check_rsrc(self, pe): ret = {} if hasattr(pe, 'DIRECTORY_ENTRY_RESOURCE'): i = 0 for resource_type in pe.DIRECTORY_ENTRY_RESOURCE.entries: if resource_type.name is not None: name = "%s" % resource_type.name else: name = "%s" % pefile.RESOURCE_TYPE.get( resource_type.struct.Id) if name is None: name = "%d" % 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) try: if sys.version_info <= (2, 6): filetype = self.ms.buffer(data).decode( 'utf-8') else: filetype = magic.from_buffer( data).decode('utf-8') except: filetype = '' ret[i] = ( name, resource_lang.data.struct.OffsetToData, resource_lang.data.struct.Size, filetype) i += 1 return ret
def check_rsrc(self, pe): ret = {} if hasattr(pe, 'DIRECTORY_ENTRY_RESOURCE'): i = 0 for resource_type in pe.DIRECTORY_ENTRY_RESOURCE.entries: if resource_type.name is not None: name = "%s" % resource_type.name else: name = "%s" % pefile.RESOURCE_TYPE.get(resource_type.struct.Id) if name is None: name = "%d" % 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) try: if sys.version_info <= (2, 6): filetype = self.ms.buffer(data).decode('utf-8') else: filetype = magic.from_buffer(data).decode('utf-8') except: filetype = '' ret[i] = (name, resource_lang.data.struct.OffsetToData, resource_lang.data.struct.Size, filetype) i += 1 return ret
def collect(self): data = self.data out = [] if data is None or len(data) == 0: out.append("Cannot read %s (maybe empty?)" % file) out.append("") return out try: pe = pefile.PE(data=data, fast_load=True) pe.parse_data_directories(directories=[ pefile.DIRECTORY_ENTRY['IMAGE_DIRECTORY_ENTRY_IMPORT'], pefile.DIRECTORY_ENTRY['IMAGE_DIRECTORY_ENTRY_EXPORT'], pefile.DIRECTORY_ENTRY['IMAGE_DIRECTORY_ENTRY_TLS'], pefile.DIRECTORY_ENTRY['IMAGE_DIRECTORY_ENTRY_RESOURCE'] ]) except: out.append("Cannot parse %s (maybe not PE?)" % file) out.append("") return out # Meta Data out.append(self.header("Meta-data")) out.append("Size: %d bytes" % len(data)) out.append("Date: %s" % self.get_timestamp(pe)) exportdll = self.check_exportdll(pe) if len(exportdll): out.append("ExportDll: %s" % exportdll) (ep, name) = self.check_ep_section(pe) s = "EP: %s (%s)" % (hex(ep + pe.OPTIONAL_HEADER.ImageBase), name) if name not in good_ep_sections: s += " [SUSPICIOUS]" out.append(s) try: if sys.version_info <= (2, 6): out.append("Type: %s" % self.ms.buffer(data).decode('utf-8')) else: out.append("Type: %s" % magic.from_buffer(data).decode('utf-8')) except: out.append("Type: data") out.append("MD5: %s" % hashlib.md5(data).hexdigest()) out.append("SHA1: %s" % hashlib.sha1(data).hexdigest()) out.append("SHA256: %s" % hashlib.sha256(data).hexdigest()) packers = self.check_packers(pe) if len(packers): out.append("Packers: %s" % ','.join(packers)) # Version Info verinfo = self.check_verinfo(pe) if len(verinfo): out.append(self.header("Version info")) out.append(verinfo) # Sections out.append(self.header("Sections")) out.append("%-10s %-12s %-12s %-12s %-12s" % ("Name", "VirtAddr", "VirtSize", "RawSize", "Entropy")) out.append("-" * 60) for sec in pe.sections: s = "%-10s %-12s %-12s %-12s %-12f" % ( sec.Name.decode('utf-8').replace('\x00', ''), hex(sec.VirtualAddress), hex(sec.Misc_VirtualSize), hex(sec.SizeOfRawData), sec.get_entropy()) if sec.SizeOfRawData == 0 or \ (sec.get_entropy() > 0 and sec.get_entropy() < 1) or \ sec.get_entropy() > 7: s += "[SUSPICIOUS]" out.append(s) # Resources resources = self.check_rsrc(pe) if len(resources): out.append(self.header("Resource entries")) out.append("%-18s %-12s %-12s Type" % ("Name", "RVA", "Size")) out.append("-" * 60) for rsrc in resources.keys(): (name, rva, size, type) = resources[rsrc] out.append("%-18s %-12s %-12s %s" % (name, hex(rva), hex(size), type)) # TLS Callbacks callbacks = self.check_tls(pe) if len(callbacks): out.append(self.header("TLS callbacks")) for cb in callbacks: out.append(" 0x%x" % cb) # Exports exports = self.check_exports(pe) if len(exports): out.append(self.header("Exported Functions")) out.append("%-10s %-30s%s" % ("Ordinal", "Name", "Forwarder")) out.append("-" * 60) for exp in exports: out.append(exp) # Libraries libs = self.check_libs(pe) if len(libs): out.append(self.header("Import Libs")) for lib in libs: out.append(lib) # Imports imports = self.check_imports(pe) if len(imports): out.append(self.header("Imported Functions")) for imp in imports: out.append(imp) # Strings # results = [] # patterns = ["[ -~]{2,}[\\\/][ -~]{2,}", "[ -~]{2,}\.[ -~]{2,}","\\\[ -~]{5,}","^[ -~]{5,}[\\\/]$","[ -~]+\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}[ -~]+"] # for pattern in patterns: # regex = re.compile(pattern) # results += regex.findall(data) # if len(results): # out.append(self.header("Interesting Strings")) # out += list(set(results)) out.append("") return out
def collect(self): data = self.data out = [] if data is None or len(data) == 0: out.append("Cannot read %s (maybe empty?)" % file) out.append("") return out try: pe = pefile.PE(data=data, fast_load=True) pe.parse_data_directories(directories=[ pefile.DIRECTORY_ENTRY['IMAGE_DIRECTORY_ENTRY_IMPORT'], pefile.DIRECTORY_ENTRY['IMAGE_DIRECTORY_ENTRY_EXPORT'], pefile.DIRECTORY_ENTRY['IMAGE_DIRECTORY_ENTRY_TLS'], pefile.DIRECTORY_ENTRY['IMAGE_DIRECTORY_ENTRY_RESOURCE']]) except: out.append("Cannot parse %s (maybe not PE?)" % file) out.append("") return out # Meta Data out.append(self.header("Meta-data")) out.append("Size: %d bytes" % len(data)) out.append("Date: %s" % self.get_timestamp(pe)) exportdll = self.check_exportdll(pe) if len(exportdll): out.append("ExportDll: %s" % exportdll) (ep, name) = self.check_ep_section(pe) s = "EP: %s (%s)" % (hex(ep+pe.OPTIONAL_HEADER.ImageBase), name) if name not in good_ep_sections: s += " [SUSPICIOUS]" out.append(s) try: if sys.version_info <= (2, 6): out.append("Type: %s" % self.ms.buffer(data).decode('utf-8')) else: out.append("Type: %s" % magic.from_buffer(data).decode('utf-8')) except: out.append("Type: data") out.append("MD5: %s" % hashlib.md5(data).hexdigest()) out.append("SHA1: %s" % hashlib.sha1(data).hexdigest()) out.append("SHA256: %s" % hashlib.sha256(data).hexdigest()) packers = self.check_packers(pe) if len(packers): out.append("Packers: %s" % ','.join(packers)) # Version Info verinfo = self.check_verinfo(pe) if len(verinfo): out.append(self.header("Version info")) out.append(verinfo) # Sections out.append(self.header("Sections")) out.append("%-10s %-12s %-12s %-12s %-12s" % ("Name", "VirtAddr", "VirtSize", "RawSize", "Entropy")) out.append("-" * 60) for sec in pe.sections: s = "%-10s %-12s %-12s %-12s %-12f" % ( sec.Name.decode('utf-8').replace('\x00', ''), hex(sec.VirtualAddress), hex(sec.Misc_VirtualSize), hex(sec.SizeOfRawData), sec.get_entropy()) if sec.SizeOfRawData == 0 or \ (sec.get_entropy() > 0 and sec.get_entropy() < 1) or \ sec.get_entropy() > 7: s += "[SUSPICIOUS]" out.append(s) # Resources resources = self.check_rsrc(pe) if len(resources): out.append(self.header("Resource entries")) out.append("%-18s %-12s %-12s Type" % ("Name", "RVA", "Size")) out.append("-" * 60) for rsrc in resources.keys(): (name, rva, size, type) = resources[rsrc] out.append("%-18s %-12s %-12s %s" % (name, hex(rva), hex(size), type)) # TLS Callbacks callbacks = self.check_tls(pe) if len(callbacks): out.append(self.header("TLS callbacks")) for cb in callbacks: out.append(" 0x%x" % cb) # Exports exports = self.check_exports(pe) if len(exports): out.append(self.header("Exported Functions")) out.append("%-10s %-30s%s" % ("Ordinal", "Name", "Forwarder")) out.append("-" * 60) for exp in exports: out.append(exp) # Libraries libs = self.check_libs(pe) if len(libs): out.append(self.header("Import Libs")) for lib in libs: out.append(lib) # Imports imports = self.check_imports(pe) if len(imports): out.append(self.header("Imported Functions")) for imp in imports: out.append(imp) # Strings # results = [] # patterns = ["[ -~]{2,}[\\\/][ -~]{2,}", "[ -~]{2,}\.[ -~]{2,}","\\\[ -~]{5,}","^[ -~]{5,}[\\\/]$","[ -~]+\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}[ -~]+"] # for pattern in patterns: # regex = re.compile(pattern) # results += regex.findall(data) # if len(results): # out.append(self.header("Interesting Strings")) # out += list(set(results)) out.append("") return out