Skip to content

Commit 5147249

Browse files
committed
Implement EFI resolver as a module workflow
1 parent f7e831a commit 5147249

File tree

18 files changed

+115
-180
lines changed

18 files changed

+115
-180
lines changed

platform/efi/efi_resolver/LICENSE

Lines changed: 0 additions & 13 deletions
This file was deleted.

platform/efi/efi_resolver/src/Plugin.cpp

Lines changed: 0 additions & 65 deletions
This file was deleted.

platform/efi/platform_efi.cpp

Lines changed: 19 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ class EFIX86Platform : public Platform
2020
Ref<CallingConvention> cc;
2121

2222
m_idtr = arch->GetRegisterByName("idtr");
23-
2423
cc = arch->GetCallingConventionByName("cdecl");
2524
if (cc)
2625
{
@@ -58,19 +57,7 @@ class EFIX86Platform : public Platform
5857

5958
virtual void BinaryViewInit(BinaryView* view) override
6059
{
61-
if (!m_idtrtype)
62-
m_idtrtype = Type::NamedType(QualifiedName("IDTR32"), GetTypeByName(QualifiedName("IDTR32")));
63-
64-
auto ctx = PluginCommandContext();
65-
ctx.binaryView = view;
66-
auto commandList = PluginCommand::GetValidList(ctx);
67-
for (auto command : commandList)
68-
{
69-
if (command.GetName() == "EFI Resolver\\Resolve EFI Types And Protocols")
70-
{
71-
command.Execute(ctx);
72-
}
73-
}
60+
m_idtrtype = Type::NamedType(QualifiedName("IDTR32"), GetTypeByName(QualifiedName("IDTR32")));
7461
}
7562

7663
virtual Ref<Type> GetGlobalRegisterType(uint32_t reg) override
@@ -95,7 +82,6 @@ class EFIX86WindowsPlatform : public Platform
9582
Ref<CallingConvention> cc;
9683

9784
m_idtr = arch->GetRegisterByName("idtr");
98-
9985
cc = arch->GetCallingConventionByName("cdecl");
10086
if (cc)
10187
{
@@ -133,19 +119,7 @@ class EFIX86WindowsPlatform : public Platform
133119

134120
virtual void BinaryViewInit(BinaryView* view) override
135121
{
136-
if (!m_idtrtype)
137-
m_idtrtype = Type::NamedType(QualifiedName("IDTR32"), GetTypeByName(QualifiedName("IDTR32")));
138-
139-
auto ctx = PluginCommandContext();
140-
ctx.binaryView = view;
141-
auto commandList = PluginCommand::GetValidList(ctx);
142-
for (auto command : commandList)
143-
{
144-
if (command.GetName() == "EFI Resolver\\Resolve EFI Types And Protocols")
145-
{
146-
command.Execute(ctx);
147-
}
148-
}
122+
m_idtrtype = Type::NamedType(QualifiedName("IDTR32"), GetTypeByName(QualifiedName("IDTR32")));
149123
}
150124

151125
virtual Ref<Type> GetGlobalRegisterType(uint32_t reg) override
@@ -191,19 +165,7 @@ class EFIX64Platform : public Platform
191165

192166
virtual void BinaryViewInit(BinaryView* view) override
193167
{
194-
if (!m_idtrtype)
195-
m_idtrtype = Type::NamedType(QualifiedName("IDTR64"), GetTypeByName(QualifiedName("IDTR64")));
196-
197-
auto ctx = PluginCommandContext();
198-
ctx.binaryView = view;
199-
auto commandList = PluginCommand::GetValidList(ctx);
200-
for (auto command : commandList)
201-
{
202-
if (command.GetName() == "EFI Resolver\\Resolve EFI Types And Protocols")
203-
{
204-
command.Execute(ctx);
205-
}
206-
}
168+
m_idtrtype = Type::NamedType(QualifiedName("IDTR64"), GetTypeByName(QualifiedName("IDTR64")));
207169
}
208170

209171
virtual Ref<Type> GetGlobalRegisterType(uint32_t reg) override
@@ -249,19 +211,7 @@ class EFIX64WindowsPlatform : public Platform
249211

250212
virtual void BinaryViewInit(BinaryView* view) override
251213
{
252-
if (!m_idtrtype)
253-
m_idtrtype = Type::NamedType(QualifiedName("IDTR64"), GetTypeByName(QualifiedName("IDTR64")));
254-
255-
auto ctx = PluginCommandContext();
256-
ctx.binaryView = view;
257-
auto commandList = PluginCommand::GetValidList(ctx);
258-
for (auto command : commandList)
259-
{
260-
if (command.GetName() == "EFI Resolver\\Resolve EFI Types And Protocols")
261-
{
262-
command.Execute(ctx);
263-
}
264-
}
214+
m_idtrtype = Type::NamedType(QualifiedName("IDTR64"), GetTypeByName(QualifiedName("IDTR64")));
265215
}
266216

267217
virtual Ref<Type> GetGlobalRegisterType(uint32_t reg) override
@@ -324,26 +274,6 @@ class EFIArm64Platform : public Platform
324274
}
325275
}
326276

