Skip to content

Commit 0c4f237

Browse files
committed
Implement EFI resolver as a module workflow
1 parent 4310f90 commit 0c4f237

File tree

2 files changed

+46
-131
lines changed

2 files changed

+46
-131
lines changed

platform/efi/efi_resolver/src/Plugin.cpp

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,17 @@
55

66
using namespace BinaryNinja;
77

8-
extern "C"
9-
{
10-
BN_DECLARE_CORE_ABI_VERSION
11-
12-
BINARYNINJAPLUGIN void CorePluginDependencies()
13-
{
14-
BinaryNinja::AddOptionalPluginDependency("arch_x86");
15-
BinaryNinja::AddOptionalPluginDependency("arch_armv7");
16-
BinaryNinja::AddOptionalPluginDependency("arch_arm64");
17-
BinaryNinja::AddOptionalPluginDependency("platform_efi");
18-
}
19-
208
static Ref<BackgroundTask> efiBackgroundTask = nullptr;
21-
22-
void Run(Ref<BinaryView> view)
9+
void EFIResolverWorkflow(const Ref<AnalysisContext>& analysisContext)
2310
{
11+
auto view = analysisContext->GetBinaryView();
12+
auto platform = view->GetDefaultPlatform();
13+
if (!platform || platform->GetName().find("efi") == std::string::npos)
14+
return;
15+
2416
efiBackgroundTask = new BackgroundTask("Loading EFI protocol mappings!", true);
2517
thread resolverThread([view]() {
26-
LogInfo("Entering new thread");
27-
28-
LogInfo("Identifying module type");
18+
LogInfo("Identifying EFI module type...");
2919
EFIModuleType moduleType = identifyModuleType(view);
3020

3121
#ifndef DEBUG
@@ -45,7 +35,6 @@ void Run(Ref<BinaryView> view)
4535
efiBackgroundTask->SetProgressText("Resolving MM related protocols...");
4636
resolver.resolveSmm();
4737
}
48-
4938
#ifndef DEBUG
5039
view->CommitUndoActions(undo);
5140
#endif
@@ -54,12 +43,34 @@ void Run(Ref<BinaryView> view)
5443
resolverThread.detach();
5544
}
5645

57-
BINARYNINJAPLUGIN bool CorePluginInit()
46+
extern "C"
5847
{
59-
EfiGuidRenderer::Register();
48+
BN_DECLARE_CORE_ABI_VERSION
49+
BINARYNINJAPLUGIN void CorePluginDependencies()
50+
{
51+
BinaryNinja::AddOptionalPluginDependency("arch_x86");
52+
BinaryNinja::AddOptionalPluginDependency("arch_armv7");
53+
BinaryNinja::AddOptionalPluginDependency("arch_arm64");
54+
BinaryNinja::AddOptionalPluginDependency("platform_efi");
55+
}
6056

61-
PluginCommand::Register("EFI Resolver\\Resolve EFI Types And Protocols", "Resolve EFI Protocols", &Run);
57+
BINARYNINJAPLUGIN bool CorePluginInit()
58+
{
59+
EfiGuidRenderer::Register();
60+
auto workflow = Workflow::Instance("core.module.metaAnalysis")->Clone();
61+
workflow->RegisterActivity(R"~({
62+
"title": "EFI Resolver",
63+
"name": "analysis.efi.efiResolver",
64+
"role": "action",
65+
"description": "This analysis step resolves EFI protocol interfaces and propagates type information.",
66+
"eligibility": {
67+
"runOnce": true,
68+
"auto": {}
69+
}
70+
})~", &EFIResolverWorkflow);
6271

63-
return true;
64-
}
72+
workflow->InsertAfter("core.module.extendedAnalysis", "analysis.efi.efiResolver");
73+
Workflow::RegisterWorkflow(workflow);
74+
return true;
75+
}
6576
}

platform/efi/platform_efi.cpp

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

2222
m_idtr = arch->GetRegisterByName("idtr");
23+
m_idtrtype = Type::NamedType(QualifiedName("IDTR32"), GetTypeByName(QualifiedName("IDTR32")));
2324

2425
cc = arch->GetCallingConventionByName("cdecl");
2526
if (cc)
@@ -56,23 +57,6 @@ class EFIX86Platform : public Platform
5657
return nullptr;
5758
}
5859

