diff options
| author | kat <kat@vector35.com> | 2025-03-05 17:25:08 -0500 |
|---|---|---|
| committer | kat <kat@vector35.com> | 2025-03-19 15:04:23 -0400 |
| commit | e6d4d38e2a5dc66d3c8004cc917bc08e39337482 (patch) | |
| tree | 6929ee09b4a06b653dde5792f881ee2e0ea29456 | |
| parent | b5caef3d7d0efa4411dddac841ea38a359956474 (diff) | |
Add mac-kernel platform
| -rw-r--r-- | platform/mac-kernel/CMakeLists.txt | 33 | ||||
| -rw-r--r-- | platform/mac-kernel/LICENSE | 13 | ||||
| -rw-r--r-- | platform/mac-kernel/README.md | 23 | ||||
| -rw-r--r-- | platform/mac-kernel/platform_mac_kernel.cpp | 348 |
4 files changed, 417 insertions, 0 deletions
diff --git a/platform/mac-kernel/CMakeLists.txt b/platform/mac-kernel/CMakeLists.txt new file mode 100644 index 00000000..add7a3d1 --- /dev/null +++ b/platform/mac-kernel/CMakeLists.txt @@ -0,0 +1,33 @@ +cmake_minimum_required(VERSION 3.9 FATAL_ERROR) + +project(platform_mac_kernel) + +if(NOT BN_INTERNAL_BUILD) + add_subdirectory(${PROJECT_SOURCE_DIR}/../.. ${PROJECT_BINARY_DIR}/api) +endif() + +file(GLOB SOURCES + ${PROJECT_SOURCE_DIR}/*.cpp + ${PROJECT_SOURCE_DIR}/*.h) + +if(DEMO) + add_library(platform_mac_kernel STATIC ${SOURCES}) +else() + add_library(platform_mac_kernel SHARED ${SOURCES}) +endif() + +target_link_libraries(platform_mac_kernel binaryninjaapi) + +set_target_properties(platform_mac_kernel PROPERTIES + CXX_STANDARD 17 + CXX_VISIBILITY_PRESET hidden + CXX_STANDARD_REQUIRED ON + VISIBILITY_INLINES_HIDDEN ON + POSITION_INDEPENDENT_CODE ON) + +if(BN_INTERNAL_BUILD) + plugin_rpath(platform_mac_kernel) + set_target_properties(platform_mac_kernel PROPERTIES + LIBRARY_OUTPUT_DIRECTORY ${BN_CORE_PLUGIN_DIR} + RUNTIME_OUTPUT_DIRECTORY ${BN_CORE_PLUGIN_DIR}) +endif() diff --git a/platform/mac-kernel/LICENSE b/platform/mac-kernel/LICENSE new file mode 100644 index 00000000..265bf79a --- /dev/null +++ b/platform/mac-kernel/LICENSE @@ -0,0 +1,13 @@ +Copyright 2021-2024 Vector 35 Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/platform/mac-kernel/README.md b/platform/mac-kernel/README.md new file mode 100644 index 00000000..043fe035 --- /dev/null +++ b/platform/mac-kernel/README.md @@ -0,0 +1,23 @@ +# platform-mac +This is the macOS platform plugin that ships with Binary Ninja. + +## Building + +Building the architecture plugin requires `cmake` 3.9 or above. You will also need the +[Binary Ninja API source](https://github.com/Vector35/binaryninja-api). + +Run `cmake`. This can be done either from a separate build directory or from the source +directory. Once that is complete, run `make` in the build directory to compile the plugin. + +The plugin can be found in the root of the build directory as `libplatform_mac.so`, +`libplatform_mac.dylib` or `platform_mac.dll` depending on your platform. + +To install the plugin, first launch Binary Ninja and uncheck the "macOS platform plugin" +option in the "Core Plugins" section. This will cause Binary Ninja to stop loading the +bundled plugin so that its replacement can be loaded. Once this is complete, you can copy +the plugin into the user plugins directory (you can locate this by using the "Open Plugin Folder" +option in the Binary Ninja UI). + +**Do not replace the architecture plugin in the Binary Ninja install directory. This will +be overwritten every time there is a Binary Ninja update. Use the above process to ensure that +updates do not automatically uninstall your custom build.** diff --git a/platform/mac-kernel/platform_mac_kernel.cpp b/platform/mac-kernel/platform_mac_kernel.cpp new file mode 100644 index 00000000..65d27d0a --- /dev/null +++ b/platform/mac-kernel/platform_mac_kernel.cpp @@ -0,0 +1,348 @@ +#include "binaryninjaapi.h" + +using namespace BinaryNinja; +using namespace std; + + +Ref<Platform> g_macKernelX86, g_macKernelX64, g_macKernelArmv7, g_macKernelThumb2, g_macKernelArm64; +Ref<Platform> g_iosKernelArmv7, g_iosKernelThumb2, g_iosKernelArm64; + + +class MacKernelX86Platform: public Platform +{ +public: + MacKernelX86Platform(Architecture* arch): Platform(arch, "mac-kernel-x86") + { + Ref<CallingConvention> cc; + + cc = arch->GetCallingConventionByName("cdecl"); + if (cc) + { + RegisterDefaultCallingConvention(cc); + RegisterCdeclCallingConvention(cc); + } + + cc = arch->GetCallingConventionByName("regparm"); + if (cc) + RegisterFastcallCallingConvention(cc); + + cc = arch->GetCallingConventionByName("stdcall"); + if (cc) + RegisterStdcallCallingConvention(cc); + } + + virtual bool GetFallbackEnabled() override + { + return false; + } + + static Ref<Platform> Recognize(BinaryView* view, Metadata* metadata) + { + auto machoPlatform = metadata->Get("machoplatform"); + if (!machoPlatform || !machoPlatform->IsUnsignedInteger()) + return nullptr; + if (machoPlatform->GetUnsignedInteger() != 2) + return g_macKernelX86; + + return nullptr; + } +}; + + +class MacKernelX64Platform: public Platform +{ +public: + MacKernelX64Platform(Architecture* arch): Platform(arch, "mac-kernel-x86_64") + { + Ref<CallingConvention> cc; + + cc = arch->GetCallingConventionByName("sysv"); + if (cc) + { + RegisterDefaultCallingConvention(cc); + RegisterCdeclCallingConvention(cc); + RegisterFastcallCallingConvention(cc); + RegisterStdcallCallingConvention(cc); + } + } + + virtual bool GetFallbackEnabled() override + { + return false; + } + + static Ref<Platform> Recognize(BinaryView* view, Metadata* metadata) + { + auto machoPlatform = metadata->Get("machoplatform"); + if (!machoPlatform || !machoPlatform->IsUnsignedInteger()) + return nullptr; + if (machoPlatform->GetUnsignedInteger() != 2) + return g_macKernelX64; + + return nullptr; + } +}; + + +class MacKernelArmv7Platform: public Platform +{ +public: + MacKernelArmv7Platform(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); + } + } + + virtual bool GetFallbackEnabled() override + { + return false; + } + + static Ref<Platform> Recognize(BinaryView* view, Metadata* metadata) + { + bool shouldRecognizeOnIOS = false; + if (view->GetFile()->IsBackedByDatabase()) + { + if (auto database = view->GetFile()->GetDatabase()) + { + if (database->HasGlobal("original_version") && database->ReadGlobal("original_version").asInt64() < 6) + shouldRecognizeOnIOS = true; + } + } + auto machoPlatform = metadata->Get("machoplatform"); + if (!machoPlatform || !machoPlatform->IsUnsignedInteger()) + return nullptr; + if (machoPlatform->GetUnsignedInteger() != 2 || shouldRecognizeOnIOS) + return g_macKernelArmv7; + + return nullptr; + } +}; + + +class MacKernelArm64Platform: public Platform +{ +public: + MacKernelArm64Platform(Architecture* arch): Platform(arch, "mac-kernel-aarch64") + { + Ref<CallingConvention> cc; + + cc = arch->GetCallingConventionByName("apple-arm64"); + if (cc) + { + RegisterDefaultCallingConvention(cc); + RegisterCdeclCallingConvention(cc); + RegisterFastcallCallingConvention(cc); + RegisterStdcallCallingConvention(cc); + } + } + + virtual bool GetFallbackEnabled() override + { + return false; + } + + static Ref<Platform> Recognize(BinaryView* view, Metadata* metadata) + { + bool shouldRecognizeOnIOS = false; + if (view->GetFile()->IsBackedByDatabase()) + { + if (auto database = view->GetFile()->GetDatabase()) + { + if (database->HasGlobal("original_version") && database->ReadGlobal("original_version").asInt64() < 6) + shouldRecognizeOnIOS = true; + } + } + auto machoPlatform = metadata->Get("machoplatform"); + if (!machoPlatform || !machoPlatform->IsUnsignedInteger()) + return nullptr; + if (machoPlatform->GetUnsignedInteger() != 2 || shouldRecognizeOnIOS) + return g_macKernelArm64; + + return nullptr; + } +}; + + +class IOSKernelArmv7Platform: public Platform +{ +public: + IOSKernelArmv7Platform(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); + } + } + + virtual bool GetFallbackEnabled() override + { + return false; + } + + static Ref<Platform> Recognize(BinaryView* view, Metadata* metadata) + { + auto machoPlatform = metadata->Get("machoplatform"); + if (machoPlatform->GetUnsignedInteger() != 2) + return nullptr; + if (!machoPlatform || !machoPlatform->IsUnsignedInteger()) + return nullptr; + if (view->GetFile()->IsBackedByDatabase()) + { + if (auto database = view->GetFile()->GetDatabase()) + { + if (database->HasGlobal("original_version") && database->ReadGlobal("original_version").asInt64() < 6) + { + LogError("%s", "iOS database was saved with mac platform. Unable to upgrade. For iOS typelibs to" + " function properly, this binary must be reopened."); + return nullptr; + } + } + } + return g_iosKernelArmv7; + } +}; + +class IOSKernelArm64Platform: public Platform +{ +public: + IOSKernelArm64Platform(Architecture* arch): Platform(arch, "ios-kernel-aarch64") + { + Ref<CallingConvention> cc; + + cc = arch->GetCallingConventionByName("apple-arm64"); + if (cc) + { + RegisterDefaultCallingConvention(cc); + RegisterCdeclCallingConvention(cc); + RegisterFastcallCallingConvention(cc); + RegisterStdcallCallingConvention(cc); + } + } + + virtual bool GetFallbackEnabled() override + { + return false; + } + + static Ref<Platform> Recognize(BinaryView* view, Metadata* metadata) + { + auto machoPlatform = metadata->Get("machoplatform"); + if (!machoPlatform || !machoPlatform->IsUnsignedInteger()) + return nullptr; + if (machoPlatform->GetUnsignedInteger() != 2) + return nullptr; + if (view->GetFile()->IsBackedByDatabase()) + { + if (auto database = view->GetFile()->GetDatabase()) + { + if (database->HasGlobal("original_version") && database->ReadGlobal("original_version").asInt64() < 6) + { + LogError("%s", "iOS database was saved with mac platform. Unable to upgrade. For iOS typelibs to" + " function properly, this binary must be reopened."); + return nullptr; + } + } + } + return g_iosKernelArm64; + } +}; + + +extern "C" +{ + BN_DECLARE_CORE_ABI_VERSION + +#ifndef DEMO_EDITION + BINARYNINJAPLUGIN void CorePluginDependencies() + { + AddOptionalPluginDependency("arch_x86"); + AddOptionalPluginDependency("arch_armv7"); + AddOptionalPluginDependency("arch_arm64"); + AddOptionalPluginDependency("view_macho"); + AddOptionalPluginDependency("sharedcache"); + } +#endif + +#ifdef DEMO_EDITION + bool MacPluginInit() +#else + BINARYNINJAPLUGIN bool CorePluginInit() +#endif + { + Ref<BinaryViewType> viewType = BinaryViewType::GetByName("KCView"); + Ref<Architecture> x86 = Architecture::GetByName("x86"); + if (x86) + { + g_macKernelX86 = new MacKernelX86Platform(x86); + Platform::Register("mac-kernel", g_macKernelX86); + if (viewType) + viewType->RegisterPlatformRecognizer(7, LittleEndian, MacKernelX86Platform::Recognize); + } + + Ref<Architecture> x64 = Architecture::GetByName("x86_64"); + if (x64) + { + g_macKernelX64 = new MacKernelX64Platform(x64); + Platform::Register("mac-kernel", g_macKernelX64); + if (viewType) + viewType->RegisterPlatformRecognizer(0x01000007, LittleEndian, MacKernelX64Platform::Recognize); + } + + Ref<Architecture> armv7 = Architecture::GetByName("armv7"); + Ref<Architecture> thumb2 = Architecture::GetByName("thumb2"); + if (armv7 && thumb2) + { + g_macKernelArmv7 = new MacKernelArmv7Platform(armv7, "mac-kernel-armv7"); + g_macKernelThumb2 = new MacKernelArmv7Platform(thumb2, "mac-kernel-thumb2"); + g_iosKernelArmv7 = new IOSKernelArmv7Platform(armv7, "ios-kernel-armv7"); + g_iosKernelThumb2 = new IOSKernelArmv7Platform(thumb2, "ios-kernel-thumb2"); + g_macKernelArmv7->AddRelatedPlatform(thumb2, g_macKernelThumb2); + g_macKernelThumb2->AddRelatedPlatform(armv7, g_macKernelArmv7); + g_iosKernelArmv7->AddRelatedPlatform(thumb2, g_iosKernelThumb2); + g_iosKernelThumb2->AddRelatedPlatform(armv7, g_iosKernelArmv7); + Platform::Register("mac-kernel", g_macKernelArmv7); + Platform::Register("ios-kernel", g_iosKernelArmv7); + Platform::Register("mac-kernel", g_macKernelThumb2); + Platform::Register("ios-kernel", g_iosKernelThumb2); + if (viewType) + { + viewType->RegisterPlatformRecognizer(0xc, LittleEndian, MacKernelArmv7Platform::Recognize); + viewType->RegisterPlatformRecognizer(0xc, LittleEndian, IOSKernelArmv7Platform::Recognize); + } + } + + Ref<Architecture> arm64 = Architecture::GetByName("aarch64"); + if (arm64) + { + g_macKernelArm64 = new MacKernelArm64Platform(arm64); + g_iosKernelArm64 = new IOSKernelArm64Platform(arm64); + Platform::Register("mac-kernel", g_macKernelArm64); + Platform::Register("ios-kernel", g_iosKernelArm64); + if (viewType) + { + viewType->RegisterPlatformRecognizer(0, LittleEndian, MacKernelArm64Platform::Recognize); + viewType->RegisterPlatformRecognizer(0x0100000c, LittleEndian, MacKernelArm64Platform::Recognize); + viewType->RegisterPlatformRecognizer(0x0200000c, LittleEndian, MacKernelArm64Platform::Recognize); + viewType->RegisterPlatformRecognizer(0, LittleEndian, IOSKernelArm64Platform::Recognize); + viewType->RegisterPlatformRecognizer(0x0100000c, LittleEndian, IOSKernelArm64Platform::Recognize); + } + } + + return true; + } +} |
