Skip to content

Commit 3c9f7e2

Browse files
ippm: move detailed readme into their own docs based on user
1 parent b4f72e7 commit 3c9f7e2

File tree

3 files changed

+379
-340
lines changed

3 files changed

+379
-340
lines changed

plugins/plugin-manager/README.md

Lines changed: 8 additions & 340 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ $ ippm update-all
1717
$ ippm remove williballenthin-hint-calls-ida-plugin
1818
```
1919

20+
We'll also work to provide an IDA-native GUI for list/install/upgrade/removing plugins in the future.
21+
2022
Available plugins:
2123

2224
| Name | Summary |
@@ -31,345 +33,11 @@ Available plugins:
3133

3234
Each of these you can install via: `ippm install ...`.
3335

34-
Read on for details:
35-
- [Installation Instructions](#installation)
36-
- [Command-Line Tool (`ippm`)](#command-line-tool-ippm)
37-
- [Packaging Plugins](#packaging-plugins)
38-
- [Entry Points](#entry-points)
39-
40-
## Installation
41-
42-
There are two steps:
43-
44-
1. to fetch the plugin manager
45-
2. to register the plugin manager with IDA Pro
46-
47-
Then you can install plugins via `pip` directly.
48-
49-
### 1. Fetch the package from PyPI
50-
51-
The plugin manager is distributed via PyPI, so install it via `pip`:
52-
53-
```bash
54-
$ pip install idapro-plugin-manager
55-
```
56-
57-
Make sure to use the `pip` from your IDAPython installation, which [I recommend to be a virtual environment](https://williballenthin.com/post/using-a-virtualenv-for-idapython/).
58-
59-
You can find the location of the `pip` executable by running the following within your IDAPython console in IDA Pro:
60-
61-
```python
62-
Python>import subprocess
63-
Python>subprocess.run(["which", "pip"], capture_output=True).stdout.decode("utf-8").strip()
64-
'/Users/user/.idapro/venv/bin/pip'
65-
```
66-
67-
(TODO: check this works on Windows, too.)
68-
69-
### 2. Register the plugin manager in IDA Pro
70-
71-
Run the following command to automatically register the plugin manager with IDA Pro:
72-
73-
```bash
74-
$ ippm register
75-
```
76-
77-
This installs the bootstrap plugin to your IDA Pro plugins directory. You only have to do this once, even if you upgrade IDA.
78-
79-
## Command-Line Tool (`ippm`)
80-
81-
The IDA Pro Plugin Manager also comes with a command-line tool, `ippm`, to help you discover and manage plugins.
82-
83-
### Listing Available Plugins
84-
85-
To see a list of IDA Pro plugins available on PyPI, use the `list` command:
86-
87-
```bash
88-
$ ippm list
89-
Available IDA Pro Plugins on PyPI
90-
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
91-
┃ Name ┃ Last Release ┃ Summary ┃
92-
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
93-
│ basic-ida-plugin (installed) │ 0.1.0 (Jun 02, 2025) │ Example IDA Plugin │
94-
│ multifile-ida-plugin │ 0.1.0 (Jun 02, 2025) │ Example IDA Plugin with multiple files │
95-
│ williballenthin-colorize-calls-ida-plugin │ 0.1.0 (Jun 03, 2025) │ IDA Pro plugin to colorize call │
96-
│ │ │ instructions and add a prefix │
97-
│ williballenthin-hint-calls-ida-plugin │ 0.1.2 (Jun 03, 2025) │ IDA Pro plugin to display popup │
98-
│ │ │ function hints for the referenced │
99-
│ │ │ calls and strings │
100-
│ williballenthin-navband-visited-ida-plugin │ 0.1.0 (Jun 03, 2025) │ IDA Pro plugin to highlight visited │
101-
│ │ │ addresses in the navigation band. │
102-
│ williballenthin-tag-func-ida-plugin │ 0.1.0 (Jun 03, 2025) │ IDA Pro plugin for tagging functions │
103-
│ │ │ into folders │
104-
└────────────────────────────────────────────┴──────────────────────┴────────────────────────────────────────┘
105-
```
106-
107-
This command queries PyPI for packages that appear to be IDA Pro plugins (based on naming conventions like `idapro-plugin-*`, `*-ida-plugin`, etc.).
108-
109-
110-
### Showing Plugin Details
111-
112-
To view detailed information about a specific plugin, use the `show` command followed by the plugin's name as it appears on PyPI:
113-
114-
```bash
115-
$ ippm show williballenthin-tag-func-ida-plugin
116-
┌─────────────────────────────┬──────────────────────────────────────────────────────────────────────────────┐
117-
│ Name │ williballenthin-tag-func-ida-plugin │
118-
│ Version │ 0.1.0 │
119-
│ Summary │ IDA Pro plugin for tagging functions into folders │
120-
│ Author │ Willi Ballenthin <willi.ballenthin@gmail.com>
121-
│ License │ Apache-2.0 │
122-
│ Requires Python │ >=3.9 │
123-
│ Package URL │ https://pypi.org/project/williballenthin-tag-func-ida-plugin/ │
124-
│ Project URL │ https://pypi.org/project/williballenthin-tag-func-ida-plugin/ │
125-
│ Release URL │ https://pypi.org/project/williballenthin-tag-func-ida-plugin/0.1.0/ │
126-
│ Version History │ 0.1.0 Jun 03, 2025 │
127-
│ Description (text/markdown) │ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ │
128-
│ │ ┃ Tag Function IDA Pro Plugin ┃ │
129-
│ │ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ │
130-
│ │ │
131-
│ │ IDA Pro plugin for tagging functions into folders. │
132-
│ │ │
133-
│ │ │
134-
│ │ Installation │
135-
│ │ │
136-
│ │ Assuming you have the IDA Pro Plugin Manager, install via pip: │
137-
│ │ │
138-
│ │ │
139-
│ │ pip install williballenthin-tag-func-ida-plugin │
140-
│ │ │
141-
│ │ │
142-
│ │ Make sure to use the pip from your IDAPython installation. │
143-
└─────────────────────────────┴──────────────────────────────────────────────────────────────────────────────
144-
```
145-
146-
### Installing Plugins
147-
148-
To install a plugin:
149-
150-
```bash
151-
$ ippm install multifile-ida-plugin
152-
Installing plugin: multifile-ida-plugin
153-
Successfully installed multifile-ida-plugin
154-
Collecting multifile-ida-plugin
155-
Downloading multifile_ida_plugin-0.1.0-py3-none-any.whl.metadata (1.8 kB)
156-
Downloading multifile_ida_plugin-0.1.0-py3-none-any.whl (2.8 kB)
157-
Installing collected packages: multifile-ida-plugin
158-
Successfully installed multifile-ida-plugin-0.1.0
159-
```
160-
36+
As a user of IDA Pro, learn more:
37+
- [Installation Instructions](./doc/as-a-user.md#installation)
38+
- [Command-Line Tool (`ippm`)](./doc/as-a-user.md#command-line-tool-ippm)
16139

162-
### Updating Plugins
163-
To update a plugin to the latest version:
164-
165-
```bash
166-
$ ippm update multifile-ida-plugin
167-
Updating plugin: multifile-ida-plugin
168-
multifile-ida-plugin is already up to date
169-
Requirement already satisfied: multifile-ida-plugin in ./.venv/lib/python3.12/site-packages (0.1.0)
170-
```
171-
172-
### Updating All Plugins
173-
174-
To update all installed plugins to their latest versions:
175-
176-
```bash
177-
$ ippm update-all
178-
Finding installed IDA Pro plugins...
179-
Found 2 installed IDA Pro plugin(s):
180-
- basic-ida-plugin
181-
- multifile-ida-plugin
182-
183-
Checking for updates...
184-
basic-ida-plugin: 0.1.0 (up to date)
185-
multifile-ida-plugin: 0.1.0 (up to date)
186-
187-
All plugins are up to date!
188-
```
189-
190-
### Removing Plugins
191-
192-
To remove an installed plugin:
193-
194-
```bash
195-
$ ippm remove multifile-ida-plugin
196-
Removing plugin: multifile-ida-plugin
197-
Successfully removed multifile-ida-plugin
198-
```
199-
200-
## Packaging Plugins
201-
202-
Plugins are distributed via PyPI, which is usually (but not always) used for Python packages.
203-
We use Python-style metadata, such as a `pyproject.toml` file, to describe the plugin.
204-
205-
By adding an "entry point" for the `idapro.plugins` group,
206-
we can register a plugin with the IDA Pro Plugin Manager.
207-
208-
Here are some example plugins:
209-
- [basic-ida-plugin](/plugins/plugin-manager/examples/basic-ida-plugin/)
210-
- [multifile-ida-plugin](/plugins/plugin-manager/examples/multifile-ida-plugin/)
211-
212-
Let's walk through `basic-ida-plugin`, which is a simple IDA plugin with a single file: `hello.py`.
213-
(Recall that IDAPython plugins should have a function named `PLUGIN_ENTRY` that's used to initialize the plugin.)
214-
215-
The package structure looks like:
216-
217-
basic-ida-plugin/
218-
├── hello.py
219-
└── pyproject.toml
220-
221-
with the `pyproject.toml` contents:
222-
223-
```toml
224-
[project]
225-
name = "basic-ida-plugin"
226-
...
227-
228-
[project.entry-points.'idapro.plugins']
229-
idapython = 'hello'
230-
```
231-
232-
and `hello.py` contents:
233-
234-
```py
235-
import idaapi
236-
237-
class hello_plugmod_t(idaapi.plugmod_t):
238-
def run(self, arg):
239-
print("Hello world! (py)")
240-
return 0
241-
242-
class hello_plugin_t(idaapi.plugin_t):
243-
flags = idaapi.PLUGIN_UNL | idaapi.PLUGIN_MULTI
244-
comment = "This is a comment"
245-
help = "This is help"
246-
wanted_name = "Hello Python plugin"
247-
wanted_hotkey = "Alt-F8"
248-
249-
def init(self):
250-
print("hello from init")
251-
return hello_plugmod_t()
252-
253-
def PLUGIN_ENTRY():
254-
return hello_plugin_t()
255-
```
256-
257-
The `pyproject.toml` entry point references `hello` Python module that contains the plugin code.
258-
Our plugin manager knows how to inspect all installed Python packages
259-
and find plugins via the metadata, including `basic-ida-plugin`.
260-
261-
I packaged this plugin and uploaded it to PyPI, so you can install it like this:
262-
263-
pip install basic-ida-plugin
264-
265-
If you have a local plugin in development, you can use other Python idioms, like:
266-
267-
pip install --editable /path/to/basic-ida-plugin/source
268-
269-
There is a more comprehensive miration guide found in [doc/migrating-a-plugin.md](doc/migrating-a-plugin.md).
270-
271-
272-
# Entry Points
273-
274-
Each package contains a single plugin.
275-
The keys within the entry points section describe the sort of plugin thats available:
276-
- `idapython` for IDAPython-based plugins
277-
- target triple for compiled plugins, like `aarch64-apple-darwin`
278-
279-
## Examples
280-
281-
For a single Python file named `hello.py` (like above):
282-
283-
```toml
284-
[project.entry-points.'idapro.plugins']
285-
idapython = 'hello' # note: there's no file extension
286-
```
287-
288-
For a plugin within a larger Python package, such as for the default plugin
289-
provided by capa in [capa.ida.plugin](https://github.com/mandiant/capa/blob/master/capa/ida/plugin/__init__.py):
290-
291-
```toml
292-
[project.entry-points.'idapro.plugins']
293-
idapython = 'capa.ida.plugin'
294-
```
295-
296-
In this scenario, the entry point section would be in capa's `pyproject.toml`,
297-
so you'd install `capa` within your IDAPython virtualenv and the plugin would
298-
now be available within IDA.
299-
300-
Since the name `capa` doesn't match the `idapro-plugin-*` prefix for IDA plugins
301-
available on PyPI, it would have to be registered with the extras list.
302-
303-
### Native plugins
304-
305-
For a compiled plugin, create a Python package with the compiled artifacts stored within the "Python" package:
306-
307-
```sh
308-
❯ eza --tree --level=2 --long --git
309-
native-ida-plugin
310-
├── bin
311-
│ └── native_ida_plugin
312-
│ ├── __init__.py
313-
│ ├── mysample.so
314-
│ ├── mysample.dll
315-
│ ├── mysample_aarch64.dylib
316-
│ └── mysample_x86_64.dylib
317-
├── pyproject.toml
318-
└── README.md
319-
```
320-
321-
And use target triple names as the entry point keys to specify filenames for the compiled artifacts:
322-
323-
```toml
324-
[project.entry-points.'idapro.plugins']
325-
aarch64-apple-darwin = "native_ida_plugin:mysample_aarch64" # note: extensions are automatically appended
326-
x86_64-apple-darwin = "native_ida_plugin:mysample_x86_64"
327-
x86_64-unknown-linux = "native_ida_plugin:mysample"
328-
x86_64-pc-windows = "native_ida_plugin:mysample"
329-
330-
[build-system]
331-
requires = ["setuptools>=61.0"]
332-
build-backend = "setuptools.build_meta"
333-
334-
[tool.setuptools]
335-
package-dir = {"" = "bin"} # Python package data is found in "bin/" directory.
336-
# "src/" is the default, but we'll use "bin/" for all this binary data.
337-
338-
[tool.setuptools.package-data]
339-
"native_ida_plugin" = [
340-
# filenames relative to: bin/native_ida_plugin/
341-
"mysample.*",
342-
"mysample_aarch64.*",
343-
"mysample_x86_64.*",
344-
]
345-
```
346-
347-
Unfortunately the entry point value (`native_ida_plugin:mysample_aarch64`) cannot contain `/` or `.`,
348-
so the compiled artifacts are best placed in that package root directory.
349-
Its also possible to use a layout like `native_ida_plugin.aarch64:mysample`.
350-
351-
Technically, the entry point value is supposed to point to a Python object.
352-
We abuse this a bit, because we assign a specific meaning to entry point keys like `aarch64-apple-darwin`.
353-
To make this safe, add package level variables to `bin/native_ida_plugin/__init__.py`:
354-
355-
```py
356-
mysample_aarch64 = None
357-
mysample_x86_64 = None
358-
mysample = None
359-
```
360-
361-
But this is not strictly necessary today.
362-
363-
# Native Dependencies
364-
365-
(this is experimental/not implemented yet/just an idea)
366-
367-
Extend the search path for libraries like this:
368-
369-
```toml
370-
[tool.idapro.plugins.lib]
371-
'aarch64-apple-darwin' = 'lib/darwin-aarch64/'
372-
'x86_64-apple-darwin' = 'lib/darwin-x86_64/'
373-
```
40+
As a plugin author, learn more about how to package your IDA Pro plugins for distribution:
41+
- [Packaging Plugins](./doc/as-a-plugin-author.md#packaging-plugins)
42+
- [Entry Points](./doc/as-a-plugin-author.md#entry-points)
37443

375-
Which is useful if your plugin depends on additional native libraries; for example, OpenSSL.

0 commit comments

Comments
 (0)