Skip to content
This repository was archived by the owner on Aug 4, 2025. It is now read-only.

Commit 922614d

Browse files
committed
Setting EFI module entry function for module type
TE's use PEI module entry point type and PE's use DXE module entry point type
1 parent 6b84e8d commit 922614d

File tree

2 files changed

+87
-22
lines changed

2 files changed

+87
-22
lines changed

__init__.py

Lines changed: 41 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from binaryninja import PluginCommand, BinaryView, BackgroundTaskThread, log_alert
2+
from .moduletype import identify_efi_module_type, set_efi_module_entry_type, EFIModuleType
23
from .protocols import (
34
init_protocol_mapping,
45
define_handle_protocol_types,
@@ -20,34 +21,26 @@ def __init__(self, bv: BinaryView):
2021
super().__init__("Initializing EFI protocol mappings...", True)
2122
self.bv = bv
2223

23-
def run(self):
24-
if not init_protocol_mapping():
24+
def _resolve_dxe(self):
25+
self.progress = "Propagating EFI system table pointers..."
26+
if not propagate_system_table_pointers(self.bv, self):
2527
return
2628

27-
if "EFI_SYSTEM_TABLE" not in self.bv.types:
28-
log_alert("This binary is not using the EFI platform. Use Open with Options when loading the binary to select the EFI platform.")
29+
self.progress = "Defining types for uses of HandleProtocol..."
30+
if not define_handle_protocol_types(self.bv, self):
2931
return
3032

31-
self.bv.begin_undo_actions()
32-
try:
33-
self.progress = "Propagating EFI system table pointers..."
34-
if not propagate_system_table_pointers(self.bv, self):
35-
return
36-
37-
self.progress = "Defining types for uses of HandleProtocol..."
38-
if not define_handle_protocol_types(self.bv, self):
39-
return
40-
41-
self.progress = "Defining types for uses of OpenProtocol..."
42-
if not define_open_protocol_types(self.bv, self):
43-
return
33+
self.progress = "Defining types for uses of OpenProtocol..."
34+
if not define_open_protocol_types(self.bv, self):
35+
return
4436

45-
self.progress = "Defining types for uses of LocateProtocol..."
46-
if not define_locate_protocol_types(self.bv, self):
47-
return
37+
self.progress = "Defining types for uses of LocateProtocol..."
38+
if not define_locate_protocol_types(self.bv, self):
39+
return
4840

49-
# SMM/MM types cannot be propagated until EFI_BOOT_SERVICES types are propagated and the
50-
# EFI_MM_BASE_PROTOCOL or EFI_SMM_BASE2_PROTOCOL is resolved
41+
# SMM/MM types cannot be propagated until EFI_BOOT_SERVICES types are propagated and the
42+
# EFI_MM_BASE_PROTOCOL or EFI_SMM_BASE2_PROTOCOL is resolved
43+
if "EFI_MM_SYSTEM_TABLE" in self.bv.types:
5144
self.progress = "Defining types for SMM/MM system tables..."
5245
if not define_locate_mm_system_table_types(self.bv, self) or not define_locate_smm_system_table_types(
5346
self.bv, self
@@ -65,6 +58,32 @@ def run(self):
6558
self.bv, self
6659
):
6760
return
61+
62+
def run(self):
63+
if not init_protocol_mapping():
64+
return
65+
66+
if "EFI_SYSTEM_TABLE" not in self.bv.types:
67+
log_alert("This binary is not using the EFI platform. Use Open with Options when loading the binary to select the EFI platform.")
68+
return
69+
70+
module_type = identify_efi_module_type(self.bv)
71+
if module_type == EFIModuleType.UNKNOWN:
72+
log_alert("Could not identify the EFI module type.")
73+
return
74+
75+
self.bv.begin_undo_actions()
76+
try:
77+
try:
78+
set_efi_module_entry_type(self.bv, module_type)
79+
except SyntaxError:
80+
log_alert("Failed to set entry function type. Update Binary Ninja for latest EFI type definitions.")
81+
return
82+
83+
if module_type == EFIModuleType.DXE:
84+
self._resolve_dxe()
85+
elif module_type == EFIModuleType.PEI:
86+
log_alert("TE PEI modules are not yet supported.")
6887
finally:
6988
self.bv.commit_undo_actions()
7089

moduletype.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
from enum import Enum
2+
from binaryninja import BinaryView, SymbolType
3+
4+
5+
class EFIModuleType(Enum):
6+
"""UEFI module types"""
7+
8+
UNKNOWN = 0
9+
DXE = 1
10+
PEI = 2
11+
12+
13+
def set_efi_module_entry_type(bv: BinaryView, modtype: EFIModuleType) -> None:
14+
"""Set the prototype for the module entrypoint"""
15+
16+
_start = bv.get_symbol_by_raw_name("_start")
17+
if not _start or _start.type != SymbolType.FunctionSymbol:
18+
return
19+
20+
func = bv.get_function_at(_start.address)
21+
if not func:
22+
return
23+
24+
if modtype == EFIModuleType.PEI:
25+
func.type = "EFI_STATUS _start(EFI_PEI_FILE_HANDLE FileHandle, EFI_PEI_SERVICES **PeiServices)"
26+
27+
if modtype == EFIModuleType.DXE:
28+
func.type = "EFI_STATUS _start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE* SystemTable)"
29+
30+
func.reanalyze()
31+
32+
33+
def identify_efi_module_type(bv: BinaryView) -> EFIModuleType:
34+
"""Identify the type of EFI module
35+
36+
PE's are reported as DXE modules and TE's are reported as PEI modules. This is correct for most
37+
cases, and is the convention used by most UEFI tooling.
38+
"""
39+
40+
if bv.get_view_of_type("PE"):
41+
return EFIModuleType.DXE
42+
43+
if bv.get_view_of_type("TE"):
44+
return EFIModuleType.PEI
45+
46+
return EFIModuleType.UNKNOWN

0 commit comments

Comments
 (0)