Ejemplo n.º 1
0
    def dump_Descriptor_Table(self, cpu_thread_id, code, num_entries=None):
        (limit, base, pa) = self.helper.get_descriptor_table(cpu_thread_id, code)
        dt = self.helper.read_physical_mem(pa, limit + 1)
        total_num = len(dt) / 16
        if (total_num < num_entries) or (num_entries is None):
            num_entries = total_num
        logger().log("[cpu%d] Physical Address: 0x%016X" % (cpu_thread_id, pa))
        logger().log("[cpu%d] # of entries    : %d" % (cpu_thread_id, total_num))
        logger().log("[cpu%d] Contents (%d entries):" % (cpu_thread_id, num_entries))
        print_buffer(buffer(dt, 0, 16 * num_entries))
        logger().log("--------------------------------------")
        logger().log("#    segment:offset         attributes")
        logger().log("--------------------------------------")
        for i in range(0, num_entries):
            offset = (
                (ord(dt[i * 16 + 11]) << 56)
                | (ord(dt[i * 16 + 10]) << 48)
                | (ord(dt[i * 16 + 9]) << 40)
                | (ord(dt[i * 16 + 8]) << 32)
                | (ord(dt[i * 16 + 7]) << 24)
                | (ord(dt[i * 16 + 6]) << 16)
                | (ord(dt[i * 16 + 1]) << 8)
                | ord(dt[i * 16 + 0])
            )
            segsel = (ord(dt[i * 16 + 3]) << 8) | ord(dt[i * 16 + 2])
            attr = (ord(dt[i * 16 + 5]) << 8) | ord(dt[i * 16 + 4])
            logger().log("%03d  %04X:%016X  0x%04X" % (i, segsel, offset, attr))

        return (pa, dt)
Ejemplo n.º 2
0
 def _ioctl( self, ioctl_code, in_buf, out_length ):
     out_buf = (c_char * out_length)()
     self.get_driver_handle()
     #ret = kernel32.DeviceIoControl( self.driver_handle, ioctl_code, in_buf, len(in_buf), byref(out_buf), out_length, byref(out_size), None )
     if logger().VERBOSE: print_buffer( in_buf )
     try:
        out_buf = win32file.DeviceIoControl( self.driver_handle, ioctl_code, in_buf, out_length, None )       
     except pywintypes.error, msg:
        logger().error( 'DeviceIoControl returned error: %s' % str(msg) )
        return None
Ejemplo n.º 3
0
 def _ioctl( self, ioctl_code, in_buf, out_length ):
     out_buf = (c_char * out_length)()
     self.get_driver_handle()
     #ret = kernel32.DeviceIoControl( self.driver_handle, ioctl_code, in_buf, len(in_buf), byref(out_buf), out_length, byref(out_size), None )
     if logger().VERBOSE: print_buffer( in_buf )
     try:
         out_buf = win32file.DeviceIoControl( self.driver_handle, ioctl_code, in_buf, out_length, None )
     except pywintypes.error, _err:
         err_status = _err[0] + 0x100000000
         if STATUS_PRIVILEGED_INSTRUCTION == err_status:
             err_msg = "HW Access Violation: DeviceIoControl returned STATUS_PRIVILEGED_INSTRUCTION (0x%X)" % err_status
             logger().error( err_msg )
             raise HWAccessViolationError( err_msg, err_status )
         else:
             err_msg = "HW Access Error: DeviceIoControl returned status 0x%X (%s)" % (err_status,_err[2])
             logger().error( err_msg )
             raise OsHelperError( err_msg, err_status )
Ejemplo n.º 4
0
    def _ioctl( self, ioctl_code, in_buf, out_length ):

        if not self.driver_loaded:
           _handle_error("chipsec kernel driver is not loaded (in native API mode?)")

        out_buf = (c_char * out_length)()
        self.get_driver_handle()
        if logger().DEBUG: print_buffer( in_buf )
        try:
            out_buf = win32file.DeviceIoControl( self.driver_handle, ioctl_code, in_buf, out_length, None )
        except pywintypes.error, _err:
            err_status = _err[0] + 0x100000000
            if STATUS_PRIVILEGED_INSTRUCTION == err_status:
                err_msg = "HW Access Violation: DeviceIoControl returned STATUS_PRIVILEGED_INSTRUCTION (0x%X)" % err_status
                if logger().DEBUG: logger().error( err_msg )
                raise HWAccessViolationError( err_msg, err_status )
            else:
                _handle_error( "HW Access Error: DeviceIoControl returned status 0x%X (%s)" % (err_status,_err[2]), err_status )
