|
| 1 | +# EFI Resolver |
| 2 | + |
| 3 | +EFI Resolver is a Binary Ninja workflow that automates the resolution of type information for EFI (Extensible Firmware |
| 4 | +Interface) protocol usage in UEFI binaries. It supports Terse Executable (TE) and Portable Executable (PE) formatted |
| 5 | +EFI binaries such as PEI, DXE, and SMM modules. |
| 6 | + |
| 7 | + |
| 8 | + |
| 9 | +## Key Features |
| 10 | + |
| 11 | +* **Automatic Type Propagation** – propagates EFI types from the module entry point to callee functions and global data |
| 12 | + variables |
| 13 | +* **EFI Protocol Interface Detection** – identifies EFI DXE, SMM, and PPI protocol interfaces by analyzing calls to EFI |
| 14 | + services methods (`InstallProtocolInterface`, `LocateProtocol`, etc.), queries known EFI types by GUID, and applies |
| 15 | + types to interface pointers |
| 16 | +* **PEI Services Table Recovery** – identifies architecture-specific code patterns (described in the |
| 17 | + [UEFI PI Specification](https://uefi.org/specs/PI/1.8/V1_PEI_Foundation.html#pei-services-table-retrieval)) for |
| 18 | + resolving the address of the PEI services table |
| 19 | +* **User-defined / Proprietary EFI Protocol Support** – allows users to create custom EFI types and associate them with |
| 20 | + an EFI GUID to be included during automated analysis |
| 21 | + |
| 22 | +## Re-running the Workflow |
| 23 | + |
| 24 | +EFI Resolver registers a plugin command that allows for re-running the EFI Resolver workflow after the binary view has |
| 25 | +been finalized. This can be valuable when manually applying new types or when creating new types for proprietary EFI |
| 26 | +protocol interfaces. To re-run EFI Resolver, click `Plugins -> Run EFI Resolver`. |
| 27 | + |
| 28 | +## User-defined EFI Protocol GUIDs and Types |
| 29 | + |
| 30 | +Binary Ninja bundles EFI platform type definitions for the majority of the types in the UEFI specification. However, |
| 31 | +many UEFI firmware vendors implement proprietary interfaces. EFI Resolver allows users to extend its capabilities by |
| 32 | +supplying custom GUIDs and associated type definitions for proprietary protocols. This can be achieved in the following |
| 33 | +steps: |
| 34 | + |
| 35 | +1. Create a JSON file named `efi-guids.json` in the `types` directory of your [user folder](index.md#user-folder) |
| 36 | + * macOS: `~/Library/Application Support/Binary Ninja/types/efi-guids.json` |
| 37 | + * Linux: `~/.binaryninja/types/efi-guids.json` |
| 38 | + * Windows: `%APPDATA%\Binary Ninja\types` |
| 39 | + |
| 40 | + ???+ Important "GUID Database" |
| 41 | + An excellent source of proprietary EFI GUIDs is Binarly's |
| 42 | + [GUID DB](https://github.com/binarly-io/guiddb/blob/main/guids.json). This file is in the expected format for |
| 43 | + EFI Resolver's `efi-guids.json`, and can be copied directly to your user folder as a starting point. |
| 44 | + |
| 45 | +2. Define a GUID in the following format: |
| 46 | + |
| 47 | + ``` |
| 48 | + { |
| 49 | + "EFI_EXAMPLE_CUSTOM_PROTOCOL_GUID": [ |
| 50 | + 19088743, 35243, 52719, |
| 51 | + 1, 35, 69, 103, 137, 171, 205, 239 |
| 52 | + ] |
| 53 | + } |
| 54 | + ``` |
| 55 | +
|
| 56 | +3. Create a type named `EFI_EXAMPLE_CUSTOM_PROTOCOL` using the types widget |
| 57 | +
|
| 58 | + ???+ Important "Unassociated EFI Types" |
| 59 | + If there is not a type for a GUID defined in `efi-guids.json`, EFI Resolver will still use the GUID name to name |
| 60 | + the protocol interface and GUID data variables. |
| 61 | +
|
| 62 | +4. Re-run the workflow |
| 63 | +
|
| 64 | +In this example, the workflow will apply the `EFI_EXAMPLE_CUSTOM_PROTOCOL` type to identified protocol interfaces that |
| 65 | +were queried in the binary via the `EFI_EXAMPLE_CUSTOM_PROTOCOL_GUID` EFI GUID. |
| 66 | +
|
| 67 | +???+ Important "Platform Types" |
| 68 | + To make a custom EFI protocol type accessible when loading future EFI binaries, it is recommended to add the type to |
| 69 | + [platform types](types/platformtypes.md) |
0 commit comments