summaryrefslogtreecommitdiff
path: root/platform/windows-kernel
diff options
context:
space:
mode:
authorPeter LaFosse <peter@vector35.com>2023-08-09 09:17:20 -0400
committerPeter LaFosse <peter@vector35.com>2023-12-02 08:43:28 -0500
commit9393d7166944c6cba3d808b976a8b73c40d2a8ea (patch)
tree13c1d75b907d69175a47c81d940ad2c2b4b1113d /platform/windows-kernel
parent577025979aee0204ce3c5f80a346e5b898e0b023 (diff)
Add windows kernel platform
Diffstat (limited to 'platform/windows-kernel')
-rw-r--r--platform/windows-kernel/CMakeLists.txt33
-rw-r--r--platform/windows-kernel/LICENSE13
-rw-r--r--platform/windows-kernel/README.md23
-rw-r--r--platform/windows-kernel/platform_windows_kernel.cpp167
4 files changed, 236 insertions, 0 deletions
diff --git a/platform/windows-kernel/CMakeLists.txt b/platform/windows-kernel/CMakeLists.txt
new file mode 100644
index 00000000..eafe32b9
--- /dev/null
+++ b/platform/windows-kernel/CMakeLists.txt
@@ -0,0 +1,33 @@
+cmake_minimum_required(VERSION 3.9 FATAL_ERROR)
+
+project(platform_windows_kernel)
+
+if(NOT BN_INTERNAL_BUILD)
+ add_subdirectory(${PROJECT_SOURCE_DIR}/../.. ${PROJECT_BINARY_DIR}/api)
+endif()
+
+file(GLOB SOURCES
+ *.cpp
+ *.h)
+
+if(DEMO)
+ add_library(platform_windows_kernel STATIC ${SOURCES})
+else()
+ add_library(platform_windows_kernel SHARED ${SOURCES})
+endif()
+
+target_link_libraries(platform_windows_kernel binaryninjaapi)
+
+set_target_properties(platform_windows_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_windows_kernel)
+ set_target_properties(platform_windows_kernel PROPERTIES
+ LIBRARY_OUTPUT_DIRECTORY ${BN_CORE_PLUGIN_DIR}
+ RUNTIME_OUTPUT_DIRECTORY ${BN_CORE_PLUGIN_DIR})
+endif()
diff --git a/platform/windows-kernel/LICENSE b/platform/windows-kernel/LICENSE
new file mode 100644
index 00000000..265883c5
--- /dev/null
+++ b/platform/windows-kernel/LICENSE
@@ -0,0 +1,13 @@
+Copyright 2021 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/windows-kernel/README.md b/platform/windows-kernel/README.md
new file mode 100644
index 00000000..37b621cc
--- /dev/null
+++ b/platform/windows-kernel/README.md
@@ -0,0 +1,23 @@
+# platform-windows-kernel
+This is the Windows kernel 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_windows_kernel.so`,
+`libplatform_windows_kernel.dylib` or `platform_windows_kernel.dll` depending on your platform.
+
+To install the plugin, first launch Binary Ninja and uncheck the "Windows kernel 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/windows-kernel/platform_windows_kernel.cpp b/platform/windows-kernel/platform_windows_kernel.cpp
new file mode 100644
index 00000000..85fdc4cd
--- /dev/null
+++ b/platform/windows-kernel/platform_windows_kernel.cpp
@@ -0,0 +1,167 @@
+#include "binaryninjaapi.h"
+#include "lowlevelilinstruction.h"
+
+using namespace BinaryNinja;
+using namespace std;
+
+
+Ref<Platform> g_windowsKernelX86, g_windowsKernelX64, g_windowsKernelArm64;
+
+
+class WindowsKernelX86Platform : public Platform
+{
+public:
+ WindowsKernelX86Platform(Architecture* arch) : Platform(arch, "windows-kernel-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() == 1) // IMAGE_SUBSYSTEM_NATIVE
+ return g_windowsKernelX86;
+ return nullptr;
+ }
+};
+
+
+class WindowsKernelX64Platform : public Platform
+{
+public:
+ WindowsKernelX64Platform(Architecture* arch) : Platform(arch, "windows-kernel-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 WindowsKernel 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() == 1) // IMAGE_SUBSYSTEM_NATIVE
+ return g_windowsKernelX64;
+ return nullptr;
+ }
+};
+
+
+
+class WindowsKernelArm64Platform : public Platform
+{
+public:
+ WindowsKernelArm64Platform(Architecture* arch) : Platform(arch, "windows-kernel-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() == 1) // IMAGE_SUBSYSTEM_NATIVE
+ return g_windowsKernelArm64;
+ return nullptr;
+ }
+};
+
+
+extern "C"
+{
+ BN_DECLARE_CORE_ABI_VERSION
+
+#ifndef DEMO_VERSION
+ BINARYNINJAPLUGIN void CorePluginDependencies()
+ {
+ AddOptionalPluginDependency("arch_x86");
+ AddOptionalPluginDependency("arch_arm64");
+ AddOptionalPluginDependency("view_pe");
+ }
+#endif
+
+#ifdef DEMO_VERSION
+ bool WindowsKernelPluginInit()
+#else
+ BINARYNINJAPLUGIN bool CorePluginInit()
+#endif
+ {
+ Ref<BinaryViewType> pe = BinaryViewType::GetByName("PE");
+ if (pe)
+ {
+ Ref<Architecture> x86 = Architecture::GetByName("x86");
+ if (x86)
+ {
+ g_windowsKernelX86 = new WindowsKernelX86Platform(x86);
+ Platform::Register("windows-kernel", g_windowsKernelX86);
+ pe->RegisterPlatformRecognizer(0x14c, LittleEndian, WindowsKernelX86Platform::Recognize);
+ }
+
+ Ref<Architecture> x64 = Architecture::GetByName("x86_64");
+ if (x64)
+ {
+ g_windowsKernelX64 = new WindowsKernelX64Platform(x64);
+ Platform::Register("windows-kernel", g_windowsKernelX64);
+ pe->RegisterPlatformRecognizer(0x8664, LittleEndian, WindowsKernelX64Platform::Recognize);
+ }
+
+ Ref<Architecture> arm64 = Architecture::GetByName("aarch64");
+ if (arm64)
+ {
+ g_windowsKernelArm64 = new WindowsKernelArm64Platform(arm64);
+ Platform::Register("windows-kernel", g_windowsKernelArm64);
+ pe->RegisterPlatformRecognizer(0xaa64, LittleEndian, WindowsKernelArm64Platform::Recognize);
+ }
+ }
+
+ return true;
+ }
+}