def NextFwFileSection(sections, ssize, sof, polarity): EFI_COMMON_SECTION_HEADER_size = struct.calcsize(EFI_COMMON_SECTION_HEADER) res = None curr_offset = sof ssize = min(ssize, len(sections)) while curr_offset + EFI_COMMON_SECTION_HEADER_size < ssize: Size, Type = struct.unpack( EFI_COMMON_SECTION_HEADER, sections[curr_offset:curr_offset + EFI_COMMON_SECTION_HEADER_size]) Size = get_3b_size(Size) Header_Size = EFI_COMMON_SECTION_HEADER_size if Size == 0xFFFFFF and (curr_offset + EFI_COMMON_SECTION_HEADER_size + struct.calcsize("I")) < ssize: Size = struct.unpack( "I", sections[curr_offset + EFI_COMMON_SECTION_HEADER_size:curr_offset + EFI_COMMON_SECTION_HEADER_size + struct.calcsize("I")])[0] Header_Size = EFI_COMMON_SECTION_HEADER_size + struct.calcsize("I") if Type in SECTION_NAMES.keys(): sec_name = SECTION_NAMES[Type] else: sec_name = "S_UNKNOWN_{:02X}".format(Type) if (Size == 0xffffff and Type == 0xff) or (Size == 0): curr_offset = align(curr_offset + 4, 4) continue sec_body = sections[curr_offset:curr_offset + Size] res = EFI_SECTION(curr_offset, sec_name, Type, sec_body, Header_Size, align(Size, 4)) break return res
def NextFwFile(FvImage, FvLength, fof, polarity): file_header_size = struct.calcsize(EFI_FFS_FILE_HEADER) fof = align(fof, 8) cur_offset = fof res = None update_or_deleted = False while cur_offset + file_header_size < min(FvLength, len(FvImage)): fsize = 0 #if (fof + file_header_size) <= min(FvLength, len(FvImage)): #Check for a blank header if polarity: blank = b"\xff" * file_header_size else: blank = b"\x00" * file_header_size if (blank == FvImage[cur_offset:cur_offset + file_header_size]): #next_offset = fof + 8 cur_offset += 8 continue Name0, IntegrityCheck, Type, Attributes, Size, State = struct.unpack( EFI_FFS_FILE_HEADER, FvImage[cur_offset:cur_offset + file_header_size]) #Get File Header Size if Attributes & FFS_ATTRIB_LARGE_FILE: header_size = struct.calcsize(EFI_FFS_FILE_HEADER2) else: header_size = struct.calcsize(EFI_FFS_FILE_HEADER) #Get File size if Attributes & FFS_ATTRIB_LARGE_FILE and len( FvImage) > fof + struct.calcsize(EFI_FFS_FILE_HEADER2): fsize = struct.unpack( "Q", FvImage[fof + file_header_size:fof + file_header_size + struct.calcsize("Q")])[0] fsize &= 0xFFFFFFFF if fsize == 0 or fsize > FvLength - cur_offset: fsize = get_3b_size(Size) #Validate fsize is a legal value if fsize == 0 or fsize > FvLength - cur_offset: logger().log( "Unable to get correct file size for NextFwFile corrupt header information" ) break #Get next_offset update_or_deleted = (bit_set(State, EFI_FILE_MARKED_FOR_UPDATE, polarity)) or (bit_set( State, EFI_FILE_DELETED, polarity)) if not ((bit_set(State, EFI_FILE_DATA_VALID, polarity)) or update_or_deleted): #else: cur_offset = align(cur_offset + 1, 8) continue Name = UUID(bytes_le=Name0) #TODO need to fix up checksum? fheader = struct.pack(EFI_FFS_FILE_HEADER, Name0, 0, Type, Attributes, Size, 0) hsum = FvChecksum8(fheader) if (Attributes & FFS_ATTRIB_CHECKSUM): fsum = FvChecksum8(FvImage[cur_offset + file_header_size:cur_offset + fsize]) else: fsum = FFS_FIXED_CHECKSUM CalcSum = (hsum | (fsum << 8)) res = EFI_FILE(cur_offset, Name, Type, Attributes, State, IntegrityCheck, fsize, FvImage[cur_offset:cur_offset + fsize], header_size, update_or_deleted, CalcSum) break return res