예제 #1
0
    def fill_memory(self, _addr, is_ptr_in_buffer, _ptr, _ptr_offset, _sig,
                    _sig_offset):
        #
        # Fill in contents at PA = _addr with known pattern to check later if any SMI handler modifies them
        #
        fill_buf = FILL_BUFFER(self.fill_byte, self.fill_size,
                               is_ptr_in_buffer, _ptr, _ptr_offset, _sig,
                               _sig_offset)

        s = "[*] writing 0x{:X} bytes at 0x{:016X}".format(
            self.fill_size, _addr)
        if is_ptr_in_buffer: s += " -> PTR at +0x{:X}".format(_ptr_offset)
        if _sig is not None: s += " -> SIG at +0x{:X}".format(_sig_offset)
        self.logger.log(s)
        self.cs.mem.write_physical_mem(_addr, self.fill_size, fill_buf)

        if self.logger.VERBOSE:
            self.logger.log(
                "filling in contents at PA 0x{:016X}:".format(_addr))
            print_buffer_bytes(fill_buf, 16)

        if is_ptr_in_buffer and _ptr is not None:
            self.logger.log(
                "[*] writing buffer at PA 0x{:016X} with 0x{:X} bytes '{}'".
                format(_ptr, self.fill_size, self.fill_byte))
            self.cs.mem.write_physical_mem(_ptr, self.fill_size,
                                           self.fill_byte * self.fill_size)

        return True