Ejemplo n.º 5
0
 def write_virtual_mem( self, virt_address, length, buf ):
     if logger().HAL:
         logger().log( '[mem] buffer len = 0x%X to VA = 0x%016X' % (length, virt_address) )
         print_buffer( buf )
     phys_address = self.va2pa(virt_address)
     return self.helper.write_physical_mem( phys_address, length, buf )
Ejemplo n.º 6
0
    def run(self):
        size = 0x100

        if len(self.argv) < 3:
            print MemCommand.__doc__
            return

        op = self.argv[2]
        t = time.time()

        if 'allocate'   == op and 4 == len(self.argv):
            size = int(self.argv[3],16)
            (va, pa) = self.cs.mem.alloc_physical_mem( size )
            self.logger.log( '[CHIPSEC] Allocated %X bytes of physical memory: VA = 0x%016X, PA = 0x%016X' % (size, va, pa) )

        elif 'pagedump' == op and len(self.argv) > 3:
            start   = long(self.argv[3],16)
            length  = long(self.argv[4],16) if len(self.argv) > 4 else chipsec.defines.BOUNDARY_4KB
            end = start + length

            dump_region_to_path( chipsec.file.get_main_dir(), start, end )

        elif 'read'     == op:
            phys_address = int(self.argv[3],16)
            size         = int(self.argv[4],16) if len(self.argv) > 4 else 0x100
            self.logger.log( '[CHIPSEC] reading buffer from memory: PA = 0x%016X, len = 0x%X..' % (phys_address, size) )
            buffer = self.cs.mem.read_physical_mem( phys_address, size )
            if len(self.argv) > 5:
                buf_file = self.argv[5]
                chipsec.file.write_file( buf_file, buffer )
                self.logger.log( "[CHIPSEC] written 0x%X bytes to '%s'" % (len(buffer), buf_file) )
            else:
                print_buffer( buffer )

        elif 'readval'  == op:
            phys_address = int(self.argv[3],16)
            width        = 0x4
            if len(self.argv) > 4: 
                width = chipsec_util.get_option_width(self.argv[4]) if chipsec_util.is_option_valid_width(self.argv[4]) else int(self.argv[4],16)
            self.logger.log( '[CHIPSEC] reading %X-byte value from PA 0x%016X..' % (width, phys_address) )
            if   0x1 == width: value = self.cs.mem.read_physical_mem_byte ( phys_address )
            elif 0x2 == width: value = self.cs.mem.read_physical_mem_word ( phys_address )
            elif 0x4 == width: value = self.cs.mem.read_physical_mem_dword( phys_address )
            self.logger.log( '[CHIPSEC] value = 0x%X' % value )

        elif 'write'    == op:
            phys_address = int(self.argv[3],16)
            if len(self.argv) > 4: 
                size = int(self.argv[4],16)
            else:
                self.logger.error( "must specify <length> argument in 'mem write'" )
                return
            if len(self.argv) > 5:
                buf_file = self.argv[5]
                if not os.path.exists( buf_file ):
                    #buffer = buf_file.decode('hex')
                    try:
                      buffer = bytearray.fromhex(buf_file)
                    except ValueError, e:
                        self.logger.error( "incorrect <value> specified: '%s'" % buf_file )
                        self.logger.error( str(e) )
                        return
                    self.logger.log( "[CHIPSEC] read 0x%X hex bytes from command-line: %s'" % (len(buffer), buf_file) )
                else:
                    buffer = chipsec.file.read_file( buf_file )
                    self.logger.log( "[CHIPSEC] read 0x%X bytes from file '%s'" % (len(buffer), buf_file) )

                if len(buffer) < size:
                    self.logger.error( "number of bytes read (0x%X) is less than the specified <length> (0x%X)" % (len(buffer),size) )
                    return

                self.logger.log( '[CHIPSEC] writing buffer to memory: PA = 0x%016X, len = 0x%X..' % (phys_address, size) )
                self.cs.mem.write_physical_mem( phys_address, size, buffer )
            else:
                self.logger.error( "must specify <buffer>|<file> argument in 'mem write'" )
                return
