Esempio n. 1
0
 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
Esempio n. 2
0
    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
Esempio n. 3
0
    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) )