def get_vmcs_address_space(cls, vmcs, host=True, base_as=None): """Returns the address_space of the host or guest process of a VMCS.""" address_space = None base_as = base_as or vmcs.obj_vm if host: cr4 = vmcs.HOST_CR4 cr3 = vmcs.HOST_CR3 controls = vmcs.EXIT_CONTROLS else: cr4 = vmcs.GUEST_CR4 cr3 = vmcs.GUEST_CR3 controls = vmcs.ENTRY_CONTROLS if not cr4 & (1 << 5): # PAE bit # No PAE address_space = intel.IA32PagedMemory(dtb=cr3, base=base_as) elif not controls & (1 << 9): # long mode bit # PAE and no long mode = 32bit PAE address_space = intel.IA32PagedMemoryPae(dtb=cr3, base=base_as) elif controls & (1 << 9): # long mode bit # Long mode AND PAE = IA-32e address_space = amd64.AMD64PagedMemory(dtb=cr3, base=base_as) return address_space
def DetectWindowsDTB(self, filename_offset, address_space): """Checks the possible filename hit for a valid DTB address.""" for dtb_rel_offset, arch in self.eprocess_index.filename_to_dtb: # We only apply indexes to 64 bit images. if arch == "AMD64": possible_dtb = self.eprocess_index.Object( "unsigned long", offset=filename_offset - dtb_rel_offset, vm=address_space).v() # Discard impossible DTB values immediately. On 64 bit # architectures, the DTB must be page aligned. if not possible_dtb or possible_dtb & 0xFFF: continue test_as = amd64.AMD64PagedMemory( session=self.session, base=address_space, dtb=possible_dtb) if self.VerifyAMD64DTB(test_as): yield test_as elif arch == "I386": possible_dtb = self.eprocess_index.Object( "unsigned long", offset=filename_offset - dtb_rel_offset, vm=address_space).v() # Discard impossible DTB values immediately. On 32 bit # architectures, the DTB must be aligned to 0x20 (with PAE). if not possible_dtb or possible_dtb & 0x1F: continue # Only support PAE - we dont really see non PAE images any more. test_as = intel.IA32PagedMemoryPae( session=self.session, base=address_space, dtb=possible_dtb) if self.VerifyI386DTB(test_as): yield test_as
def DetectWindowsDTB(self, filename_offset, address_space): """Checks the possible filename hit for a valid DTB address.""" for dtb_rel_offset, arch in self.eprocess_index.filename_to_dtb: if arch == "AMD64": possible_dtb = self.eprocess_index.Object( "unsigned long", offset=filename_offset - dtb_rel_offset, vm=address_space).v() # Discard impossible DTB values immediately. On 64 bit # architectures, the DTB must be page aligned. if not possible_dtb or possible_dtb & 0xFFF: continue test_as = amd64.AMD64PagedMemory( session=self.session, base=address_space, dtb=possible_dtb) if self.VerifyDTB(test_as): yield test_as
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, 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 (offset == 0 and 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")) pe_helper = pe_vtypes.PE( session=self.session, address_space=test_as, image_base=self.session.GetParameter("kernel_base")) return self._test_rsds(pe_helper.RSDS) # Try Windows by GUID: rsds = self.pe_profile.CV_RSDS_HEADER(offset=offset, vm=address_space) return self._test_rsds(rsds)