예제 #2
0
    def read_spi(self, spi_fla, data_byte_count ):

        self.check_hardware_sequencing()

        buf = bytearray()
        dbc = SPI_READ_WRITE_DEF_DBC
        if (data_byte_count >= SPI_READ_WRITE_MAX_DBC):
            dbc = SPI_READ_WRITE_MAX_DBC

        n = data_byte_count // dbc
        r = data_byte_count % dbc
        if self.logger.UTIL_TRACE or self.logger.HAL:
            self.logger.log( "[spi] reading 0x{:x} bytes from SPI at FLA = 0x{:x} (in {:d} 0x{:x}-byte chunks + 0x{:x}-byte remainder)".format(data_byte_count, spi_fla, n, dbc, r) )

        cycle_done = self._wait_SPI_flash_cycle_done()
        if not cycle_done:
            self.logger.error( "SPI cycle not ready" )
            return None

        for i in range(n):
            if self.logger.HAL:
                self.logger.log( "[spi] reading chunk {:d} of 0x{:x} bytes from 0x{:x}".format(i, dbc, spi_fla + i *dbc) )
            if not self._send_spi_cycle( HSFCTL_READ_CYCLE, dbc -1, spi_fla + i *dbc ):
                self.logger.error( "SPI flash read failed" )
            else:
                for fdata_idx in range(0, dbc //4):
                    dword_value = self.spi_reg_read( self.fdata0_off + fdata_idx *4 )
                    if self.logger.HAL:
                        self.logger.log( "[spi] FDATA00 + 0x{:x}: 0x{:x}".format(fdata_idx *4, dword_value) )
                    buf += struct.pack("I", dword_value)

        if (0 != r):
            if self.logger.HAL:
                self.logger.log( "[spi] reading remaining 0x{:x} bytes from 0x{:x}".format(r, spi_fla + n *dbc) )
            if not self._send_spi_cycle( HSFCTL_READ_CYCLE, r -1, spi_fla + n *dbc ):
                self.logger.error( "SPI flash read failed" )
            else:
                t = 4
                n_dwords = (r +3) //4
                for fdata_idx in range(0, n_dwords):
                    dword_value = self.spi_reg_read( self.fdata0_off + fdata_idx *4 )
                    if self.logger.HAL:
                        self.logger.log( "[spi] FDATA00 + 0x{:x}: 0x{:08X}".format(fdata_idx *4, dword_value) )
                    if (fdata_idx == (n_dwords -1)) and (0 != r%4):
                        t = r%4
                    for j in range(t):
                        buf += struct.pack('B', (dword_value >> (8 *j)) & 0xff)

        if self.logger.HAL:
            self.logger.log( "[spi] buffer read from SPI:" )
            print_buffer_bytes(buf)

        return buf
예제 #3
0
    def send_smmc_SMI(self,
                      smmc,
                      guid,
                      payload,
                      payload_loc,
                      CommandPort=0x0,
                      DataPort=0x0):
        guid_b = uuid.UUID(guid).bytes_le
        payload_sz = len(payload)

        data_hdr = guid_b + struct.pack("Q", payload_sz) + payload
        # write payload to payload_loc
        CommBuffer_offset = 56
        BufferSize_offset = CommBuffer_offset + 8
        ReturnStatus_offset = BufferSize_offset + 8

        self.cs.mem.write_physical_mem(smmc + CommBuffer_offset, 8,
                                       struct.pack("Q", payload_loc))
        self.cs.mem.write_physical_mem(smmc + BufferSize_offset, 8,
                                       struct.pack("Q", len(data_hdr)))
        self.cs.mem.write_physical_mem(payload_loc, len(data_hdr), data_hdr)

        if self.logger.VERBOSE:
            self.logger.log("[*] Communication buffer on input")
            print_buffer_bytes(
                self.cs.mem.read_physical_mem(payload_loc, len(data_hdr)))
            self.logger.log("")

        self.send_SMI_APMC(CommandPort, DataPort)

        if self.logger.VERBOSE:
            self.logger.log("[*] Communication buffer on output")
            print_buffer_bytes(
                self.cs.mem.read_physical_mem(payload_loc, len(data_hdr)))
            self.logger.log("")

        ReturnStatus = struct.unpack(
            "Q", self.cs.mem.read_physical_mem(smmc + ReturnStatus_offset,
                                               8))[0]
        return ReturnStatus
예제 #4
0
파일: tpm.py 프로젝트: npmitche/chipsec
    def command( self, commandName, locality, command_argv ):
        """
        Send command to the TPM and receive data
        """
        try:
            Locality = LOCALITY[locality]
        except:
            if self.logger.HAL: self.logger.log_bad("Invalid locality value\n")
            return

        requestedUse = False

        #
        # Request locality use if needed
        #
        access_address = self.TPM_BASE | Locality | TPM_ACCESS
        if self.helper.read_mmio_reg( access_address, 4 ) == BEENSEIZED:
            self.helper.write_mmio_reg( access_address, 4, REQUESTUSE )
            requestedUse = True

        #
        # Build command (big endian) and send/receive
        #
        ( command, size ) = COMMANDS[commandName]( command_argv )
        self._send_command( Locality, command, size )

        ( header, data, header_blob, data_blob ) = self._read_response( Locality )
        self.logger.log( header )
        print_buffer_bytes( data_blob )
        self.logger.log( '\n' )

        #
        # Release locality if needed
        #
        if requestedUse==True:
            self.helper.write_mmio_reg( access_address, 4, BEENSEIZED )
        self.helper.write_mmio_reg( access_address, 1, ACTIVELOCALITY )
예제 #5
0
    def check_memory(self, _addr, _smi_desc, fn, restore_contents=False):
        _ptr = _smi_desc.ptr
        filler = self.fill_byte * self.fill_size
        #
        # Check if contents have changed at physical address passed in GPRs to SMI handler
        # If changed, SMI handler might have written to that address
        #
        self.logger.log("    < checking buffers")

        expected_buf = FILL_BUFFER(self.fill_byte, self.fill_size,
                                   _smi_desc.ptr_in_buffer, _smi_desc.ptr,
                                   _smi_desc.ptr_offset, _smi_desc.sig,
                                   _smi_desc.sig_offset)
        buf = self.cs.mem.read_physical_mem(_addr, self.fill_size)
        differences = DIFF(expected_buf, buf, self.fill_size)
        _changed = (len(differences) > 0)

        if self.logger.VERBOSE:
            self.logger.log("checking contents at PA 0x{:016X}:".format(_addr))
            print_buffer_bytes(buf, 16)
            self.logger.log("expected contents:")
            print_buffer_bytes(expected_buf, 16)

        if _changed:
            self.logger.log("    contents changed at 0x{:016X} +{}".format(
                _addr, differences))
            if restore_contents:
                self.logger.log(
                    "    restoring 0x{:X} bytes at 0x{:016X}".format(
                        self.fill_size, _addr))
                self.cs.mem.write_physical_mem(_addr, self.fill_size,
                                               expected_buf)
            if DUMP_MEMORY_ON_DETECT:
                _pth_smi = os.path.join(
                    _pth, '{:X}_{}'.format(_smi_desc.smi_code, _smi_desc.name))
                if not os.path.exists(_pth_smi): os.makedirs(_pth_smi)
                _f = os.path.join(_pth_smi, fn + '.dmp')
                self.logger.log("    dumping buffer to '{}'".format(_f))
                write_file(_f, buf)

        _changed1 = False
        expected_buf = filler
        if _smi_desc.ptr_in_buffer and _ptr is not None:
            buf1 = self.cs.mem.read_physical_mem(_ptr, self.fill_size)
            differences1 = DIFF(expected_buf, buf1, self.fill_size)
            _changed1 = (len(differences1) > 0)

            if self.logger.VERBOSE:
                self.logger.log(
                    "checking contents at PA 0x{:016X}:".format(_ptr))
                print_buffer_bytes(buf1, 16)

            if _changed1:
                self.logger.log("    contents changed at 0x{:016X} +{}".format(
                    _ptr, differences1))
                if restore_contents:
                    self.logger.log(
                        "    restoring 0x{:X} bytes at PA 0x{:016X}".format(
                            self.fill_size, _ptr))
                    self.cs.mem.write_physical_mem(_ptr, self.fill_size,
                                                   expected_buf)
                if DUMP_MEMORY_ON_DETECT:
                    _pth_smi = os.path.join(
                        _pth, '{:X}_{}'.format(_smi_desc.smi_code,
                                               _smi_desc.name))
                    if not os.path.exists(_pth_smi): os.makedirs(_pth_smi)
                    _f = os.path.join(
                        _pth_smi,
                        fn + ('_ptr{:X}.dmp'.format(_smi_desc.ptr_offset)))
                    self.logger.log("    dumping buffer to '{}'".format(_f))
                    write_file(_f, buf1)

        return (_changed or _changed1)