def build_efi_tree(_uefi, data, fwtype): fvolumes = [] fv_off, fv_guid, fv_size, fv_attr, fv_hdrsz, fv_csum, fv_hdroff, fv_img, fv_calccsum = NextFwVolume( data) while fv_off is not None: fv = EFI_FV(fv_off, fv_guid, fv_size, fv_attr, fv_hdrsz, fv_csum, fv_hdroff, fv_img, fv_calccsum) fv.calc_hashes() # Detect File System firmware volumes if fv.Guid in (EFI_PLATFORM_FS_GUIDS + EFI_FS_GUIDS): fwbin = build_efi_file_tree(_uefi, fv_img, fwtype) for i in fwbin: fv.children.append(i) # Detect NVRAM firmware volumes elif fv.Guid in EFI_NVRAM_GUIDS: # == VARIABLE_STORE_FV_GUID: fv.isNVRAM = True try: fv.NVRAMType = identify_EFI_NVRAM( fv.Image) if fwtype is None else fwtype except: logger().warn("couldn't identify NVRAM in FV {{{}}}".format( fv.Guid)) fvolumes.append(fv) fv_off, fv_guid, fv_size, fv_attr, fv_hdrsz, fv_csum, fv_hdroff, fv_img, fv_calccsum = NextFwVolume( data, fv.Offset + fv.Size) return fvolumes
def decode_uefi_region(_uefi, pth, fname, fwtype): bios_pth = os.path.join(pth, fname + '.dir') if not os.path.exists(bios_pth): os.makedirs(bios_pth) fv_pth = os.path.join(bios_pth, 'FV') if not os.path.exists(fv_pth): os.makedirs(fv_pth) # Decoding UEFI Firmware Volumes if logger().HAL: logger().log("[spi_uefi] decoding UEFI firmware volumes...") parse_uefi_region_from_file(_uefi, fname, fwtype, fv_pth) # Decoding EFI Variables NVRAM if logger().HAL: logger().log("[spi_uefi] decoding UEFI NVRAM...") region_data = read_file(fname) if fwtype is None: fwtype = identify_EFI_NVRAM(region_data) if fwtype is None: return elif fwtype not in fw_types: if logger().HAL: logger().error("unrecognized NVRAM type {}".format(fwtype)) return nvram_fname = os.path.join(bios_pth, ('nvram_{}'.format(fwtype))) logger().set_log_file((nvram_fname + '.nvram.lst')) _uefi.parse_EFI_variables(nvram_fname, region_data, False, fwtype)
def decode_uefi_region(_uefi, pth, fname, fwtype): bios_pth = os.path.join( pth, fname + '.dir' ) if not os.path.exists( bios_pth ): os.makedirs( bios_pth ) fv_pth = os.path.join( bios_pth, 'FV' ) if not os.path.exists( fv_pth ): os.makedirs( fv_pth ) # Decoding UEFI Firmware Volumes if logger().HAL: logger().log( "[spi_uefi] decoding UEFI firmware volumes..." ) parse_uefi_region_from_file( _uefi, fname, fwtype, fv_pth ) # Decoding EFI Variables NVRAM if logger().HAL: logger().log( "[spi_uefi] decoding UEFI NVRAM..." ) region_data = read_file( fname ) if fwtype is None: fwtype = identify_EFI_NVRAM( region_data ) if fwtype is None: return elif fwtype not in fw_types: if logger().HAL: logger().error( "unrecognized NVRAM type {}".format(fwtype) ) return nvram_fname = os.path.join( bios_pth, ('nvram_{}'.format(fwtype)) ) logger().set_log_file( (nvram_fname + '.nvram.lst') ) _uefi.parse_EFI_variables( nvram_fname, region_data, False, fwtype )
def build_efi_tree(_uefi, data, fwtype): fvolumes = [] fv_off, fv_guid, fv_size, fv_attr, fv_hdrsz, fv_csum, fv_hdroff, fv_img, fv_calccsum = NextFwVolume( data) while fv_off is not None: fv = EFI_FV(fv_off, fv_guid, fv_size, fv_attr, fv_hdrsz, fv_csum, fv_hdroff, fv_img, fv_calccsum) fv.calc_hashes() polarity = bit_set(fv.Attributes, EFI_FVB2_ERASE_POLARITY) # Detect File System firmware volumes if fv.Guid in (EFI_PLATFORM_FS_GUIDS + EFI_FS_GUIDS): foff, next_offset, fname, ftype, fattr, fstate, fcsum, fsz, fimg, fhdrsz, fUD, fcalcsum = NextFwFile( fv.Image, fv.Size, fv.HeaderSize, polarity) while next_offset is not None: if fname: fwbin = EFI_FILE(foff, fname, ftype, fattr, fstate, fcsum, fsz, fimg, fhdrsz, fUD, fcalcsum) fwbin.calc_hashes() if fwbin.Type not in (EFI_FV_FILETYPE_ALL, EFI_FV_FILETYPE_RAW, EFI_FV_FILETYPE_FFS_PAD): fwbin.children = build_efi_modules_tree( _uefi, fwtype, fwbin.Image, fwbin.Size, fwbin.HeaderSize, polarity) elif fwbin.Type == EFI_FV_FILETYPE_RAW: if fwbin.Name != NVAR_NVRAM_FS_FILE: fwbin.children = build_efi_tree( _uefi, fwbin.Image, fwtype) else: fwbin.isNVRAM = True fwbin.NVRAMType = FWType.EFI_FW_TYPE_NVAR fv.children.append(fwbin) foff, next_offset, fname, ftype, fattr, fstate, fcsum, fsz, fimg, fhdrsz, fUD, fcalcsum = NextFwFile( fv.Image, fv.Size, next_offset, polarity) # Detect NVRAM firmware volumes elif fv.Guid in EFI_NVRAM_GUIDS: # == VARIABLE_STORE_FV_GUID: fv.isNVRAM = True try: fv.NVRAMType = identify_EFI_NVRAM( fv.Image) if fwtype is None else fwtype except: logger().warn("couldn't identify NVRAM in FV {%s}" % fv.Guid) fvolumes.append(fv) fv_off, fv_guid, fv_size, fv_attr, fv_hdrsz, fv_csum, fv_hdroff, fv_img, fv_calccsum = NextFwVolume( data, fv.Offset + fv.Size) return fvolumes
def nvram_auth(self): authvars = 1 rom = read_file( self.romfilename ) if self.fwtype is None: self.fwtype = identify_EFI_NVRAM( rom ) if self.fwtype is None: self.logger.error( "Could not automatically identify EFI NVRAM type" ) return elif self.fwtype not in fw_types: self.logger.error( "Unrecognized EFI NVRAM type '{}'".format(self.fwtype) ) return _orig_logname = self.logger.LOG_FILE_NAME self.logger.set_log_file( (self.romfilename + '.nv.lst') ) self._uefi.parse_EFI_variables( self.romfilename, rom, authvars, self.fwtype ) self.logger.set_log_file( _orig_logname )
def build_efi_tree( _uefi, data, fwtype ): fvolumes = [] fv_off, fv_guid, fv_size, fv_attr, fv_hdrsz, fv_csum, fv_hdroff, fv_img, fv_calccsum = NextFwVolume( data ) while fv_off is not None: fv = EFI_FV( fv_off, fv_guid, fv_size, fv_attr, fv_hdrsz, fv_csum, fv_hdroff, fv_img, fv_calccsum ) fv.calc_hashes() polarity = bit_set( fv.Attributes, EFI_FVB2_ERASE_POLARITY ) # Detect File System firmware volumes if fv.Guid in (EFI_PLATFORM_FS_GUIDS + EFI_FS_GUIDS): foff, next_offset, fname, ftype, fattr, fstate, fcsum, fsz, fimg, fhdrsz, fUD, fcalcsum = NextFwFile( fv.Image, fv.Size, fv.HeaderSize, polarity ) while next_offset is not None: if fname: fwbin = EFI_FILE( foff, fname, ftype, fattr, fstate, fcsum, fsz, fimg, fhdrsz, fUD, fcalcsum ) fwbin.calc_hashes() if fwbin.Type not in (EFI_FV_FILETYPE_ALL, EFI_FV_FILETYPE_RAW, EFI_FV_FILETYPE_FFS_PAD): fwbin.children = build_efi_modules_tree( _uefi, fwtype, fwbin.Image, fwbin.Size, fwbin.HeaderSize, polarity ) elif fwbin.Type == EFI_FV_FILETYPE_RAW: if fwbin.Name != NVAR_NVRAM_FS_FILE: fwbin.children = build_efi_tree( _uefi, fwbin.Image, fwtype ) else: fwbin.isNVRAM = True fwbin.NVRAMType = FWType.EFI_FW_TYPE_NVAR fv.children.append(fwbin) foff, next_offset, fname, ftype, fattr, fstate, fcsum, fsz, fimg, fhdrsz, fUD, fcalcsum = NextFwFile( fv.Image, fv.Size, next_offset, polarity ) # Detect NVRAM firmware volumes elif fv.Guid in EFI_NVRAM_GUIDS: # == VARIABLE_STORE_FV_GUID: fv.isNVRAM = True try: fv.NVRAMType = identify_EFI_NVRAM( fv.Image ) if fwtype is None else fwtype except: logger().warn("couldn't identify NVRAM in FV {%s}" % fv.Guid) fvolumes.append(fv) fv_off, fv_guid, fv_size, fv_attr, fv_hdrsz, fv_csum, fv_hdroff, fv_img, fv_calccsum = NextFwVolume( data, fv.Offset + fv.Size ) return fvolumes
def build_efi_tree( _uefi, data, fwtype ): fvolumes = [] fv_off, fv_guid, fv_size, fv_attr, fv_hdrsz, fv_csum, fv_hdroff, fv_img, fv_calccsum = NextFwVolume( data ) while fv_off is not None: fv = EFI_FV( fv_off, fv_guid, fv_size, fv_attr, fv_hdrsz, fv_csum, fv_hdroff, fv_img, fv_calccsum ) fv.calc_hashes() # Detect File System firmware volumes if fv.Guid in (EFI_PLATFORM_FS_GUIDS + EFI_FS_GUIDS): fwbin = build_efi_file_tree ( _uefi, fv_img, fwtype) for i in fwbin: fv.children.append(i) # Detect NVRAM firmware volumes elif fv.Guid in EFI_NVRAM_GUIDS: # == VARIABLE_STORE_FV_GUID: fv.isNVRAM = True try: fv.NVRAMType = identify_EFI_NVRAM( fv.Image ) if fwtype is None else fwtype except: logger().warn("couldn't identify NVRAM in FV {{{}}}".format(fv.Guid)) fvolumes.append(fv) fv_off, fv_guid, fv_size, fv_attr, fv_hdrsz, fv_csum, fv_hdroff, fv_img, fv_calccsum = NextFwVolume( data, fv.Offset + fv.Size ) return fvolumes
def traverse_uefi_region(_uefi, data, fwtype, uefi_path='', printall=True, dumpall=True, match_criteria=None, findall=True): found, voln, fwbin_dir = False, 0, '' # caller specified non-empty matching rules so we'll need to look for specific EFI modules as we parse FVs bsearch = (match_criteria is not None) fv_off, fv_guid, fv_size, fv_attr, fv_hdrsz, fv_csum, fv_hdroff, fv_img, fv_calccsum = NextFwVolume( data) while fv_off is not None: fv = EFI_FV(fv_off, fv_guid, fv_size, fv_attr, fv_hdrsz, fv_csum, fv_hdroff, fv_img, fv_calccsum) add_hashes(fv) if printall: logger().log(fv) if dumpall: volume_path = dump_fv(fv, voln, uefi_path) # only check the match rules if we need to find specific EFI module if bsearch and check_match_criteria(fv, match_criteria): if findall: found = True else: return True polarity = bit_set(fv.Attributes, EFI_FVB2_ERASE_POLARITY) # # Detect File System firmware volumes # if fv.Guid == EFI_FIRMWARE_FILE_SYSTEM2_GUID or fv.Guid == EFI_FIRMWARE_FILE_SYSTEM_GUID: foff, next_offset, fname, ftype, fattr, fstate, fcsum, fsz, fimg, fhdrsz, fUD, fcalcsum = NextFwFile( fv.Image, fv.Size, fv.HeaderSize, polarity) while (next_offset is not None): if fname is not None: fwbin = EFI_FILE(foff, fname, ftype, fattr, fstate, fcsum, fsz, fimg, fhdrsz, fUD, fcalcsum) fwbin.indent = DEF_INDENT add_hashes(fwbin) if printall: logger().log(fwbin) if dumpall: fwbin_dir = dump_fw_file(fwbin, volume_path) # only check the match rules if we need to find specific EFI module if bsearch and check_match_criteria(fwbin, match_criteria): if findall: found = True else: return True if fwbin.Type not in (EFI_FV_FILETYPE_ALL, EFI_FV_FILETYPE_RAW, EFI_FV_FILETYPE_FFS_PAD): if dumpall: os.makedirs(fwbin_dir) f = traverse_uefi_section(_uefi, fwtype, fwbin.Image, fwbin.Size, fwbin.HeaderSize, polarity, fv.Offset + fwbin.Offset, printall, dumpall, fwbin_dir, match_criteria, findall) if bsearch and f: if findall: found = True else: return True elif fwbin.Type == EFI_FV_FILETYPE_RAW: if fwbin.Name == NVAR_NVRAM_FS_FILE and fwbin.UD: if dumpall: _uefi.parse_EFI_variables( os.path.join(file_dir_path, 'DEFAULT_NVRAM'), FvImage, False, FWType.EFI_FW_TYPE_NVAR) foff, next_offset, fname, ftype, fattr, fstate, fcsum, fsz, fimg, fhdrsz, fUD, fcalcsum = NextFwFile( fv.Image, fv.Size, next_offset, polarity) # # Detect NVRAM firmware volumes # elif fv.Guid in EFI_NVRAM_GUIDS: # == VARIABLE_STORE_FV_GUID: if dumpall: try: t = identify_EFI_NVRAM( fv.Image) if fwtype is None else fwtype if t is not None: _uefi.parse_EFI_variables( os.path.join(volume_path, 'NVRAM'), fv.Image, False, t) except: logger().error( "[uefi] couldn't parse NVRAM firmware volume {%s}" % fv.Guid) #elif fv.Guid == ADDITIONAL_NV_STORE_GUID: # if dumpall: _uefi.parse_EFI_variables( os.path.join(volume_path, 'DEFAULT_NVRAM'), fv.Image, False, FWType.EFI_FW_TYPE_EVSA ) fv_off, fv_guid, fv_size, fv_attr, fv_hdrsz, fv_csum, fv_hdroff, fv_img, fv_calccsum = NextFwVolume( data, fv.Offset + fv.Size) voln += 1 return found
def traverse_uefi_region( _uefi, data, fwtype, uefi_path='', printall=True, dumpall=True, match_criteria=None, findall=True ): found, voln, fwbin_dir = False, 0, '' # caller specified non-empty matching rules so we'll need to look for specific EFI modules as we parse FVs bsearch = (match_criteria is not None) fv_off, fv_guid, fv_size, fv_attr, fv_hdrsz, fv_csum, fv_hdroff, fv_img, fv_calccsum = NextFwVolume( data ) while fv_off is not None: fv = EFI_FV( fv_off, fv_guid, fv_size, fv_attr, fv_hdrsz, fv_csum, fv_hdroff, fv_img, fv_calccsum ) add_hashes( fv ) if printall: logger().log( fv ) if dumpall: volume_path = dump_fv( fv, voln, uefi_path ) # only check the match rules if we need to find specific EFI module if bsearch and check_match_criteria( fv, match_criteria ): if findall: found = True else: return True polarity = bit_set( fv.Attributes, EFI_FVB2_ERASE_POLARITY ) # # Detect File System firmware volumes # if fv.Guid == EFI_FIRMWARE_FILE_SYSTEM2_GUID or fv.Guid == EFI_FIRMWARE_FILE_SYSTEM_GUID: foff, next_offset, fname, ftype, fattr, fstate, fcsum, fsz, fimg, fhdrsz, fUD, fcalcsum = NextFwFile( fv.Image, fv.Size, fv.HeaderSize, polarity ) while (next_offset is not None): if fname is not None: fwbin = EFI_FILE( foff, fname, ftype, fattr, fstate, fcsum, fsz, fimg, fhdrsz, fUD, fcalcsum ) fwbin.indent = DEF_INDENT add_hashes( fwbin ) if printall: logger().log( fwbin ) if dumpall: fwbin_dir = dump_fw_file( fwbin, volume_path ) # only check the match rules if we need to find specific EFI module if bsearch and check_match_criteria( fwbin, match_criteria ): if findall: found = True else: return True if dumpall: os.makedirs( fwbin_dir ) if fwbin.Type not in (EFI_FV_FILETYPE_ALL, EFI_FV_FILETYPE_RAW, EFI_FV_FILETYPE_FFS_PAD): f = traverse_uefi_section( _uefi, fwtype, fwbin.Image, fwbin.Size, fwbin.HeaderSize, polarity, fv.Offset + fwbin.Offset, printall, dumpall, fwbin_dir, match_criteria, findall ) if bsearch and f: if findall: found = True else: return True elif fwbin.Type == EFI_FV_FILETYPE_RAW: if (fwbin.Name == NVAR_NVRAM_FS_FILE) and dumpall: _uefi.parse_EFI_variables( os.path.join(fwbin_dir, 'NVRAM%s' % ('.UD' if fwbin.UD else '')), fv.Image, False, FWType.EFI_FW_TYPE_NVAR ) else: f = traverse_uefi_region( _uefi, fwbin.Image, fwtype, fwbin_dir, printall, dumpall, match_criteria, findall ) if bsearch and f: if findall: found = True else: return True foff, next_offset, fname, ftype, fattr, fstate, fcsum, fsz, fimg, fhdrsz, fUD, fcalcsum = NextFwFile( fv.Image, fv.Size, next_offset, polarity ) # # Detect NVRAM firmware volumes # elif fv.Guid in EFI_NVRAM_GUIDS: # == VARIABLE_STORE_FV_GUID: if dumpall: try: t = identify_EFI_NVRAM( fv.Image ) if fwtype is None else fwtype if t is not None: _uefi.parse_EFI_variables( os.path.join(volume_path, 'NVRAM'), fv.Image, False, t ) except: logger().error( "[uefi] couldn't parse NVRAM firmware volume {%s}" % fv.Guid ) #elif fv.Guid == ADDITIONAL_NV_STORE_GUID: # if dumpall: _uefi.parse_EFI_variables( os.path.join(volume_path, 'DEFAULT_NVRAM'), fv.Image, False, FWType.EFI_FW_TYPE_EVSA ) fv_off, fv_guid, fv_size, fv_attr, fv_hdrsz, fv_csum, fv_hdroff, fv_img, fv_calccsum = NextFwVolume( data, fv.Offset + fv.Size ) voln += 1 return found