327-
virtual void BinaryViewInit(BinaryView* view) override
328-
{
329-
if (!m_tpidrel0type)
330-
m_tpidrel0type = Type::NamedType(QualifiedName("EFI_PEI_SERVICES"),
331-
Type::PointerType(view->GetDefaultArchitecture(),
332-
Type::PointerType(
333-
view->GetDefaultArchitecture(), GetTypeByName(QualifiedName("EFI_PEI_SERVICES")))));
334-
335-
auto ctx = PluginCommandContext();
336-
ctx.binaryView = view;
337-
auto commandList = PluginCommand::GetValidList(ctx);
338-
for (auto command : commandList)
339-
{
340-
if (command.GetName() == "EFI Resolver\\Resolve EFI Types And Protocols")
341-
{
342-
command.Execute(ctx);
343-
}
344-
}
345-
}
346-
347277
static Ref<Platform> Recognize(BinaryView* view, Metadata* metadata)
348278
{
349279
Ref<Metadata> subsystem = metadata->Get("Subsystem");
@@ -354,6 +284,13 @@ class EFIArm64Platform : public Platform
354284
return nullptr;
355285
}
356286

287+
virtual void BinaryViewInit(BinaryView* view) override
288+
{
289+
m_tpidrel0type = Type::NamedType(QualifiedName("EFI_PEI_SERVICES"),
290+
Type::PointerType(GetArchitecture(),
291+
Type::PointerType(GetArchitecture(), GetTypeByName(QualifiedName("EFI_PEI_SERVICES")))));
292+
}
293+
357294
virtual Ref<Type> GetGlobalRegisterType(uint32_t reg) override
358295
{
359296
if (reg == m_tpidrel0)
@@ -384,26 +321,6 @@ class EFIArm64WindowsPlatform : public Platform
384321
}
385322
}
386323

387-
virtual void BinaryViewInit(BinaryView* view) override
388-
{
389-
if (!m_tpidrel0type)
390-
m_tpidrel0type = Type::NamedType(QualifiedName("EFI_PEI_SERVICES"),
391-
Type::PointerType(view->GetDefaultArchitecture(),
392-
Type::PointerType(
393-
view->GetDefaultArchitecture(), GetTypeByName(QualifiedName("EFI_PEI_SERVICES")))));
394-
395-
auto ctx = PluginCommandContext();
396-
ctx.binaryView = view;
397-
auto commandList = PluginCommand::GetValidList(ctx);
398-
for (auto command : commandList)
399-
{
400-
if (command.GetName() == "EFI Resolver\\Resolve EFI Types And Protocols")
401-
{
402-
command.Execute(ctx);
403-
}
404-
}
405-
}
406-
407324
static Ref<Platform> Recognize(BinaryView* view, Metadata* metadata)
408325
{
409326
Ref<Metadata> subsystem = metadata->Get("Subsystem");
@@ -414,6 +331,14 @@ class EFIArm64WindowsPlatform : public Platform
414331
return nullptr;
415332
}
416333