Ejemplo n.º 7
0
    def gfx_aperture_dma_read_write(self, address, size=0x4, value=None, pte_num=0):
        r = 0
        pages = 0

        gmadr = self.get_GMADR()
        off = address%0x1000
        h = 0x1000 - off
        igd_addr = gmadr + pte_num*0x1000
        pte_orig = self.read_GGTT_PTE( pte_num )

        if self.logger.HAL:
            self.logger.log( '[igd] reading 0x%X bytes at PA 0x%016X through IGD aperture (DMA) using PTE%d' % (size,address,pte_num) )
            self.logger.log( '[igd] GFx aperture (GMADR): 0x%016X' % gmadr )
            self.logger.log( '[igd] GFx GTT base        : 0x%016X' % self.get_GGTT_base() )
            self.logger.log( '[igd] original GTT PTE%03d: 0x%08X' % (pte_num,pte_orig) )
        

        if (h > 0) and (size > h):
            r = (size - h)%0x1000
            pages = 2 + (size - h)//0x1000
        else:
            r = size%0x1000
            pages = 1 + size//0x1000

        N = pages
        if self.logger.HAL: self.logger.log( '[igd] pages = 0x%X, r = 0x%x, N = %d' % (pages,r,N) )

        if self.logger.VERBOSE:
            self.logger.log( '[igd] original data at address 0x%016X:' % address )
            print_buffer(self.cs.mem.read_physical_mem(address, size))

        buffer = ''
        pa = address    
        for p in range(N):
            pte = self.get_GGTT_PTE_from_PA(pa)
            if self.logger.HAL: self.logger.log( '[igd] GFx PTE for address 0x%016X: 0x%08X' % (address,pte) )
            self.write_GGTT_PTE(pte_num, pte)
            if (p == 0):
                pa_off = off
                size = h if (pa_off > 0)   else 0x1000
            else:
                pa_off = 0
            if (p == N-1):
                size = r if (r > 0) else 0x1000
            if value is None:
                if self.logger.HAL: self.logger.log( '[igd] reading 0x%X bytes at 0x%016X through GFx aperture 0x%016X ..' % (size,pa,igd_addr + pa_off) )
                page = self.cs.mem.read_physical_mem(igd_addr + pa_off, size)
                buffer += page
                if self.logger.HAL: print_buffer(page[:size])
            else:
                if self.logger.HAL: self.logger.log( '[igd] writing 0x%X bytes to 0x%016X through GFx aperture 0x%016X ..' % (size,pa,igd_addr + pa_off) )
                page = value[p*0x1000:p*0x1000+size]
                self.cs.mem.write_physical_mem(igd_addr + pa_off, size, page)
                if self.logger.HAL: print_buffer(page)
            pa += size

        # restore original PTE
        if self.logger.HAL: self.logger.log( '[igd] restoring GFx PTE%d 0x%X..' % (pte_num,pte_orig) )
        self.write_GGTT_PTE(pte_num, pte_orig)

        return buffer
Ejemplo n.º 8
0
 def find_EFI_Table(self, table_sig):
     (smram_base, smram_limit, smram_size) = self.cs.cpu.get_SMRAM()
     CHUNK_SZ = 1024 * 1024  # 1MB
     if logger().HAL:
         logger().log(
             "[uefi] searching memory for EFI table with signature '{}' ..".
             format(table_sig))
     table_pa, table_header, table, table_buf = None, None, None, None
     pa = smram_base - CHUNK_SZ
     isFound = False
     while pa > CHUNK_SZ:
         if logger().HAL:
             logger().log('[uefi] reading 0x{:016X}..'.format(pa))
         try:
             membuf = self.cs.mem.read_physical_mem(pa, CHUNK_SZ)
         except OsHelperError as err:
             if logger().HAL:
                 logger().log(
                     "[uefi] Unable to read memory at pa: {:016X} Error: {}"
                     .format(pa, err))
             pa -= CHUNK_SZ
             continue
         pos = bytestostring(membuf).find(table_sig)
         if -1 != pos:
             table_pa = pa + pos
             if logger().HAL:
                 logger().log(
                     "[uefi] found signature '{}' at 0x{:016X}..".format(
                         table_sig, table_pa))
             if pos < (CHUNK_SZ - EFI_TABLE_HEADER_SIZE):
                 hdr = membuf[pos:pos + EFI_TABLE_HEADER_SIZE]
             else:
                 hdr = self.cs.mem.read_physical_mem(
                     table_pa, EFI_TABLE_HEADER_SIZE)
             table_header = EFI_TABLE_HEADER(
                 *struct.unpack_from(EFI_TABLE_HEADER_FMT, hdr))
             # do some sanity checks on the header
             if 0 != table_header.Reserved or                 \
                0 == table_header.CRC32    or                 \
                table_header.Revision not in EFI_REVISIONS or \
                table_header.HeaderSize > MAX_EFI_TABLE_SIZE:
                 if logger().HAL:
                     logger().log(
                         "[uefi] found '{}' at 0x{:016X} but doesn't look like an actual table. keep searching.."
                         .format(table_sig, table_pa))
                     logger().log(table_header)
             else:
                 isFound = True
                 if logger().HAL:
                     logger().log(
                         "[uefi] found EFI table at 0x{:016X} with signature '{}'.."
                         .format(table_pa, table_sig))
                 table_size = struct.calcsize(EFI_TABLES[table_sig]['fmt'])
                 if pos < (CHUNK_SZ - EFI_TABLE_HEADER_SIZE - table_size):
                     table_buf = membuf[pos:pos + EFI_TABLE_HEADER_SIZE +
                                        table_size]
                 else:
                     table_buf = self.cs.mem.read_physical_mem(
                         table_pa, EFI_TABLE_HEADER_SIZE + table_size)
                 table = EFI_TABLES[table_sig]['struct'](
                     *struct.unpack_from(EFI_TABLES[table_sig]['fmt'],
                                         table_buf[EFI_TABLE_HEADER_SIZE:]))
                 if logger().HAL:
                     print_buffer(bytestostring(table_buf))
                     logger().log('[uefi] {}:'.format(
                         EFI_TABLES[table_sig]['name']))
                     logger().log(table_header)
                     logger().log(table)
                 break
         pa -= CHUNK_SZ
     if (not isFound) and logger().HAL:
         logger().log(
             "[uefi] could not find EFI table with signature '{}'".format(
                 table_sig))
     return (isFound, table_pa, table_header, table, table_buf)
