Skip to content

Commit 86befe1

Browse files
authored
Merge pull request #9 from WhatTheFuzz/feature/docs
Add instructions on how to add the API key.
2 parents 8208c29 + a286e47 commit 86befe1

4 files changed

Lines changed: 77 additions & 6 deletions

File tree

README.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,73 @@ If you're installing this as a standalone plugin, you can place (or sym-link)
1010
this in BinaryNinja's plugin path. Default paths are detailed on
1111
[Vector 35's documentation][default-plugin-dir].
1212

13+
## API Key
14+
15+
This requires an [API token from OpenAI][token]. The plugin checks for the API
16+
key in two ways (in this order).
17+
18+
First, it checks the environment variable `OPENAI_API_KEY`, which you can set
19+
inside of Binary Ninja's Python console like so:
20+
21+
```python
22+
import os
23+
os.environ["OPENAI_API_KEY"] = "INSERT KEY HERE"
24+
```
25+
26+
Or you can write it to a file. The file is set in [entry.py][entry] and is a
27+
parameter to the Agent class. By default it checks for the file
28+
`~/.openai/api_key.txt`. You can add your API token like so:
29+
30+
```shell
31+
mkdir ~/.openai
32+
echo -n "INSERT KEY HERE" > ~/.openai/api_key.txt
33+
```
34+
35+
Note that if you have both set, the plugin defaults to the environment variable.
36+
If your API token is invalid, you'll receive the following error:
37+
38+
```python
39+
openai.error.AuthenticationError: Incorrect API key provided: <BAD KEY HERE>.
40+
You can find your API key at https://beta.openai.com.
41+
```
42+
43+
## Usage
44+
45+
After installation, you can right-click on any function in Binary Ninja and
46+
select `Plugins > OpenAI > What Does this Function Do (HLIL)?`. Alternatively,
47+
select a function in Binary Ninja (by clicking on any instruction in the
48+
function) and use the menu bar options
49+
`Plugins > OpenAI > What Does this Function Do (HLIL)?`. If your cursor has
50+
anything else selected other than an instruction inside a function, `OpenAI`
51+
will not appear as a selection inside the `Plugins` menu. This can happen if
52+
you've selected data or instructions that Binary Ninja determined did not belong
53+
inside of the function.
54+
55+
The output will appear in Binary Ninja's Log like so:
56+
57+
![The output of running the plugin.](./resources/output.png)
58+
59+
## OpenAI Model
60+
61+
By default, the plugin uses the `text-davinci-003` model, you can tweak this
62+
inside of [entry.py][entry].
63+
64+
## Known Issues
65+
66+
The query does not use Python's [asyncio][asyncio] and thus blocks the main
67+
thread. You may be unable to interact with the Binary Ninja UI while the query
68+
is waiting to be resolved. In some cases, your operating system may detect that
69+
Binary Ninja has stopped responding and ask you to Force Quit it. I have not
70+
experience any egregiously long hangs, however. This is documented in issue
71+
[#8][issue-8].
72+
1373
## License
1474

1575
This project is licensed under the [MIT license][license].
1676

1777
[default-plugin-dir]:https://docs.binary.ninja/guide/plugins.html
78+
[token]:https://beta.openai.com/account/api-keys
79+
[entry]:./entry.py
80+
[asyncio]:https://docs.python.org/3/library/asyncio.html
81+
[issue-8]:https://github.com/WhatTheFuzz/binaryninja-openai/issues/8
1882
[license]:./LICENSE

resources/output.png

81.7 KB
Loading

src/agent.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from binaryninja.lowlevelil import LowLevelILFunction
1010
from binaryninja.mediumlevelil import MediumLevelILFunction
1111
from binaryninja.highlevelil import HighLevelILFunction
12+
from binaryninja import log
1213

1314
from .exceptions import InvalidEngineException
1415

@@ -58,11 +59,17 @@ def read_api_key(self, filename: Optional[Path]=None) -> str:
5859
if os.getenv('OPENAI_API_KEY'):
5960
return os.getenv('OPENAI_API_KEY')
6061
if filename:
61-
with open(filename, mode='r', encoding='ascii') as api_key_file:
62-
return api_key_file.read()
63-
else:
64-
raise APIError('No API key found. Please set the environment '
65-
'variable OPENAI_API_KEY to your API key.')
62+
log.log_info(f'No API key detected under the environment variable '
63+
f'OPENAI_API_KEY. Reading API key from {filename}')
64+
try:
65+
with open(filename, mode='r', encoding='ascii') as api_key_file:
66+
return api_key_file.read()
67+
except FileNotFoundError as error:
68+
log.log_error(f'Could not find API key file at {filename}.')
69+
70+
raise APIError('No API key found. Please set the environment '
71+
'variable OPENAI_API_KEY to your API key, or write '
72+
'it to ~/openai/api_key.txt.')
6673

6774

6875
def instruction_list(self, function: Union[LowLevelILFunction,

src/entry.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from binaryninja import BinaryView, Function
33
from . agent import Agent
44

5-
API_KEY_PATH = Path.home() / Path('.openai/api_key')
5+
API_KEY_PATH = Path.home() / Path('.openai/api_key.txt')
66

77
# We don't use the bv argument, but it gets passed in by the PluginCommand.
88
# pylint: disable=unused-argument

0 commit comments

Comments
 (0)