334+
virtual void BinaryViewInit(BinaryView* view) override
335+
{
336+
m_tpidrel0type = Type::NamedType(QualifiedName("EFI_PEI_SERVICES"),
337+
Type::PointerType(GetArchitecture(),
338+
Type::PointerType(
339+
GetArchitecture(), GetTypeByName(QualifiedName("EFI_PEI_SERVICES")))));
340+
}
341+
417342
virtual Ref<Type> GetGlobalRegisterType(uint32_t reg) override
418343
{
419344
if (reg == m_tpidrel0)
Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,25 @@ Author: **Vector 35 Inc**
33

44
_A Binary Ninja built-in plugin that automatically resolves type information for EFI protocol usage._
55

6-
This repository contains C++ version of EFI Resolver, which is bundled with Binary Ninja. For the original Python
7-
version, please refer to https://github.com/vector35/efi-resolver/tree/main
8-
96
## Description:
107

11-
EFI Resolver is a Binary Ninja plugin that automates the task of resolving EFI protocol type information. It supports both DXE files and PEI files. It propagates parameter pointers from entry points to system table, MM system table, boot services, and runtime services to any global variables where they are stored. For PEI files, it also supports identifying [processor-specific mechanisms](https://uefi.org/specs/PI/1.8/V1_PEI_Foundation.html#pei-services-table-retrieval) for retrieving PEI services pointers. The plugin also identifies references to the boot services, MM protocol functions and PEI services, and applies type information according to the GUID passed to these functions. The plugin supports the core UEFI specification, and allows users to provide custom vendor protocols.
8+
EFI Resolver is a Binary Ninja plugin that automates the resolution of EFI protocol type information. It supports both
9+
DXE files and PEI modules. The plugin propagates parameter pointers from entry points to system tables, including the
10+
main system table, MM system table, boot services, and runtime services, assigning types to global variables.
11+
12+
For PEI files, EFI Resolver can also detect
13+
[processor-specific patterns](https://uefi.org/specs/PI/1.8/V1_PEI_Foundation.html#pei-services-table-retrieval)
14+
used to retrieve PEI services pointers.
15+
16+
Additionally, the plugin identifies references to boot services, MM protocol functions, and PEI services. It applies
17+
type information based on the GUIDs passed to these functions.
18+
19+
EFI Resolver supports the core UEFI specification and allows users to define custom vendor protocols.
1220

1321
## Build Instructions
1422

1523
```bash
16-
git clone https://github.com/Vector35/binaryninja-api.git
17-
git clone https://github.com/Vector35/efi-resolver.git && cd efi-resolver
24+
git clone https://github.com/Vector35/binaryninja-api.git && cd binaryninja-api/plugins/efi_resolver
1825
export BN_API_PATH=../binaryninja-api # Or specifying the path to api repo
1926
cmake -S . -B build -GNinja
2027
cmake --build build -t install
@@ -26,7 +33,7 @@ This plugin is released under an Apache-2.0 license.
2633

2734
## Supplying Custom UEFI Protocol GUIDs and Types
2835

29-
By default, EFI Resolver propagates types and GUIDs using Binary Ninja's native platform types for EFI. Many UEFI
36+
EFI Resolver propagates types and GUIDs using Binary Ninja's native platform types for EFI. Many UEFI
3037
firmware binaries include types (and GUIDs) for proprietary protocols. This section describes how users can supply
3138
custom UEFI types and GUIDs for use with EFI Resolver type propagation.
3239

@@ -125,4 +132,4 @@ struct EFI_EXAMPLE_CUSTOM_PROTOCOL
125132

126133
After a Binary Ninja restart, when a binary is loaded with the `efi-x86` platform, the `EFI_EXAMPLE_CUSTOM_PROTOCOL`
127134
type will be imported. When EFI Resolver runs, it will detect uses of `EFI_EXAMPLE_CUSTOM_PROTOCOL_GUID` and propagate
128-
the `EFI_EXAMPLE_CUSTOM_PROTOCOL` type.
135+
the `EFI_EXAMPLE_CUSTOM_PROTOCOL` type.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)