diff options
| author | Rusty Wagner <rusty.wagner@gmail.com> | 2023-06-14 15:51:09 -0400 |
|---|---|---|
| committer | Rusty Wagner <rusty.wagner@gmail.com> | 2023-06-14 15:53:36 -0400 |
| commit | 7b4d183be90a2570c13abc5a0d3655c542854f35 (patch) | |
| tree | a52367e1366d09e282080a5e6855ff339e0e3bd7 /platform | |
| parent | 49b90e2334a5532ed1c98ae99a07b0438c407be4 (diff) | |
Support IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION PE subsystem with EFI types
Diffstat (limited to 'platform')
| -rw-r--r-- | platform/efi/platform_efi.cpp | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/platform/efi/platform_efi.cpp b/platform/efi/platform_efi.cpp index bc5dc208..4a1763ef 100644 --- a/platform/efi/platform_efi.cpp +++ b/platform/efi/platform_efi.cpp @@ -6,6 +6,7 @@ using namespace std; Ref<Platform> g_efiX86, g_efiX64, g_efiArm, g_efiThumb, g_efiArm64; +Ref<Platform> g_efiX86Windows, g_efiX64Windows, g_efiArm64Windows; class EFIX86Platform : public Platform @@ -52,6 +53,50 @@ public: }; +class EFIX86WindowsPlatform : public Platform +{ +public: + EFIX86WindowsPlatform(Architecture* arch) : Platform(arch, "efi-windows-x86") + { + Ref<CallingConvention> cc; + + cc = arch->GetCallingConventionByName("cdecl"); + if (cc) + { + RegisterDefaultCallingConvention(cc); + RegisterCdeclCallingConvention(cc); + } + + cc = arch->GetCallingConventionByName("fastcall"); + if (cc) + RegisterFastcallCallingConvention(cc); + + cc = arch->GetCallingConventionByName("stdcall"); + if (cc) + RegisterStdcallCallingConvention(cc); + + cc = arch->GetCallingConventionByName("thiscall"); + if (cc) + RegisterCallingConvention(cc); + + // Linux-style register convention is commonly used by Borland compilers + cc = arch->GetCallingConventionByName("regparm"); + if (cc) + RegisterCallingConvention(cc); + } + + static Ref<Platform> Recognize(BinaryView* view, Metadata* metadata) + { + Ref<Metadata> subsystem = metadata->Get("Subsystem"); + if (!subsystem || !subsystem->IsUnsignedInteger()) + return nullptr; + if (subsystem->GetUnsignedInteger() == 0x10) // IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION + return g_efiX86Windows; + return nullptr; + } +}; + + class EFIX64Platform : public Platform { public: @@ -85,6 +130,39 @@ public: }; +class EFIX64WindowsPlatform : public Platform +{ +public: + EFIX64WindowsPlatform(Architecture* arch) : Platform(arch, "efi-windows-x86_64") + { + Ref<CallingConvention> cc; + + cc = arch->GetCallingConventionByName("win64"); + if (cc) + { + RegisterDefaultCallingConvention(cc); + RegisterCdeclCallingConvention(cc); + RegisterFastcallCallingConvention(cc); + RegisterStdcallCallingConvention(cc); + } + + // Linux-style calling convention is sometimes used internally by EFI applications + cc = arch->GetCallingConventionByName("sysv"); + RegisterCallingConvention(cc); + } + + static Ref<Platform> Recognize(BinaryView* view, Metadata* metadata) + { + Ref<Metadata> subsystem = metadata->Get("Subsystem"); + if (!subsystem || !subsystem->IsUnsignedInteger()) + return nullptr; + if (subsystem->GetUnsignedInteger() == 0x10) // IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION + return g_efiX64Windows; + return nullptr; + } +}; + + class EFIArmv7Platform : public Platform { public: @@ -143,6 +221,35 @@ public: }; +class EFIArm64WindowsPlatform : public Platform +{ +public: + EFIArm64WindowsPlatform(Architecture* arch) : Platform(arch, "efi-windows-aarch64") + { + Ref<CallingConvention> cc; + + cc = arch->GetCallingConventionByName("cdecl"); + if (cc) + { + RegisterDefaultCallingConvention(cc); + RegisterCdeclCallingConvention(cc); + RegisterFastcallCallingConvention(cc); + RegisterStdcallCallingConvention(cc); + } + } + + static Ref<Platform> Recognize(BinaryView* view, Metadata* metadata) + { + Ref<Metadata> subsystem = metadata->Get("Subsystem"); + if (!subsystem || !subsystem->IsUnsignedInteger()) + return nullptr; + if (subsystem->GetUnsignedInteger() == 0x10) // IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION + return g_efiArm64Windows; + return nullptr; + } +}; + + extern "C" { BN_DECLARE_CORE_ABI_VERSION @@ -172,6 +279,10 @@ extern "C" g_efiX86 = new EFIX86Platform(x86); Platform::Register("efi", g_efiX86); pe->RegisterPlatformRecognizer(0x14c, LittleEndian, EFIX86Platform::Recognize); + + g_efiX86Windows = new EFIX86WindowsPlatform(x86); + Platform::Register("efi", g_efiX86Windows); + pe->RegisterPlatformRecognizer(0x14c, LittleEndian, EFIX86WindowsPlatform::Recognize); } Ref<Architecture> x64 = Architecture::GetByName("x86_64"); @@ -180,6 +291,10 @@ extern "C" g_efiX64 = new EFIX64Platform(x64); Platform::Register("efi", g_efiX64); pe->RegisterPlatformRecognizer(0x8664, LittleEndian, EFIX64Platform::Recognize); + + g_efiX64Windows = new EFIX64WindowsPlatform(x64); + Platform::Register("efi", g_efiX64Windows); + pe->RegisterPlatformRecognizer(0x8664, LittleEndian, EFIX64WindowsPlatform::Recognize); } Ref<Architecture> armv7 = Architecture::GetByName("armv7"); @@ -203,6 +318,10 @@ extern "C" g_efiArm64 = new EFIArm64Platform(arm64); Platform::Register("efi", g_efiArm64); pe->RegisterPlatformRecognizer(0xaa64, LittleEndian, EFIArm64Platform::Recognize); + + g_efiArm64Windows = new EFIArm64WindowsPlatform(arm64); + Platform::Register("efi", g_efiArm64Windows); + pe->RegisterPlatformRecognizer(0xaa64, LittleEndian, EFIArm64WindowsPlatform::Recognize); } } |
