def scan_for_process(self): """Scan the image for the idle process.""" maxlen = self.session.GetParameter("autodetect_scan_length", 10 * 1024 * 1024 * 1024) self.image_name_offset = self.profile.get_obj_offset( "_EPROCESS", "ImageFileName") for offset, hit in scan.MultiStringScanner( session=self.session, needles=self.plugin_args.process_name, profile=self.profile, address_space=self.physical_address_space).scan(0, maxlen=maxlen): eprocess = self.profile.Object( "_EPROCESS", offset=offset - self.image_name_offset, vm=self.session.physical_address_space) self.session.report_progress( u"Found possible _EPROCESS @ 0x%X (In process %s) (DTB: 0x%X)", eprocess.obj_offset, utils.SmartUnicode(hit), eprocess.Pcb.DirectoryTableBase.v()) yield eprocess
def render(self, renderer): scanner = scan.MultiStringScanner( needles=self.keyword, address_space=self.address_space, session=self.session) for hit, _ in scanner.scan(offset=self.offset, maxlen=self.limit): hexdumper = self.session.plugins.dump( offset=hit - 16, length=self.context + 16, address_space=self.address_space) hexdumper.render(renderer)
def find_in_module(self, module_name, pattern): if module_name.lower() not in self.modules: raise Exception('Module is not in lsass emmory space! %s' % module_name) module = self.modules[module_name.lower()] res = [] scanner = scan.MultiStringScanner( needles=[pattern], address_space=self.lsass_task.get_process_address_space()) for hit, _ in scanner.scan(offset=int(module.start_addr), maxlen=int(module.size)): res.append(int(hit)) return res
def render(self, renderer): scanner = scan.MultiStringScanner( needles=[utils.SmartStr(x) for x in self.plugin_args.keyword], address_space=self.plugin_args.address_space, session=self.session) for hit, _ in scanner.scan(offset=self.plugin_args.offset, maxlen=self.plugin_args.limit): hexdumper = self.session.plugins.dump( offset=hit - 16, length=self.plugin_args.context + 16, address_space=self.plugin_args.address_space) hexdumper.render(renderer)
def DetectFromHit(self, hit, filename_offset, address_space): # Make use of already known dtb and kernel_base parameters - this speeds # up live analysis significantly since we do not need to search for # anything then. if filename_offset == 0: if (self.session.HasParameter("dtb") and self.session.HasParameter("kernel_base")): test_as = amd64.AMD64PagedMemory( session=self.session, base=address_space, dtb=self.session.GetParameter("dtb")) if self.VerifyAMD64DTB(test_as): return self._match_profile_for_kernel_base( self.session.GetParameter("kernel_base"), test_as) return # Get potential kernel address spaces. for test_as in self.DetectWindowsDTB(filename_offset, address_space): # Try to find the kernel base. This can be improved in future by # taking more than a single search point. scanner = scan.MultiStringScanner( address_space=test_as, needles=[ b"This program cannot be run in DOS mode", ]) if self.session.HasParameter("kernel_base"): kernel_base = self.session.GetParameter("kernel_base") return self._match_profile_for_kernel_base( kernel_base, test_as) for offset, _ in scanner.scan( offset=0xF80000000000, maxlen=0x10000000000): kernel_base = offset & 0xFFFFFFFFFFFFFF000 profile_obj = self._match_profile_for_kernel_base( kernel_base, test_as) if profile_obj: self.session.logging.debug( "Verifying profile %s by scanning processes for a valid DTB", profile_obj) if self.VerifyProfile(profile_obj): return profile_obj
def DetectFromHit(self, hit, filename_offset, address_space): # Get potential kernel address spaces. for test_as in self.DetectWindowsDTB(filename_offset, address_space): # Try to find the kernel base. This can be improved in future by # taking more than a single search point. scanner = scan.MultiStringScanner( address_space=test_as, needles=[ "This program cannot be run in DOS mode", ]) kernel_base = self.session.GetParameter("kernel_base") if kernel_base: return self._match_profile_for_kernel_base( kernel_base, test_as) for offset, _ in scanner.scan( offset=0xF80000000000, maxlen=0x10000000000): kernel_base = offset & 0xFFFFFFFFFFFFFF000 profile_obj = self._match_profile_for_kernel_base( kernel_base, test_as) if profile_obj: return profile_obj
def _ScanProfiles(self): address_space = self.session.physical_address_space best_profile = None best_match = 0 methods = [] needles = [] needle_lookup = {} method_names = self.session.GetParameter("autodetect") self.session.logging.debug( "Will detect profile using these Detectors: %s" % ",".join( method_names)) if not method_names: raise RuntimeError("No autodetection methods specified. " "Use the --autodetect parameter.") for method_name in method_names: for method in DetectionMethod.classes_by_name[method_name]: methods.append(method(session=self.session)) methods.sort(key=lambda x: x.order) for method in methods: for keyword in method.Keywords(): needles.append(keyword) needle_lookup.setdefault(keyword, []).append(method) for offset in method.Offsets(): self.session.logging.debug("Trying method %s, offset %d", method.name, offset) profile = method.DetectFromHit(None, offset, address_space) if profile: self.session.logging.info( "Detection method %s yielded profile %s", method.name, profile) return profile # 10 GB by default. autodetect_scan_length = self.session.GetParameter( "autodetect_scan_length", 10*1024*1024*1024) # Build and configure the scanner. scanner = scan.MultiStringScanner( profile=obj.NoneObject(), address_space=address_space, needles=needles, session=self.session) scanner.progress_message = "Autodetecting profile: %(offset)#08x" for offset, hit in scanner.scan(maxlen=autodetect_scan_length): self.session.render_progress( "guess_profile: autodetection hit @ %x - %s", offset, hit) for method in needle_lookup[hit]: profile = method.DetectFromHit(hit, offset, address_space) if profile: self.session.logging.debug( "Detection method %s worked at offset %#x", method.name, offset) return profile if best_match == 1.0: # If we have an exact match we can stop scanning. break threshold = self.session.GetParameter("autodetect_threshold") if best_match == 0: self.session.logging.error( "No profiles match this image. Try specifying manually.") return obj.NoneObject("No profile detected") elif best_match < threshold: self.session.logging.error( "Best match for profile is %s with %.0f%%, which is too low " + "for given threshold of %.0f%%. Try lowering " + "--autodetect-threshold.", best_profile.name, best_match * 100, threshold * 100) return obj.NoneObject("No profile detected") else: self.session.logging.info( "Profile %s matched with %.0f%% confidence.", best_profile.name, best_match * 100) return best_profile