From 2323afe3d7907438edbd1c18cdf06110b7f3eef2 Mon Sep 17 00:00:00 2001 From: Michael Krasnitski Date: Tue, 19 Aug 2025 11:43:14 -0400 Subject: [PATCH] Add basic linux-ilp32 platform support --- platform/linux/platform_linux.cpp | 64 ++++++++++++++++++++++++++++--- 1 file changed, 59 insertions(+), 5 deletions(-) diff --git a/platform/linux/platform_linux.cpp b/platform/linux/platform_linux.cpp index 5143432396..1dcc769c08 100644 --- a/platform/linux/platform_linux.cpp +++ b/platform/linux/platform_linux.cpp @@ -4,7 +4,9 @@ using namespace BinaryNinja; using namespace std; Ref g_linuxX32; +Ref g_linuxIlp32; #define EM_X86_64 62 // AMD x86-64 architecture +#define EM_AARCH64 183 // ARM64 architecture class LinuxX86Platform: public Platform { @@ -199,6 +201,50 @@ class LinuxArm64Platform: public Platform } }; +class LinuxIlp32Platform: public Platform +{ + public: + LinuxIlp32Platform(Architecture* arch): Platform(arch, "linux-ilp32") + { + Ref cc; + + cc = arch->GetCallingConventionByName("cdecl"); + if (cc) + { + RegisterDefaultCallingConvention(cc); + RegisterCdeclCallingConvention(cc); + RegisterFastcallCallingConvention(cc); + RegisterStdcallCallingConvention(cc); + } + + cc = arch->GetCallingConventionByName("linux-syscall"); + if (cc) + SetSystemCallConvention(cc); + } + + virtual size_t GetAddressSize() const override + { + return 4; + } + + static Ref Recognize(BinaryView* view, Metadata* metadata) + { + Ref fileClass = metadata->Get("EI_CLASS"); + + if (!fileClass || !fileClass->IsUnsignedInteger()) + return nullptr; + + Ref machine = metadata->Get("e_machine"); + if (!machine || !machine->IsUnsignedInteger()) + return nullptr; + + if (fileClass->GetUnsignedInteger() == 1 && machine->GetUnsignedInteger() == EM_AARCH64) + return g_linuxIlp32; + + return nullptr; + } +}; + class LinuxMipsPlatform: public Platform { @@ -406,13 +452,21 @@ extern "C" Ref arm64 = Architecture::GetByName("aarch64"); if (arm64) { - Ref platform; + Ref arm64_platform = new LinuxArm64Platform(arm64); + g_linuxIlp32 = new LinuxIlp32Platform(arm64); + + Platform::Register("linux", arm64_platform); + Platform::Register("linux", g_linuxIlp32); - platform = new LinuxArm64Platform(arm64); - Platform::Register("linux", platform); // Linux binaries sometimes have an OS identifier of zero, even though 3 is the correct one - BinaryViewType::RegisterPlatform("ELF", 0, platform); - BinaryViewType::RegisterPlatform("ELF", 3, platform); + BinaryViewType::RegisterPlatform("ELF", 0, arm64_platform); + BinaryViewType::RegisterPlatform("ELF", 3, arm64_platform); + + Ref elf = BinaryViewType::GetByName("ELF"); + if (elf) { + elf->RegisterPlatformRecognizer(EM_AARCH64, LittleEndian, LinuxIlp32Platform::Recognize); + elf->RegisterPlatformRecognizer(EM_AARCH64, BigEndian, LinuxIlp32Platform::Recognize); + } } Ref ppc = Architecture::GetByName("ppc");