diff options
| author | Rusty Wagner <rusty.wagner@gmail.com> | 2023-06-13 11:29:42 -0600 |
|---|---|---|
| committer | Rusty Wagner <rusty.wagner@gmail.com> | 2023-06-13 16:46:47 -0400 |
| commit | 52eb0de5dcddaee2b8bd3122512ae4c20e0e9545 (patch) | |
| tree | 8543df055ebc32d32283c0231cbeb6c7fd424533 /platform/linux/platform_linux.cpp | |
| parent | adb7ef55fc4e24f03e6faf353cc9122ee07c714f (diff) | |
Move platform submodules into API
Diffstat (limited to 'platform/linux/platform_linux.cpp')
| -rw-r--r-- | platform/linux/platform_linux.cpp | 305 |
1 files changed, 305 insertions, 0 deletions
diff --git a/platform/linux/platform_linux.cpp b/platform/linux/platform_linux.cpp new file mode 100644 index 00000000..1a4c9d93 --- /dev/null +++ b/platform/linux/platform_linux.cpp @@ -0,0 +1,305 @@ +#include "binaryninjaapi.h" + +using namespace BinaryNinja; +using namespace std; + + +class LinuxX86Platform: public Platform +{ +public: + LinuxX86Platform(Architecture* arch): Platform(arch, "linux-x86") + { + Ref<CallingConvention> cc; + + cc = arch->GetCallingConventionByName("cdecl"); + if (cc) + { + RegisterDefaultCallingConvention(cc); + RegisterCdeclCallingConvention(cc); + } + + cc = arch->GetCallingConventionByName("regparm"); + if (cc) + RegisterCallingConvention(cc); + + cc = arch->GetCallingConventionByName("stdcall"); + if (cc) + RegisterStdcallCallingConvention(cc); + + cc = arch->GetCallingConventionByName("linux-syscall"); + if (cc) + SetSystemCallConvention(cc); + } +}; + +class LinuxPpc32Platform: public Platform +{ +public: + LinuxPpc32Platform(Architecture* arch, const std::string& name): Platform(arch, name) + { + Ref<CallingConvention> cc; + + cc = arch->GetCallingConventionByName("svr4"); + if (cc) + { + RegisterDefaultCallingConvention(cc); + } + + cc = arch->GetCallingConventionByName("linux-syscall"); + if (cc) + SetSystemCallConvention(cc); + } +}; + +class LinuxPpc64Platform: public Platform +{ +public: + LinuxPpc64Platform(Architecture* arch, const std::string& name): Platform(arch, name) + { + Ref<CallingConvention> cc; + + cc = arch->GetCallingConventionByName("svr4"); + if (cc) + { + RegisterDefaultCallingConvention(cc); + } + + cc = arch->GetCallingConventionByName("linux-syscall"); + if (cc) + SetSystemCallConvention(cc); + } +}; + +class LinuxX64Platform: public Platform +{ +public: + LinuxX64Platform(Architecture* arch): Platform(arch, "linux-x86_64") + { + Ref<CallingConvention> cc; + + cc = arch->GetCallingConventionByName("sysv"); + if (cc) + { + RegisterDefaultCallingConvention(cc); + RegisterCdeclCallingConvention(cc); + RegisterFastcallCallingConvention(cc); + RegisterStdcallCallingConvention(cc); + } + + cc = arch->GetCallingConventionByName("linux-syscall"); + if (cc) + SetSystemCallConvention(cc); + } +}; + + +class LinuxArmv7Platform: public Platform +{ +public: + LinuxArmv7Platform(Architecture* arch, const std::string& name): Platform(arch, name) + { + Ref<CallingConvention> cc; + + cc = arch->GetCallingConventionByName("cdecl"); + if (cc) + { + RegisterDefaultCallingConvention(cc); + RegisterCdeclCallingConvention(cc); + RegisterFastcallCallingConvention(cc); + RegisterStdcallCallingConvention(cc); + } + + cc = arch->GetCallingConventionByName("linux-syscall"); + if (cc) + SetSystemCallConvention(cc); + } +}; + + +class LinuxArm64Platform: public Platform +{ +public: + LinuxArm64Platform(Architecture* arch): Platform(arch, "linux-aarch64") + { + Ref<CallingConvention> cc; + + cc = arch->GetCallingConventionByName("cdecl"); + if (cc) + { + RegisterDefaultCallingConvention(cc); + RegisterCdeclCallingConvention(cc); + RegisterFastcallCallingConvention(cc); + RegisterStdcallCallingConvention(cc); + } + + cc = arch->GetCallingConventionByName("linux-syscall"); + if (cc) + SetSystemCallConvention(cc); + } +}; + + +class LinuxMipsPlatform: public Platform +{ +public: + LinuxMipsPlatform(Architecture* arch, const std::string& name): Platform(arch, name) + { + Ref<CallingConvention> cc; + + cc = arch->GetCallingConventionByName("o32"); + if (cc) + { + RegisterDefaultCallingConvention(cc); + RegisterCdeclCallingConvention(cc); + RegisterFastcallCallingConvention(cc); + RegisterStdcallCallingConvention(cc); + } + + cc = arch->GetCallingConventionByName("linux-syscall"); + if (cc) + SetSystemCallConvention(cc); + } +}; + + +extern "C" +{ + BN_DECLARE_CORE_ABI_VERSION + +#ifndef DEMO_VERSION + BINARYNINJAPLUGIN void CorePluginDependencies() + { + AddOptionalPluginDependency("arch_x86"); + AddOptionalPluginDependency("arch_armv7"); + AddOptionalPluginDependency("arch_arm64"); + AddOptionalPluginDependency("arch_mips"); + AddOptionalPluginDependency("arch_ppc"); + AddOptionalPluginDependency("view_elf"); + } +#endif + +#ifdef DEMO_VERSION + bool LinuxPluginInit() +#else + BINARYNINJAPLUGIN bool CorePluginInit() +#endif + { + Ref<Architecture> x86 = Architecture::GetByName("x86"); + if (x86) + { + Ref<Platform> platform; + + platform = new LinuxX86Platform(x86); + Platform::Register("linux", platform); + // Linux binaries sometimes have an OS identifier of zero, even though 3 is the correct one + BinaryViewType::RegisterPlatform("ELF", 0, x86, platform); + BinaryViewType::RegisterPlatform("ELF", 3, x86, platform); + } + + Ref<Architecture> x64 = Architecture::GetByName("x86_64"); + if (x64) + { + Ref<Platform> platform; + + platform = new LinuxX64Platform(x64); + Platform::Register("linux", platform); + // Linux binaries sometimes have an OS identifier of zero, even though 3 is the correct one + BinaryViewType::RegisterPlatform("ELF", 0, x64, platform); + BinaryViewType::RegisterPlatform("ELF", 3, x64, platform); + } + + Ref<Architecture> armv7 = Architecture::GetByName("armv7"); + Ref<Architecture> armv7eb = Architecture::GetByName("armv7eb"); + Ref<Architecture> thumb2 = Architecture::GetByName("thumb2"); + Ref<Architecture> thumb2eb = Architecture::GetByName("thumb2eb"); + if (armv7 && armv7eb && thumb2 && thumb2eb) + { + Ref<Platform> armPlatform, armebPlatform, thumbPlatform, thumbebPlatform; + + armPlatform = new LinuxArmv7Platform(armv7, "linux-armv7"); + armebPlatform = new LinuxArmv7Platform(armv7eb, "linux-armv7eb"); + thumbPlatform = new LinuxArmv7Platform(thumb2, "linux-thumb2"); + thumbebPlatform = new LinuxArmv7Platform(thumb2eb, "linux-thumb2eb"); + armPlatform->AddRelatedPlatform(thumb2, thumbPlatform); + armebPlatform->AddRelatedPlatform(thumb2eb, thumbebPlatform); + thumbPlatform->AddRelatedPlatform(armv7, armPlatform); + thumbebPlatform->AddRelatedPlatform(armv7eb, armebPlatform); + Platform::Register("linux", armPlatform); + Platform::Register("linux", thumbPlatform); + Platform::Register("linux", armebPlatform); + Platform::Register("linux", thumbebPlatform); + // Linux binaries sometimes have an OS identifier of zero, even though 3 is the correct one + BinaryViewType::RegisterPlatform("ELF", 0, armv7, armPlatform); + BinaryViewType::RegisterPlatform("ELF", 3, armv7, armPlatform); + BinaryViewType::RegisterPlatform("ELF", 0, armv7eb, armebPlatform); + BinaryViewType::RegisterPlatform("ELF", 3, armv7eb, armebPlatform); + } + + Ref<Architecture> arm64 = Architecture::GetByName("aarch64"); + if (arm64) + { + Ref<Platform> platform; + + 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, arm64, platform); + BinaryViewType::RegisterPlatform("ELF", 3, arm64, platform); + } + + Ref<Architecture> ppc = Architecture::GetByName("ppc"); + Ref<Architecture> ppcle = Architecture::GetByName("ppc_le"); + if (ppc && ppcle) + { + Ref<Platform> platform; + Ref<Platform> platformle; + + platform = new LinuxPpc32Platform(ppc, "linux-ppc32"); + platformle = new LinuxPpc32Platform(ppcle, "linux-ppc32_le"); + Platform::Register("linux", platform); + Platform::Register("linux", platformle); + // Linux binaries sometimes have an OS identifier of zero, even though 3 is the correct one + BinaryViewType::RegisterPlatform("ELF", 0, ppc, platform); + BinaryViewType::RegisterPlatform("ELF", 3, ppc, platform); + BinaryViewType::RegisterPlatform("ELF", 0, ppcle, platformle); + BinaryViewType::RegisterPlatform("ELF", 3, ppcle, platformle); + } + + Ref<Architecture> ppc64 = Architecture::GetByName("ppc64"); + Ref<Architecture> ppc64le = Architecture::GetByName("ppc64_le"); + if (ppc64 && ppc64le) + { + Ref<Platform> platform; + Ref<Platform> platformle; + + platform = new LinuxPpc64Platform(ppc64, "linux-ppc64"); + platformle = new LinuxPpc64Platform(ppc64le, "linux-ppc64_le"); + Platform::Register("linux", platform); + Platform::Register("linux", platformle); + // Linux binaries sometimes have an OS identifier of zero, even though 3 is the correct one + BinaryViewType::RegisterPlatform("ELF", 0, ppc64, platform); + BinaryViewType::RegisterPlatform("ELF", 3, ppc64, platform); + BinaryViewType::RegisterPlatform("ELF", 0, ppc64le, platformle); + BinaryViewType::RegisterPlatform("ELF", 3, ppc64le, platformle); + } + + Ref<Architecture> mipsel = Architecture::GetByName("mipsel32"); + Ref<Architecture> mipseb = Architecture::GetByName("mips32"); + if (mipsel && mipseb) + { + Ref<Platform> platformLE, platformBE; + + platformLE = new LinuxMipsPlatform(mipsel, "linux-mipsel"); + platformBE = new LinuxMipsPlatform(mipseb, "linux-mips"); + Platform::Register("linux", platformLE); + Platform::Register("linux", platformBE); + // Linux binaries sometimes have an OS identifier of zero, even though 3 is the correct one + BinaryViewType::RegisterPlatform("ELF", 0, mipsel, platformLE); + BinaryViewType::RegisterPlatform("ELF", 0, mipseb, platformBE); + BinaryViewType::RegisterPlatform("ELF", 3, mipsel, platformLE); + BinaryViewType::RegisterPlatform("ELF", 3, mipseb, platformBE); + } + + return true; + } +} |