Ejemplo n.º 9
0
    def find_s3_bootscript(self):
        found = False
        BootScript_addresses = []

        efivars = self.list_EFI_variables()
        if efivars is None:
            logger().error('Could not enumerate UEFI variables at runtime')
            return (found, BootScript_addresses)
        if logger().HAL:
            logger().log("[uefi] searching for EFI variable(s): " +
                         str(S3_BOOTSCRIPT_VARIABLES))

        for efivar_name in efivars:
            (off, buf, hdr, data, guid, attrs) = efivars[efivar_name][0]
            if efivar_name in S3_BOOTSCRIPT_VARIABLES:
                if logger().HAL:
                    logger().log("[uefi] found: {} {{{}}} {} variable".format(
                        efivar_name, guid, get_attr_string(attrs)))
                if logger().HAL:
                    logger().log(
                        '[uefi] {} variable data:'.format(efivar_name))
                    print_buffer(bytestostring(data))

                varsz = len(data)
                if 4 == varsz: AcpiGlobalAddr_fmt = '<L'
                elif 8 == varsz: AcpiGlobalAddr_fmt = '<Q'
                else:
                    logger().error(
                        "Unrecognized format of '{}' UEFI variable (data size = 0x{:X})"
                        .format(efivar_name, varsz))
                    break
                AcpiGlobalAddr = struct.unpack_from(AcpiGlobalAddr_fmt,
                                                    data)[0]
                if 0 == AcpiGlobalAddr:
                    logger().error(
                        "Pointer to ACPI Global Data structure in {} variable is 0"
                        .format(efivar_name))
                    break
                if logger().HAL:
                    logger().log(
                        "[uefi] Pointer to ACPI Global Data structure: 0x{:016X}"
                        .format(AcpiGlobalAddr))
                if logger().HAL:
                    logger().log(
                        "[uefi] Decoding ACPI Global Data structure..")
                AcpiVariableSet = self.helper.read_physical_mem(
                    AcpiGlobalAddr, ACPI_VARIABLE_SET_STRUCT_SIZE)
                if logger().HAL:
                    logger().log('[uefi] AcpiVariableSet structure:')
                    print_buffer(bytestostring(AcpiVariableSet))
                AcpiVariableSet_fmt = '<6Q'
                #if len(AcpiVariableSet) < struct.calcsize(AcpiVariableSet_fmt):
                #    logger().error( 'Unrecognized format of AcpiVariableSet structure' )
                #    return (False,0)
                AcpiReservedMemoryBase, AcpiReservedMemorySize, S3ReservedLowMemoryBase, AcpiBootScriptTable, RuntimeScriptTableBase, AcpiFacsTable = struct.unpack_from(
                    AcpiVariableSet_fmt, AcpiVariableSet)
                if logger().HAL:
                    logger().log(
                        '[uefi] ACPI Boot-Script table base = 0x{:016X}'.
                        format(AcpiBootScriptTable))
                found = True
                BootScript_addresses.append(AcpiBootScriptTable)
                #break
        return (found, BootScript_addresses)