Skip to content

Commit 7e2ac5f

Browse files
IDA: Add a simple action to generate spec files (#94)
* IDA: Add a simple action to generate spec files * docs: Update the example instructions
1 parent b9d73b1 commit 7e2ac5f

File tree

2 files changed

+96
-4
lines changed

2 files changed

+96
-4
lines changed

README.md

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,11 +85,25 @@ These depend on tools like [IDA Pro](https://www.hex-rays.com/products/ida) or [
8585

8686
Given that we have either of the above, we can try out Anvill's machine code lifter on a binary of our choice.
8787

88+
**First, we generate a JSON specification from a binary:**
89+
90+
From the CLI:
91+
8892
```shell
89-
# First, we generate a JSON specification from a binary
90-
python3.8 -m anvill --bin_in my_binary --spec_out spec.json
91-
# Finally we produce LLVM bitcode from a JSON specification
92-
./remill-build/tools/anvill/anvill-lift-json-*.0 --spec spec.json --bc_out out.bc
93+
python3 -m anvill --bin_in my_binary --spec_out spec.json
94+
```
95+
96+
With the IDA plugin:
97+
1. Open the binary inside IDA
98+
2. Select **Run script** in the **File** menu
99+
3. Open the `examples/ida_plugin_action.py`
100+
4. In the disasm window, place the cursor inside a function
101+
5. Right click and select **Generate ANVILL spec file**
102+
103+
**Finally we produce LLVM bitcode from a JSON specification**
104+
105+
```
106+
./build/anvill-decompile-json-*.0 --spec spec.json --bc_out out.bc
93107
```
94108

95109
### Docker image

examples/ida_plugin_action.py

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# Copyright (c) 2021-present Trail of Bits, Inc.
2+
3+
import ida_funcs
4+
import ida_kernwin
5+
import idautils
6+
7+
import anvill
8+
import json
9+
10+
class generate_anvill_spec_t(ida_kernwin.action_handler_t):
11+
def activate(self, ctx):
12+
user_input = ida_kernwin.ask_yn(ida_kernwin.ASKBTN_YES, "Would you like to export all functions?")
13+
if user_input == ida_kernwin.ASKBTN_CANCEL:
14+
return 1
15+
16+
output_file_name_hint = ""
17+
18+
p = anvill.get_program()
19+
20+
if user_input == ida_kernwin.ASKBTN_NO:
21+
screen_cursor = ida_kernwin.get_screen_ea()
22+
function_name = ida_funcs.get_func_name(screen_cursor)
23+
if function_name is None:
24+
print("ANVILL: The cursor is not located inside a function")
25+
return 1
26+
27+
output_file_name_hint = function_name + ".json"
28+
29+
try:
30+
p.add_function_definition(screen_cursor)
31+
32+
except:
33+
print("ANVILL: Failed to process the function at address {0:x}".format(screen_cursor))
34+
return 1
35+
36+
else:
37+
function_address_list = idautils.Functions()
38+
for function_address in function_address_list:
39+
try:
40+
p.add_function_definition(function_address)
41+
42+
except:
43+
print("ANVILL: Failed to process the function at address {0:x}".format(function_address))
44+
45+
output_file_name_hint = "program.json"
46+
47+
output_path = ida_kernwin.ask_file(True, output_file_name_hint, "Select where to save the spec file")
48+
if not output_path:
49+
return 1
50+
51+
output = json.dumps(p.proto(), sort_keys=False, indent=2)
52+
53+
print("ANVILL: Saving the spec file to {}".format(output_path))
54+
with open(output_path, "w") as f:
55+
f.write(output)
56+
57+
def update(self, ctx):
58+
if ctx.widget_type == ida_kernwin.BWN_DISASM:
59+
return ida_kernwin.AST_ENABLE_FOR_WIDGET
60+
61+
return ida_kernwin.AST_DISABLE_FOR_WIDGET
62+
63+
ACTION_NAME = "generate-anvill-spec-file"
64+
65+
ida_kernwin.register_action(
66+
ida_kernwin.action_desc_t(
67+
ACTION_NAME,
68+
"Generate ANVILL spec file",
69+
generate_anvill_spec_t(),
70+
"Ctrl+H"))
71+
72+
class popup_hooks_t(ida_kernwin.UI_Hooks):
73+
def finish_populating_widget_popup(self, w, popup):
74+
if ida_kernwin.get_widget_type(w) == ida_kernwin.BWN_DISASM:
75+
ida_kernwin.attach_action_to_popup(w, popup, ACTION_NAME, None)
76+
77+
hooks = popup_hooks_t()
78+
hooks.hook()

0 commit comments

Comments
 (0)