-
Notifications
You must be signed in to change notification settings - Fork 32
/
Copy pathcli_acfg_disasm.py
126 lines (105 loc) · 5.5 KB
/
cli_acfg_disasm.py
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
##############################################################################
# #
# Code for the USENIX Security '22 paper: #
# How Machine Learning Is Solving the Binary Function Similarity Problem. #
# #
# MIT License #
# #
# Copyright (c) 2019-2022 Cisco Talos #
# #
# Permission 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: #
# #
# The above copyright notice and this permission notice shall be #
# included in all copies or substantial portions of the Software. #
# #
# THE 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. #
# #
# cli_acfg_disasm.py - Call IDA_acfg_disasm.py IDA script. #
# #
##############################################################################
import click
import json
import subprocess
import time
from os import getenv
from os.path import abspath
from os.path import dirname
from os.path import isfile
from os.path import join
IDA_PATH = getenv("IDA_PATH", "/home/user/idapro-7.3/idat64")
IDA_PLUGIN = join(dirname(abspath(__file__)), 'IDA_acfg_disasm.py')
REPO_PATH = dirname(dirname(dirname(abspath(__file__))))
LOG_PATH = "acfg_disasm_log.txt"
@click.command()
@click.option('-j', '--json-path', required=True,
help='JSON file with selected functions.')
@click.option('-o', '--output-dir', required=True,
help='Output directory.')
def main(json_path, output_dir):
"""Call IDA_acfg_disasm.py IDA script."""
try:
if not isfile(IDA_PATH):
print("[!] Error: IDA_PATH:{} not valid".format(IDA_PATH))
print("Use 'export IDA_PATH=/full/path/to/idat64'")
return
print("[D] JSON path: {}".format(json_path))
print("[D] Output directory: {}".format(output_dir))
if not isfile(json_path):
print("[!] Error: {} does not exist".format(json_path))
return
with open(json_path) as f_in:
jj = json.load(f_in)
success_cnt, error_cnt = 0, 0
start_time = time.time()
for idb_rel_path in jj.keys():
print("\n[D] Processing: {}".format(idb_rel_path))
# Convert the relative path into a full path
idb_path = join(REPO_PATH, idb_rel_path)
print("[D] IDB full path: {}".format(idb_path))
if not isfile(idb_path):
print("[!] Error: {} does not exist".format(idb_path))
continue
cmd = [IDA_PATH,
'-A',
'-L{}'.format(LOG_PATH),
'-S{}'.format(IDA_PLUGIN),
'-Oacfg_disasm:{}:{}:{}'.format(
json_path,
idb_rel_path,
output_dir),
idb_path]
print("[D] cmd: {}".format(cmd))
proc = subprocess.Popen(
cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = proc.communicate()
if proc.returncode == 0:
print("[D] {}: success".format(idb_path))
success_cnt += 1
else:
print("[!] Error in {} (returncode={})".format(
idb_path, proc.returncode))
error_cnt += 1
end_time = time.time()
print("[D] Elapsed time: {}".format(end_time - start_time))
with open(LOG_PATH, "a+") as f_out:
f_out.write("elapsed_time: {}\n".format(end_time - start_time))
print("\n# IDBs correctly processed: {}".format(success_cnt))
print("# IDBs error: {}".format(error_cnt))
except Exception as e:
print("[!] Exception in cli_acfg_disasm\n{}".format(e))
if __name__ == '__main__':
main()