diff options
Diffstat (limited to 'docs/dev/plugins.md')
| -rw-r--r-- | docs/dev/plugins.md | 240 |
1 files changed, 130 insertions, 110 deletions
diff --git a/docs/dev/plugins.md b/docs/dev/plugins.md index f83de6c7..cd320784 100644 --- a/docs/dev/plugins.md +++ b/docs/dev/plugins.md @@ -114,16 +114,18 @@ although it is recommended to use the latest version. The first things to specify in your CMake file are a couple boilerplate options for building C++: - # Pick whatever version you have - cmake_minimum_required(VERSION 3.24) +```cmake +# Pick whatever version you have +cmake_minimum_required(VERSION 3.24) - # Name your plugin - project(TestPlugin CXX) +# Name your plugin +project(TestPlugin CXX) - set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD 20) - # Unless you are writing a plugin that needs Qt's UI, specify this - set(HEADLESS 1) +# Unless you are writing a plugin that needs Qt's UI, specify this +set(HEADLESS 1) +``` Then you want to get the matching API repository for the version of Binary Ninja you have. This information is contained in a file named `api_REVISION.txt` that exists in the root install folder for Linux, @@ -132,43 +134,51 @@ the `Contents/Resources` sub-folder on macOS, and the root installation folder o Once you know which revision to use, you can clone a copy of the binaryninja-api repository and reference it directly in your plugin. If you're using git, this can be accomplished easily using a submodule: - git submodule add https://github.com/Vector35/binaryninja-api.git binaryninjaapi - cd binaryninjaapi - # Pick the revision from api_REVISION.txt - git checkout 6466fba3341b2ea7dbfceeeebbc6c0322a5d8514 +```bash +git submodule add https://github.com/Vector35/binaryninja-api.git binaryninjaapi +cd binaryninjaapi +# Pick the revision from api_REVISION.txt +git checkout 6466fba3341b2ea7dbfceeeebbc6c0322a5d8514 +``` If you're not using git, you can clone the repository elsewhere: - git clone https://github.com/Vector35/binaryninja-api.git binaryninjaapi - cd binaryninjaapi - # Pick the revision from api_REVISION.txt - git checkout 6466fba3341b2ea7dbfceeeebbc6c0322a5d8514 +```bash +git clone https://github.com/Vector35/binaryninja-api.git binaryninjaapi +cd binaryninjaapi +# Pick the revision from api_REVISION.txt +git checkout 6466fba3341b2ea7dbfceeeebbc6c0322a5d8514 +``` Now that you have the correct copy of the api, you need to point CMake at it and include it for use. Include something like the following in your CMake script and either add the path of your clone to the HINTS list or set the BN_API_PATH environment variable to the location of your clone - find_path( - BN_API_PATH - NAMES binaryninjaapi.h - # List of paths to search for the clone of the api - HINTS ../.. binaryninjaapi $ENV{BN_API_PATH} - REQUIRED - ) - add_subdirectory(${BN_API_PATH} api) +```cmake +find_path( + BN_API_PATH + NAMES binaryninjaapi.h + # List of paths to search for the clone of the api + HINTS ../.. binaryninjaapi $ENV{BN_API_PATH} + REQUIRED +) +add_subdirectory(${BN_API_PATH} api) +``` Be sure to create a shared library and link against the Binary Ninja api. Also, you can use the `bn_install_plugin` helper to automatically set up your plugin to install to the Binary Ninja plugins directory when you use `cmake install`. - # Use whichever sources and plugin name you want - add_library(TestPlugin SHARED TestPlugin.cpp) +```cmake +# Use whichever sources and plugin name you want +add_library(TestPlugin SHARED TestPlugin.cpp) - # Link with Binary Ninja - target_link_libraries(TestPlugin PUBLIC binaryninjaapi) +# Link with Binary Ninja +target_link_libraries(TestPlugin PUBLIC binaryninjaapi) - # Tell `cmake --install` to copy your plugin to the plugins directory - bn_install_plugin(TestPlugin) +# Tell `cmake --install` to copy your plugin to the plugins directory +bn_install_plugin(TestPlugin) +``` From there you can write the rest of your plugin's CMake configuration, including any other dependencies or options that you want. When you want to run your plugin, you can use `cmake --build` and `cmake --install` @@ -178,24 +188,26 @@ You could also copy the plugin manually if you are using a different plugins dir In the source code of your plugin, you will need to export some functions that Binary Ninja uses to load your plugin at runtime: - #include "binaryninjaapi.h" - extern "C" { - // Tells Binary Ninja which version of the API you compiled against - BN_DECLARE_CORE_ABI_VERSION +```cpp +#include "binaryninjaapi.h" +extern "C" { + // Tells Binary Ninja which version of the API you compiled against + BN_DECLARE_CORE_ABI_VERSION - // Function run on plugin startup, do simple initialization here (Settings, BinaryViewTypes, etc) - BINARYNINJAPLUGIN bool CorePluginInit() - { - return true; - } + // Function run on plugin startup, do simple initialization here (Settings, BinaryViewTypes, etc) + BINARYNINJAPLUGIN bool CorePluginInit() + { + return true; + } - // (Optional) Function to add other plugin dependencies in case your plugin requires them - BINARYNINJAPLUGIN void CorePluginDependencies() - { - // For example, if you require the x86 to be loaded before your plugin - AddRequiredPluginDependency("arch_x86"); - } + // (Optional) Function to add other plugin dependencies in case your plugin requires them + BINARYNINJAPLUGIN void CorePluginDependencies() + { + // For example, if you require the x86 to be loaded before your plugin + AddRequiredPluginDependency("arch_x86"); } +} +``` From there, you can implement your plugin functionality as you desire. I highly recommend looking at other plugins for API usage since the C++ API is less well-documented than the Python API. Usually the functions and classes are named @@ -219,46 +231,50 @@ or you can attempt to use a system-provided copy if you use Linux and like to li Building it is a bit of a process, but should provide you with a working installation. Once you have a Qt build, you can amend your CMake file to make a UI plugin. You will need the following CMake: - # Remove this or set to 0 - # set(HEADLESS 1) +```cmake +# Remove this or set to 0 +# set(HEADLESS 1) - # If you are using Qt MOC (i.e. use Q_OBJECT/Q_SIGNALS/Q_SLOTS) - set(CMAKE_AUTOMOC ON) - set(CMAKE_AUTORCC ON) +# If you are using Qt MOC (i.e. use Q_OBJECT/Q_SIGNALS/Q_SLOTS) +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) - # Locate Qt installation for linking - find_package(Qt6 COMPONENTS Core Gui Widgets REQUIRED) +# Locate Qt installation for linking +find_package(Qt6 COMPONENTS Core Gui Widgets REQUIRED) - # Add MOCS to your build - add_library(TestPlugin SHARED library.cpp ${MOCS}) +# Add MOCS to your build +add_library(TestPlugin SHARED library.cpp ${MOCS}) - # Link against both binaryninjaapi/binaryninjaui and Qt6 - target_link_libraries(TestPlugin PUBLIC binaryninjaapi binaryninjaui Qt6::Core Qt6::Gui Qt6::Widgets) +# Link against both binaryninjaapi/binaryninjaui and Qt6 +target_link_libraries(TestPlugin PUBLIC binaryninjaapi binaryninjaui Qt6::Core Qt6::Gui Qt6::Widgets) +``` Then, in your plugin code, instead of using the exported functions for a core plugin, use the ones for a UI plugin: - #include "binaryninjaapi.h" - #include "uitypes.h" - #include "uicontext.h" +```cpp +#include "binaryninjaapi.h" +#include "uitypes.h" +#include "uicontext.h" - extern "C" { - // Tells Binary Ninja which version of the API you compiled against - BN_DECLARE_UI_ABI_VERSION +extern "C" { + // Tells Binary Ninja which version of the API you compiled against + BN_DECLARE_UI_ABI_VERSION - // Function run on plugin startup, do simple initialization here (ViewTypes, SidebarWidgetTypes, etc) - BINARYNINJAPLUGIN bool UIPluginInit() - { - return true; - } + // Function run on plugin startup, do simple initialization here (ViewTypes, SidebarWidgetTypes, etc) + BINARYNINJAPLUGIN bool UIPluginInit() + { + return true; + } - // (Optional) Function to add other plugin dependencies in case your plugin requires them - // Historically, these have never actually been used - BINARYNINJAPLUGIN void UIPluginDependencies() - { - // For example, if you require triage view to be loaded before your plugin - AddRequiredUIPluginDependency("triage"); - } + // (Optional) Function to add other plugin dependencies in case your plugin requires them + // Historically, these have never actually been used + BINARYNINJAPLUGIN void UIPluginDependencies() + { + // For example, if you require triage view to be loaded before your plugin + AddRequiredUIPluginDependency("triage"); } +} +``` From there, you can implement whatever wacky Qt user interfaces you dream up. Be warned that the Binary Ninja UI API is rather poorly documented and often missing helper functions for use by plugins. Feel free to ask for assistance and @@ -305,51 +321,55 @@ VSCode takes a bit of configuration to set up, but can build and debug plugins e You can install the C/C++ extension, the CMake extension, and the CMake Tools extension. You need to set up a task in `.vscode/tasks.json` to build and install your plugin. Something like this: - // tasks.json - { - "version": "2.0.0", - "tasks": [ - { - "type": "cmake", - "label": "CMake: install", - "command": "install", - "problemMatcher": [], - "detail": "CMake template install task", - "options": { - "environment": { - // You will need this if your Binary Ninja installation is not in the default location - "BN_INSTALL_DIR": "C:\\Users\\User\\AppData\\Local\\Vector35\\BinaryNinja", - // You will need this if you are writing a UI plugin - "PATH": "C:\\Users\\User\\Qt\\6.10.1\\msvc2019_64\\bin" - } +```jsonc +// tasks.json +{ + "version": "2.0.0", + "tasks": [ + { + "type": "cmake", + "label": "CMake: install", + "command": "install", + "problemMatcher": [], + "detail": "CMake template install task", + "options": { + "environment": { + // You will need this if your Binary Ninja installation is not in the default location + "BN_INSTALL_DIR": "C:\\Users\\User\\AppData\\Local\\Vector35\\BinaryNinja", + // You will need this if you are writing a UI plugin + "PATH": "C:\\Users\\User\\Qt\\6.10.1\\msvc2019_64\\bin" } } - ] - } + } + ] +} +``` You will also want to set up a launch task in `.vscode/launch.json` to launch Binary Ninja in a debugger, so you can debug your plugin. Be sure to set `"preLaunchTask"` to use the `CMake: install` task created above, so your code updates will be built and installed automatically before you start debugging. - // launch.json - { - "version": "0.2.0", - "configurations": [ - { - "name": "(Windows) Launch", - "type": "cppvsdbg", - "request": "launch", - "program": "C:\\Users\\User\\AppData\\Local\\Vector35\\BinaryNinja\\binaryninja.exe", - "args": [], - "stopAtEntry": false, - "cwd": "C:\\Users\\User\\AppData\\Local\\Vector35\\BinaryNinja", - "environment": [], - "console": "externalTerminal", - "preLaunchTask": "CMake: install" - } - ] - } +```jsonc +// launch.json +{ + "version": "0.2.0", + "configurations": [ + { + "name": "(Windows) Launch", + "type": "cppvsdbg", + "request": "launch", + "program": "C:\\Users\\User\\AppData\\Local\\Vector35\\BinaryNinja\\binaryninja.exe", + "args": [], + "stopAtEntry": false, + "cwd": "C:\\Users\\User\\AppData\\Local\\Vector35\\BinaryNinja", + "environment": [], + "console": "externalTerminal", + "preLaunchTask": "CMake: install" + } + ] +} +``` There are a few other options you can use to assist in debugging: |
