def parse_XROM( self, xrom_base, xrom_dump=False ): xrom_sig = self.cs.mem.read_physical_mem_word( xrom_base ) if xrom_sig != XROM_SIGNATURE: return None xrom_hdr_buf = self.cs.mem.read_physical_mem( xrom_base, PCI_XROM_HEADER_SIZE ) xrom_hdr = PCI_XROM_HEADER( *struct.unpack_from( PCI_XROM_HEADER_FMT, xrom_hdr_buf ) ) if xrom_dump: xrom_fname = 'xrom_%x-%x-%x_%x%x.bin' % (bus, dev, fun, vid, did) xrom_buf = self.cs.mem.read_physical_mem( xrom_base, xrom_size ) # use xrom_hdr.InitSize ? write_file( xrom_fname, xrom_buf ) return xrom_hdr
def smi_mmio_range_fuzz(self, thread_id, b, d, f, bar_off, is64bit, bar, new_bar, base, size): # copy all registers from MMIO range to new location in memory # we do that once rather than before every SMI since we return after first change detected self.logger.log( "[*] copying BAR 0x%X > 0x%X" % (base,self.reloc_mmio) ) orig_mmio = self.copy_bar(base, self.reloc_mmio, size) if self.logger.VERBOSE: self.cs.mmio.dump_MMIO(base, size) file.write_file('mmio_mem.orig', orig_mmio) for smi_code in xrange(self.smic_start,self.smic_end+1): for smi_data in xrange(self.smid_start,self.smid_end+1): for ecx in xrange(self.smif_start,self.smif_end+1): self.logger.log( "> SMI# %02X: data %02X, func (ECX) %X" % (smi_code,smi_data,ecx) ) if FLUSH_OUTPUT_AFTER_SMI: self.logger.flush() # point MMIO range to new location (relocate MMIO range) self.logger.log( " relocating BAR 0x%X" % bar ) if not self.modify_bar(b, d, f, bar_off, is64bit, bar, new_bar): continue # generate SW SMI self._interrupts.send_SW_SMI(thread_id, smi_code, smi_data, _FILL_VALUE_QWORD, self.comm, ecx, _FILL_VALUE_QWORD, _FILL_VALUE_QWORD, _FILL_VALUE_QWORD) # restore original location of MMIO range self.restore_bar(b, d, f, bar_off, is64bit, bar) self.logger.log( " restored BAR with 0x%X" % bar ) # check the contents at the address range used to relocate MMIO BAR buf = self.cs.mem.read_physical_mem( self.reloc_mmio, size ) diff = DIFF(orig_mmio, buf, size) self.logger.log(" checking relocated MMIO") if len(diff) > 0: self.logger.log_important("changes found at 0x%X +%s" % (self.reloc_mmio, diff)) if self.logger.VERBOSE: file.write_file('mmio_mem.new', buf) return True return False
def run(self): if len(self.argv) < 3: print DecodeCommand.__doc__ return _uefi = uefi.UEFI( self.cs ) if self.argv[2] == "types": print "\n<fw_type> should be in [ %s ]\n" % ( " | ".join( ["%s" % t for t in uefi.uefi_platform.fw_types] ) ) return rom_file = self.argv[2] fwtype = self.argv[3] if len(self.argv) == 4 else None self.logger.log( "[CHIPSEC] Decoding SPI ROM image from a file '%s'" % rom_file ) t = time.time() f = read_file( rom_file ) (fd_off, fd) = spi_descriptor.get_spi_flash_descriptor( f ) if (-1 == fd_off) or (fd is None): self.logger.error( "Could not find SPI Flash descriptor in the binary '%s'" % rom_file ) return False self.logger.log( "[CHIPSEC] Found SPI Flash descriptor at offset 0x%x in the binary '%s'" % (fd_off, rom_file) ) rom = f[fd_off:] # Decoding Flash Descriptor #self.logger.LOG_COMPLETE_FILE_NAME = os.path.join( pth, 'flash_descriptor.log' ) #parse_spi_flash_descriptor( self.cs, fd ) # Decoding SPI Flash Regions # flregs[r] = (r,SPI_REGION_NAMES[r],flreg,base,limit,notused) flregs = spi_descriptor.get_spi_regions( fd ) if flregs is None: self.logger.error( "SPI Flash descriptor region is not valid" ) return False _orig_logname = self.logger.LOG_FILE_NAME pth = os.path.join( self.cs.helper.getcwd(), rom_file + ".dir" ) if not os.path.exists( pth ): os.makedirs( pth ) for r in flregs: idx = r[0] name = r[1] base = r[3] limit = r[4] notused = r[5] if not notused: region_data = rom[base:limit+1] fname = os.path.join( pth, '%d_%04X-%04X_%s.bin' % (idx, base, limit, name) ) write_file( fname, region_data ) if spi.FLASH_DESCRIPTOR == idx: # Decoding Flash Descriptor self.logger.set_log_file( os.path.join( pth, fname + '.log' ) ) spi_descriptor.parse_spi_flash_descriptor( self.cs, region_data ) elif spi.BIOS == idx: # Decoding EFI Firmware Volumes self.logger.set_log_file( os.path.join( pth, fname + '.log' ) ) spi_uefi.decode_uefi_region(_uefi, pth, fname, fwtype) self.logger.set_log_file( _orig_logname ) self.logger.log( "[CHIPSEC] (decode) time elapsed %.3f" % (time.time()-t) )