|
3 | 3 | using namespace BinaryNinja; |
4 | 4 | using namespace std; |
5 | 5 |
|
| 6 | +Ref<Platform> g_linuxX32; |
| 7 | +#define EM_X86_64 62 // AMD x86-64 architecture |
6 | 8 |
|
7 | 9 | class LinuxX86Platform: public Platform |
8 | 10 | { |
@@ -103,6 +105,50 @@ class LinuxX64Platform: public Platform |
103 | 105 | }; |
104 | 106 |
|
105 | 107 |
|
| 108 | +class LinuxX32Platform: public Platform |
| 109 | +{ |
| 110 | + public: |
| 111 | + LinuxX32Platform(Architecture* arch): Platform(arch, "linux-x32") |
| 112 | + { |
| 113 | + Ref<CallingConvention> cc; |
| 114 | + cc = arch->GetCallingConventionByName("sysv"); |
| 115 | + if (cc) |
| 116 | + { |
| 117 | + RegisterDefaultCallingConvention(cc); |
| 118 | + RegisterCdeclCallingConvention(cc); |
| 119 | + RegisterFastcallCallingConvention(cc); |
| 120 | + RegisterStdcallCallingConvention(cc); |
| 121 | + } |
| 122 | + |
| 123 | + cc = arch->GetCallingConventionByName("linux-syscall"); |
| 124 | + if (cc) |
| 125 | + SetSystemCallConvention(cc); |
| 126 | + } |
| 127 | + |
| 128 | + virtual size_t GetAddressSize() const override |
| 129 | + { |
| 130 | + return 4; |
| 131 | + } |
| 132 | + |
| 133 | + static Ref<Platform> Recognize(BinaryView* view, Metadata* metadata) |
| 134 | + { |
| 135 | + Ref<Metadata> fileClass = metadata->Get("EI_CLASS"); |
| 136 | + |
| 137 | + if (!fileClass || !fileClass->IsUnsignedInteger()) |
| 138 | + return nullptr; |
| 139 | + |
| 140 | + Ref<Metadata> machine = metadata->Get("e_machine"); |
| 141 | + if (!machine || !machine->IsUnsignedInteger()) |
| 142 | + return nullptr; |
| 143 | + |
| 144 | + if (fileClass->GetUnsignedInteger() == 1 && machine->GetUnsignedInteger() == EM_X86_64) |
| 145 | + return g_linuxX32; |
| 146 | + |
| 147 | + return nullptr; |
| 148 | + } |
| 149 | +}; |
| 150 | + |
| 151 | + |
106 | 152 | class LinuxArmv7Platform: public Platform |
107 | 153 | { |
108 | 154 | public: |
@@ -314,13 +360,20 @@ extern "C" |
314 | 360 | Ref<Architecture> x64 = Architecture::GetByName("x86_64"); |
315 | 361 | if (x64) |
316 | 362 | { |
317 | | - Ref<Platform> platform; |
| 363 | + Ref<Platform> x64Platform = new LinuxX64Platform(x64); |
| 364 | + g_linuxX32 = new LinuxX32Platform(x64); |
| 365 | + |
| 366 | + Platform::Register("linux", x64Platform); |
| 367 | + Platform::Register("linux", g_linuxX32); |
318 | 368 |
|
319 | | - platform = new LinuxX64Platform(x64); |
320 | | - Platform::Register("linux", platform); |
321 | 369 | // Linux binaries sometimes have an OS identifier of zero, even though 3 is the correct one |
322 | | - BinaryViewType::RegisterPlatform("ELF", 0, platform); |
323 | | - BinaryViewType::RegisterPlatform("ELF", 3, platform); |
| 370 | + BinaryViewType::RegisterPlatform("ELF", 0, x64, x64Platform); |
| 371 | + BinaryViewType::RegisterPlatform("ELF", 3, x64, x64Platform); |
| 372 | + |
| 373 | + |
| 374 | + Ref<BinaryViewType> elf = BinaryViewType::GetByName("ELF"); |
| 375 | + if (elf) |
| 376 | + elf->RegisterPlatformRecognizer(EM_X86_64, LittleEndian, LinuxX32Platform::Recognize); |
324 | 377 | } |
325 | 378 |
|
326 | 379 | Ref<Architecture> armv7 = Architecture::GetByName("armv7"); |
|
0 commit comments