Binary Ninja Blog

Plugin Manager 2.0

(NOTE: This blog is primarily intended for Binary Ninja plugin authors – the user-facing component for the plugin manager is under testing and should be released shortly)

We’re pleased to announce the imminent release of Binary Ninja’s Plugin Manager 2.0. This article is intended for plugin authors interested in updating their plugins to ensure compatibility with the new interface. The new UI will dramatically improve plugin discoverability and highlight the many great plugin authors out there.

Requirements

Getting your plugin listed in the Plugin Manager UI is straightforward. If you already have a plugin in the old repository and just need to update it you can skip to the last section: What about my old plugin?

1. Create a GitHub Repository

The first step is to write your plugin and create a GitHub repository for it (our sample plugin can help). While we do plan to add support for Gitlab-based repositories, our current iteration only supports GitHub.

2. Create Your plugin.json

With your plugin in a presentable state, the next step is to create your plugin.json file. We recommend either copying an existing one, for example OpaquePredicatePatcher/plugin.json, or using the interactive command line tool generate_plugininfo.py using the --plugin or the --all options to generate the plugin.json, LICENSE file and the README.md.

Example

{
    "pluginmetadataversion": 2,
    "name": "Opaque Predicate Patcher",
    "type": ["helper" ],
    "api": ["python2", "python3"],
    "description": "Automatically patch opaque predicates",
    "longdescription": "This script will automatically remove conditional branches which have constant conditions. It can be run from the command line via `python -mOpaquePredicatePatcher.__main__` (if the BinaryNinja python library is in your path) or installed as a plugin in your user plugin directory. Read more about how this tool works on our blog: [Automated Opaque Predicate Removal](https://binary.ninja/2017/10/01/automated-opaque-predicate-removal.html)\n\n###Example\n\n![Before and After](opaque_predicate_elimination.gif =400x400 'Before and After')",
    "license": {
            "name": "MIT",
            "text": "Copyright (c) 2017 Vecto 35 LLC\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."

    },
    "platforms": ["Windows", "Linux", "Darwin"],
    "installinstructions" : {
            "Windows":"",
            "Linux":"",
            "Darwin":""
    },
    "dependencies": {
    },
    "version": "1.1.1",
    "author": "Vector 35 LLC",
    "minimumbinaryninjaversion": 0
}

Fields

Required Fields:

  • pluginmetadataversion - The current version is the integer 2
  • name - The display name for the plugin. Do not include version information in this field. Good names do not use “Binary Ninja” or “Binja”–nor do they use the words “plugin” or “extension”. So instead of “Binja 6502 Architecture Plugin” simply use “6502 Architecture”.
  • author - Your name, handle, or company name.
  • api - A list of supported architectures. Though we currently support python2 and python3 we highly recommend plugin authors support python3 as python2 support will soon be deprecated.
  • license - A json object with name and text keys.
  • description - This is a short (<50 character) description of the plugin.
  • longdescription - A longer markdown formatted description of the plugin including hyperlinks and images as needed.
  • version - Version string
  • minimumBinaryNinjaVersion - An integer build number (so instead of 1.1.555 use 555).
  • platforms - A list of strings, one for each supported platform. Valid platforms are Darwin, Linux, and Windows

Recommended Fields:

  • type - A list of strings of the following types: core, ui, architecture, binaryview, and helper. This field isn’t currently used by the UI.
    • core - Plugin that extends the core’s analysis. Your plugin probably isn’t one of these.
    • ui - The plugin extends the UI is some way and imports binaryninjaui.
    • architecture - The plugin adds an architecture (e.g. x86, ARM, MIPS).
    • binaryview - The plugin adds a new BinaryView (e.g. PE, MachO, ELF).
    • helper - Plugin that adds some functionality to Binary Ninja. Most plugins will be of this type.
  • installinstructions - A json object with keys for each supported platform listed in platforms and values containing markdown formatted text describing how to install the plugin on that platform.

