summaryrefslogtreecommitdiff
path: root/docs/dev/plugins.md
blob: 3de9f08924ccd4947013227f03bce0dedc63625e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# Writing Plugins


## Writing Python Plugins

### Creating the Plugin

First, take a look at some of the [example](https://github.com/Vector35/binaryninja-api/tree/dev/python/examples) plugins, or some of the [community](https://github.com/Vector35/community-plugins) plugins to get a feel for different APIs you might be interested in. Of course, the full [API](https://api.binary.ninja/) docs are online and available offline via the `Help`/`Open Python API Reference...`.

To start, we suggest you download the [sample plugin](https://github.com/Vector35/sample_plugin) as a template since it contains all of the elements you're likely to need.

- Begin by editing the `plugin.json` file
- Next, update the `LICENSE`
- For small scripts, you can include all the code inside of `__init__.py`, though we recommend for most larger scripts that init just act as an initializer and call into functions organized appropriately in other files.
- If you have python dependencies, create a [requirements.txt](https://pip.pypa.io/en/latest/cli/pip_freeze/) listing any python dependencies.

### Submitting to the Plugin Manager

If your plugin was created as described above, there's only two steps to get it submitted to the plugin manager!

1. First, create a release either [manually](https://binary.ninja/2019/07/04/plugin-manager-2.0.html#5-create-a-release) or using our [release helper](https://github.com/Vector35/release_helper).
1. Next, just [file an issue](https://github.com/Vector35/community-plugins/issues/new/choose) letting us know about your plugin.

For future releases all you need to do is increment the version and create a new release.

### Using Your Own Plugin Repository

The simplest way to run your own plugin repository is to duplicate the structure of [https://github.com/vector35/community-plugins](https://github.com/vector35/community-plugins). Specifically, the [plugins.json](https://github.com/Vector35/community-plugins/blob/master/plugins.json), as [listing.json](https://github.com/Vector35/community-plugins/blob/master/listing.json) is used along with [generate_index.py](https://github.com/Vector35/community-plugins/blob/master/generate_index.py) to create that file.

Once you've created your test repository, use the `pluginManager.unofficialName` and `pluginManager.unofficialUrl` settings to add your third-party repository.

The [`add_repository`](https://api.binary.ninja/binaryninja.pluginmanager-module.html#binaryninja.pluginmanager.RepositoryManager.add_repository) API can also be used to add the repository, though it [may require manual creation of the repository folder](https://github.com/Vector35/binaryninja-api/issues/2987).
### Testing

It's useful to be able to reload your plugin during testing. On the Commercial edition of Binary Ninja, this is easily accomplished with a stand-alone headless install using `import binaryninja` after [installing the API](https://github.com/Vector35/binaryninja-api/blob/dev/scripts/install_api.py).  (install_api.py is included in each platforms respective [installation folder](../guide/#binary-path))

For other plugins, we recommend the following workflow from the scripting console which enables easy iteration and testing:

```python
import pluginname
import importlib
importlib.reload(pluginname);pluginname.callbackmethod(bv)
```

Then just `[UP] [ENTER]` to trigger the reload when the plugin has changed.

## Writing plugins using other IDEs

Even though non-commercial licenses don't have headless automation, the [install API](https://github.com/Vector35/binaryninja-api/blob/dev/scripts/install_api.py) script (which is included in the installation directory) allows you to add the binaryninja module to your python environment. Once you do that, you should get automatic completion in any editor that supports it even on non-commercial! Of course, on commercial and enterprise installations, the script is even more useful, allowing for headless scripts with your existing python interpreter.

## Debugging using other IDEs

If you wish to debug your python scripts, there are a few methods specific to different IDEs:

### Remote debugging with VSCode:

1. Run `pip install --user debugpy` in the Python interpreter you have selected in Binary Ninja Settings.
1. In VSCode, open the Run and Debug sidebar.
1. Create a `launch.json` file if one does not already exist, or open `launch.json` if one does.
1. In `launch.json`, select Add Configuration > Python > Remote Attach
1. Enter a host of `localhost` and any port
1. Set the path mapping to be from `/` to `/` (Windows: `C:\\` to `C:\\`)
1. Open Binary Ninja
1. Use `connect_vscode_debugger(port=12345)` in the Python Console, using whichever port you selected in `launch.json`.
1. In VSCode, start debugging. You should see the bottom toolbar change color, and the debugger should be attached.

### Remote debugging with IntelliJ PyCharm

**WARNING**: Does not work on PyCharm Community, requires PyCharm Professional

1. In PyCharm, add a Run Configuration for Python Debug Server. Give it a name and choose a port and host.
1. Run the `pip install` script displayed in the Run Configuration using whichever python interpreter you have selected for Binary Ninja.
1. In PyCharm, start debugging. You should see "Waiting for process connection..." in the Debugger panel.
1. Open Binary Ninja
1. Use `connect_pycharm_debugger(port=12345)` in the Python Console, using whichever port you selected in the Run Configuration. You should now see "Connected" in the PyCharm Debugger panel.

# Writing Native Plugins

Unfortunately, native plugins are not supported in the plugin manager at this time. It's possible to work-around this limitation by pre-building for all three platforms a native plugin and using a python plugin that acts as a loader for the native plugin, but no such examples exist.

## Matching API versions

One issue with building a native plugin is that you'll want your plugin to be able to match the API of a given dev build. This information is contained in a file named `api_REVISION.txt` that exists in the root install folder for Linux, the `Contents/Resources` sub-folder on MacOS, and the root installation folder on Windows.

## Examples

Several native plugin examples exist:

 - [ObjectiveNinja](https://github.com/jonpalmisc/ObjectiveNinja)
 - [BinExport](https://github.com/google/binexport#binary-ninja) (Used with BinDiff)
 - [Binliner](https://github.com/holmesmr/binliner)