59-
virtual void BinaryViewInit(BinaryView* view) override
60-
{
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-
}
74-
}
75-
7660
virtual Ref<Type> GetGlobalRegisterType(uint32_t reg) override
7761
{
7862
if (reg == m_idtr)
@@ -95,6 +79,7 @@ class EFIX86WindowsPlatform : public Platform
9579
Ref<CallingConvention> cc;
9680

9781
m_idtr = arch->GetRegisterByName("idtr");
82+
m_idtrtype = Type::NamedType(QualifiedName("IDTR32"), GetTypeByName(QualifiedName("IDTR32")));
9883

9984
cc = arch->GetCallingConventionByName("cdecl");
10085
if (cc)
@@ -131,23 +116,6 @@ class EFIX86WindowsPlatform : public Platform
131116
return nullptr;
132117
}
133118

134-
virtual void BinaryViewInit(BinaryView* view) override
135-
{
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-
}
149-
}
150-
151119
virtual Ref<Type> GetGlobalRegisterType(uint32_t reg) override
152120
{
153121
if (reg == m_idtr)
@@ -169,6 +137,8 @@ class EFIX64Platform : public Platform
169137
Ref<CallingConvention> cc;
170138

171139
m_idtr = arch->GetRegisterByName("idtr");
140+
m_idtrtype = Type::NamedType(QualifiedName("IDTR64"), GetTypeByName(QualifiedName("IDTR64")));
141+
172142
cc = arch->GetCallingConventionByName("win64");
173143
if (cc)
174144
{
@@ -189,23 +159,6 @@ class EFIX64Platform : public Platform
189159
return nullptr;
190160
}
191161

192-
virtual void BinaryViewInit(BinaryView* view) override
193-
{
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-
}
207-
}
208-
209162
virtual Ref<Type> GetGlobalRegisterType(uint32_t reg) override
210163
{
211164
if (reg == m_idtr)
@@ -227,6 +180,7 @@ class EFIX64WindowsPlatform : public Platform
227180
Ref<CallingConvention> cc;
228181

229182
m_idtr = arch->GetRegisterByName("idtr");
183+
m_idtrtype = Type::NamedType(QualifiedName("IDTR64"), GetTypeByName(QualifiedName("IDTR64")));
230184
cc = arch->GetCallingConventionByName("win64");
231185
if (cc)
232186
{
@@ -247,23 +201,6 @@ class EFIX64WindowsPlatform : public Platform
247201
return nullptr;
248202
}
249203

250-
virtual void BinaryViewInit(BinaryView* view) override
251-
{
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-
}
265-
}
266-
267204
virtual Ref<Type> GetGlobalRegisterType(uint32_t reg) override
268205
{
269206
if (reg == m_idtr)
@@ -314,6 +251,9 @@ class EFIArm64Platform : public Platform
314251
Ref<CallingConvention> cc;
315252

316253
m_tpidrel0 = arch->GetRegisterByName("tpidr_el0");
254+
m_tpidrel0type = Type::NamedType(QualifiedName("EFI_PEI_SERVICES"),
255+
Type::PointerType(GetArchitecture(),
256+
Type::PointerType(GetArchitecture(), GetTypeByName(QualifiedName("EFI_PEI_SERVICES")))));
317257
cc = arch->GetCallingConventionByName("cdecl");
318258
if (cc)
319259
{
@@ -324,26 +264,6 @@ class EFIArm64Platform : public Platform
324264
}
325265
}
326266

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-
347267
static Ref<Platform> Recognize(BinaryView* view, Metadata* metadata)
348268
{
349269
Ref<Metadata> subsystem = metadata->Get("Subsystem");
@@ -374,6 +294,10 @@ class EFIArm64WindowsPlatform : public Platform
374294
Ref<CallingConvention> cc;
375295

376296
m_tpidrel0 = arch->GetRegisterByName("tpidr_el0");
297+
m_tpidrel0type = Type::NamedType(QualifiedName("EFI_PEI_SERVICES"),
298+
Type::PointerType(GetArchitecture(),
299+
Type::PointerType(
300+
GetArchitecture(), GetTypeByName(QualifiedName("EFI_PEI_SERVICES")))));
377301
cc = arch->GetCallingConventionByName("cdecl");
378302
if (cc)
379303
{
@@ -384,26 +308,6 @@ class EFIArm64WindowsPlatform : public Platform
384308
}
385309
}
386310

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-
407311
static Ref<Platform> Recognize(BinaryView* view, Metadata* metadata)
408312
{
409313
Ref<Metadata> subsystem = metadata->Get("Subsystem");

0 commit comments

Comments
 (0)