plugin.json Verification

The generate_plugininfo.py script has a handy verification feature which is actually what it will do if you pass no arguments. For example: ./generate_plugininfo.py is equivalent to generate_plugininfo.py -v plugin.json.

3. Testing & Compatibility

To ensure your plugin supports the widest possible audience there are three categories of compatibility you should be test and ensure compatibility.

Platform

Binary Ninja supports Linux, MacOS, and Windows, and your license entitles you to run Binary Ninja on all three platforms. We encourage plugin authors to test their plugins on all three.

API

Binary Ninja currently supports both python2 and python3 scripting APIs. We strongly discourage the use of python2 for new plugins, and encourage plugins to be both python2 and python3 compatible. We will be soon deprecating python2 and plugins that only support python2 will be removed from the Plugin Manager.

Binary Ninja Version

We recommend testing your plugin minimally on the previous stable version of Binary Ninja. You can access previous stable and development builds from the version selector built into Binary Ninja.

Version Switcher >

4. Choose a License

We require all plugins in the Plugin Manager to have a license. The generate_plugininfo.py can help you with this.

A word about license choice:

Our preferred licenses for plugins are MIT, BSD, or LGPL. Licenses such as GPLv2, GPLv3, and AGPL may prevent us from redistributing your plugin. Presumably this may run counter to your desires if you’re submitting your plugin to the plugin repository.

5. Create a Release

As a change from the previous version of the Plugin Manager we now require users to create official releases of their plugin. If you’ve never used this feature before, it’s simple and we highly recommend GitHub’s hub tool for it.

Let’s say you’ve just made your final commit and your ready to submit your Awesome Plugin 1.0. Your plugin.json and LICENSE has been created and added to your repository. Next, create and push an annotated tag.

git tag -a 1.0
git push origin 1.0

Next use the command line hub tool:

hub release create 1.0

You’ll get asked for a title, like Awesome Plugin 1.0.

6. Submitting your Plugin

To submit your plugin to the Community Repository, just file an issue with your specific tag and repository. Here’s an example issue:

Title:

Initial submission of My Awesome Plugin

Message:

I'm pleased to submit My Awesome Plugin 1.0 to the community repository.

Updating your plugin

  1. Commit your change set.
  2. Update your plugin.json
  3. Create a Release 4. Create an issue listing the new release tag.

[EDIT: 2023-05-20: As of earlier last year, creating an issue is no longer required. Now your best bet is to follow the documentation instructions.]

What about my old plugin?

If you already have a plugin in the old repository you will need some updates to your plugin.json.

The Fast Version

  1. Run generate_plugininfo.py -v to verify that your plugin.json has all of the required fields for the new plugin manager, and generate_plugininfo.py -a to generate all required files (or check the help and only generate what you need)
  2. Tag a release (you might want to use hub to do it).
  3. File an issue to let us know the release and repo we should add

The Long Version

New Fields

  • A specification version pluginmetadataversion has been added. The current version 2 should be added.
  • The platforms array has been added. This field specifies the platforms that this plugin has been tested on. The valid platforms are Windows, Linux, and Darwin. Testing can be a pain, especially if you don’t have access to a MacOS machine. We recommend asking the great people in our public slack channel; it’s also a great place to get feedback!
  • An installinstructions object has been added. This object should have keys for each of the supported platforms above, and values of Markdown formatted strings explaining how to install the plugin, including any prerequisites.

Updates

  • The original version of the plugin.json had all objects inside a json object with the key plugin, all fields are now top level.
  • The api field is now an array of strings with supported values python2 and python3. We strongly encourage all plugins to be python3 compatible as we will soon be deprecating python2.
  • The minimumBinaryNinjaVersion is no longer an object it is a simple integer representing the build number. So if your plugin requires a feature added in Binary Ninja version 1.1.555 your minimumBinaryNinjaVersion would be 555.