diff options
| author | Brandon Miller <brandon@vector35.com> | 2025-05-08 15:08:10 -0400 |
|---|---|---|
| committer | Brandon Miller <brandon@vector35.com> | 2025-05-08 15:08:10 -0400 |
| commit | 5147249a644f611a801aada7645b7a993fc8e314 (patch) | |
| tree | 3a18e50df5ae9edcf31f3545a7f27774021c76a1 /plugins/efi_resolver/src/Plugin.cpp | |
| parent | f7e831ab40a5031cec9186096a90d94735080ed7 (diff) | |
Implement EFI resolver as a module workflow
Diffstat (limited to 'plugins/efi_resolver/src/Plugin.cpp')
| -rw-r--r-- | plugins/efi_resolver/src/Plugin.cpp | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/plugins/efi_resolver/src/Plugin.cpp b/plugins/efi_resolver/src/Plugin.cpp new file mode 100644 index 00000000..9d5a69ce --- /dev/null +++ b/plugins/efi_resolver/src/Plugin.cpp @@ -0,0 +1,81 @@ +#include "DxeResolver.h" +#include "PeiResolver.h" +#include "binaryninjaapi.h" +#include <thread> + +using namespace BinaryNinja; + +static Ref<BackgroundTask> m_efiBackgroundTask = nullptr; + +bool IsValid(BinaryView* view) +{ + if (!view) + return false; + + auto platform = view->GetDefaultPlatform(); + return (platform && platform->GetName().find("efi-") != std::string::npos); +} + + +void RunCommand(Ref<BinaryView> view) +{ + m_efiBackgroundTask = new BackgroundTask("Running EFI resolver...", true); + thread resolverThread([view]() { + LogInfo("Identifying EFI module type..."); + EFIModuleType moduleType = identifyModuleType(view); + + auto undo = view->BeginUndoActions(); + if (moduleType == PEI) + { + m_efiBackgroundTask->SetProgressText("Resolving PEIM..."); + auto resolver = PeiResolver(view, m_efiBackgroundTask); + resolver.resolvePei(); + } + else if (moduleType == DXE) + { + m_efiBackgroundTask->SetProgressText("Resolving DXE protocols..."); + auto resolver = DxeResolver(view, m_efiBackgroundTask); + resolver.resolveDxe(); + m_efiBackgroundTask->SetProgressText("Resolving MM related protocols..."); + resolver.resolveSmm(); + } + view->CommitUndoActions(undo); + m_efiBackgroundTask->Finish(); + }); + + resolverThread.detach(); +} + + +void RunWorkflow(const Ref<AnalysisContext>& analysisContext) +{ + auto view = analysisContext->GetBinaryView(); + if (IsValid(view)) + RunCommand(view); +} + + +extern "C" +{ + BN_DECLARE_CORE_ABI_VERSION + BINARYNINJAPLUGIN bool CorePluginInit() + { + EfiGuidRenderer::Register(); + auto workflow = Workflow::Instance("core.module.metaAnalysis")->Clone(); + workflow->RegisterActivity(R"~({ + "title": "EFI Resolver", + "name": "analysis.efi.efiResolver", + "role": "action", + "description": "This analysis step resolves EFI protocol interfaces and propagates type information.", + "eligibility": { + "runOnce": true, + "auto": {} + } + })~", &RunWorkflow); + + workflow->InsertAfter("core.module.extendedAnalysis", "analysis.efi.efiResolver"); + Workflow::RegisterWorkflow(workflow); + PluginCommand::Register("Run EFI Resolver", "Resolve EFI interfaces and types", &RunCommand, &IsValid); + return true; + } +} |
