Difference between revisions of "Boot.efi Information"

From AwkwardTV
Jump to: navigation, search
(Experimentation)
(Experimentation)
Line 114: Line 114:
 
|-
 
|-
 
| Build a boot.efi with the first and second PE sections swapped, update prop. header || Fails to boot - question-mark icon
 
| Build a boot.efi with the first and second PE sections swapped, update prop. header || Fails to boot - question-mark icon
 +
|-
 +
| Extract first PE section, rename to boot.efi || Fails to boot - question-mark icon
 +
|-
 +
| Extract second PE section, rename to boot.efi || Fails to boot - question-mark icon
 
|}
 
|}
  
 
The results of the first experiment are a pleasant surprise, since they indicate that the firmware doesn't validate the entire boot.efi file - only the PE sections contained within.  This suggests that if the proper checksum algorithm is discovered, booting a custom EFI image should be within reach.
 
The results of the first experiment are a pleasant surprise, since they indicate that the firmware doesn't validate the entire boot.efi file - only the PE sections contained within.  This suggests that if the proper checksum algorithm is discovered, booting a custom EFI image should be within reach.

Revision as of 21:02, 4 April 2007

Overview

In general, EFI executables adhere to the PE / COFF format, the documentation for which is readily available online: Portable Executable / Common Object File Format Documentation

At a glance, Apple's boot.efi does not adhere to this standard, but upon closer examination, it turns out to be two separate PE files concatenated together along with a proprietary header.

Proprietary header

AppleTV boot.efi

00000000h: B9 FA F1 0E 02 00 00 00 07 00 00 00 03 00 00 00 30 00 00 00 D8 3F 02 00 00 00 00 00 07 00 00 01 ; ¹úñ.............0...Ø?..........
00000020h: 03 00 00 00 08 40 02 00 28 4F 02 00 00 00 00 00                                                 ; .....@..(O......
Offset Data Purpose
0x00 B9 FA F1 0E Magic number? 0xEF1FAB9 looks like leetspeak
0x04 02 00 00 00 Unknown
0x08 07 00 00 00 Unknown
0x0B 03 00 00 00 Unknown
0xF0 30 00 00 00 Offset (in bytes) to beginning of first executable's header ( = 48 dec)
0xF4 D8 3F 02 00 Length (in bytes) of first executable ( = 147416 dec)
0xF8 00 00 00 00 Unknown (end of record?)
0xFB 07 00 00 01 Unknown
0x20 03 00 00 00 Unknown
0x24 08 40 02 00 Offset (in bytes) to beginning of second executable's header ( = 147464 dec)
0x28 28 4f 02 00 Length (in bytes) of first executable ( = 151336 dec)
0x3B 00 00 00 00 Unknown (end of record?)

OS X 10.4.8 boot.efi

00000000h: B9 FA F1 0E 02 00 00 00 07 00 00 00 03 00 00 00 30 00 00 00 21 0D 02 00 00 00 00 00 07 00 00 01 ; ¹úñ.............0...!...........
00000020h: 03 00 00 00 51 0D 02 00 17 13 02 00 00 00 00 00                                                 ; ....Q...........
Offset Data Purpose
0x00 B9 FA F1 0E Magic number? 0xEF1FAB9 looks like leetspeak
0x04 02 00 00 00 Unknown
0x08 07 00 00 00 Unknown
0x0B 03 00 00 00 Unknown
0xF0 30 00 00 00 Offset (in bytes) to beginning of first executable's header ( = 48 dec)
0xF4 21 0D 02 00 Length (in bytes) of first executable ( = 134433 dec)
0xF8 00 00 00 00 Unknown (end of record?)
0xFB 07 00 00 01 Unknown
0x20 03 00 00 00 Unknown
0x24 51 0D 02 00 Offset (in bytes) to beginning of second executable's header ( = 134481 dec)
0x28 17 13 02 00 Length (in bytes) of first executable ( = 135959 dec)
0x3B 00 00 00 00 Unknown (end of record?)

Note that the "Unknown" fields are the same between both files - only the offset and length fields have changed.


PE Sections

If the AppleTV boot.efi is split according to the information in the proprietary header, the result is two valid and distinct PE files. Interestingly, the seldom-used checksum field in the "Optional Header" is filled in here (see Section 3.4.2 of the PE/COFF spec above). Combined with the fact that a single-byte change to a safe region of the file (ie, a string resource) is enough to keep the AppleTV from booting successfully, this suggests that the firmware is validating the checksum before beginning execution.

These checksums are not calculated in the usual manner. Microsoft keeps the actual algorithm used for calculating the checksum a secret, but they make a library for calculating the checksum of a PE image available, which produces the following results:

PE Section File Checksum Calculated MS Checksum
1 0xF59B0200 0x000262C5
2 0xCAAD0200 0x0002DD57

The checksum values from the OS X 10.4.8 PE sections are not included here, but are similarly incorrect.

None of the freely available EFI executables (elilo, refit, Intel reference shell implementation, etc) have a checksum value specified at all, although this knowledge is basically useless without knowing the method for calculating the proper checksum.

Experimentation

Experiment Result
Modify the file by shifting both PE sections 4 bytes forward, update prop. header Boots successfully
Build a boot.efi with two copies of the first PE section, update prop. header Fails to boot - question-mark icon
Build a boot.efi with two copies of the second PE section, update prop. header Fails to boot - question-mark icon
Build a boot.efi with the first and second PE sections swapped, update prop. header Fails to boot - question-mark icon
Extract first PE section, rename to boot.efi Fails to boot - question-mark icon
Extract second PE section, rename to boot.efi Fails to boot - question-mark icon

The results of the first experiment are a pleasant surprise, since they indicate that the firmware doesn't validate the entire boot.efi file - only the PE sections contained within. This suggests that if the proper checksum algorithm is discovered, booting a custom EFI image should be within reach.