Skip to content

Commit 5376d95

Browse files
committed
fixed autounstrip to work like portal
1 parent e548efa commit 5376d95

3 files changed

Lines changed: 53 additions & 26 deletions

File tree

features/auto_unstrip/auto_unstrip.py

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from binaryninja import BinaryView, log_info, log_error, Symbol, SymbolType
2-
from reait.api import RE_authentication, RE_search, RE_nearest_symbols_batch, RE_analyze_functions
2+
from reait.api import RE_authentication, RE_search, RE_nearest_symbols_batch, RE_analyze_functions, RE_name_score
33
from concurrent.futures import ThreadPoolExecutor, as_completed
44
from typing import List, Dict, Tuple
55
import math
@@ -36,22 +36,28 @@ def _rename_function(self, bv: BinaryView, addr: int, new_name: str, new_name_ma
3636
def _process_batch(self, function_ids: List[int], id_to_addr: Dict[int, int], bv: BinaryView) -> Tuple[int, List[str]]:
3737
"""Process a batch of function IDs and return the number of renamed functions"""
3838
try:
39-
ret = RE_nearest_symbols_batch(
39+
functions_by_distance = RE_nearest_symbols_batch(
4040
function_ids=function_ids,
4141
distance=self.auto_unstrip_distance,
4242
debug_enabled=True,
4343
nns=1
4444
).json()["function_matches"]
4545

46+
functions = []
47+
for function in functions_by_distance:
48+
functions.append({"function_id": function['origin_function_id'], "function_name": function['nearest_neighbor_function_name']})
49+
log_info(f"RevEng.AI | Functions by distance: {functions}")
50+
functions_by_score = RE_name_score(functions).json()["data"]
51+
log_info(f"RevEng.AI | Functions by score: {functions_by_score}")
4652
renamed_count = 0
4753
errors = []
48-
for result in ret:
54+
for result in functions_by_distance:
4955
try:
5056
func_id = result['origin_function_id']
5157
func_addr = id_to_addr.get(func_id)
5258
if not func_addr:
5359
continue
54-
60+
5561
new_name = result['nearest_neighbor_function_name']
5662
if not new_name or new_name.startswith(("sub_", "FUN_")):
5763
continue
@@ -60,8 +66,18 @@ def _process_batch(self, function_ids: List[int], id_to_addr: Dict[int, int], bv
6066
if not new_name_mangled or new_name_mangled.startswith(("sub_", "FUN_")):
6167
continue
6268

63-
if self._rename_function(bv, func_addr, new_name, new_name_mangled):
64-
renamed_count += 1
69+
for function in functions_by_score:
70+
if function['function_id'] == func_id:
71+
if function['box_plot']["average"] < 0.9:
72+
log_info(f"RevEng.AI | Function {function['function_id']} has a score of {function['box_plot']["average"]:.2f} for name {function['function_name']}, skipping")
73+
break
74+
else:
75+
log_info(f"RevEng.AI | Function {function['function_id']} has a score of {function['box_plot']["average"]:.2f} for name {function['function_name']}, renaming")
76+
if self._rename_function(bv, func_addr, new_name, new_name_mangled):
77+
renamed_count += 1
78+
break
79+
80+
6581
except Exception as e:
6682
errors.append(str(e))
6783

@@ -76,16 +92,17 @@ def auto_unstrip(self, bv: BinaryView):
7692

7793
self.base_addr = bv.image_base
7894
self.path = bv.file.filename
95+
binary_id = self.config.get_binary_id(bv)
7996
log_info(f"RevEng.AI | Path: {self.path}")
80-
log_info(f"RevEng.AI | Binary ID: {self.config.binary_id}")
97+
log_info(f"RevEng.AI | Binary ID: {binary_id}")
8198

8299
results = RE_search(fpath=self.path).json()["query_results"]
83100
log_info(f"RevEng.AI | Search Results: {results}")
84101

85102
if not len(results):
86103
raise Exception("Binary not found in RevEng.AI, try uploading again.")
87104

88-
analyzed_functions = RE_analyze_functions(self.path, self.config.binary_id).json()["functions"]
105+
analyzed_functions = RE_analyze_functions(self.path, binary_id).json()["functions"]
89106
function_ids = [func["function_id"] for func in analyzed_functions]
90107

91108
id_to_addr = {

features/choose_source/choose_source.py

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,14 @@ def __init__(self, config):
1111
def choose_source(self, bv: BinaryView, chose: str):
1212
try:
1313
log_info(f"RevEng.AI | Chose: {chose}")
14-
binary_id = chose.split("ID: ")[1].split(" -")[0]
15-
log_info(f"RevEng.AI | Binary ID: {self.config.binary_id}")
16-
# TODO: implement array like to store binary id and binaryhash and filesize
17-
18-
self.config.set_current_info(binary_id)
14+
new_binary_id = int(chose.split("ID: ")[1].split(" -")[0])
15+
binary_id = self.config.get_binary_id(bv)
16+
if binary_id == new_binary_id:
17+
log_info("RevEng.AI | Binary ID is already set to the chosen one.")
18+
return True
19+
20+
log_info(f"RevEng.AI | Changing Binary ID: {binary_id} to {new_binary_id}")
21+
self.config.set_current_info(new_binary_id)
1922

2023
return True
2124
except Exception as e:
@@ -25,9 +28,9 @@ def choose_source(self, bv: BinaryView, chose: str):
2528
def get_analysis(self, bv: BinaryView):
2629
try:
2730
log_info(f"RevEng.AI | Path: {bv.file.filename}")
28-
log_info(f"RevEng.AI | Binary ID: {self.config.binary_id}")
29-
30-
# TODO: check if the binary is already in the database
31+
binary_id = self.config.get_binary_id(bv)
32+
log_info(f"RevEng.AI | Current Binary ID: {binary_id}")
33+
3134

3235
results = RE_search(fpath=bv.file.filename).json()["query_results"]
3336

@@ -37,9 +40,11 @@ def get_analysis(self, bv: BinaryView):
3740
options = []
3841
for result in results:
3942
option = f"Name: {result['binary_name'][:10]}{'...' if len(result['binary_name']) > 10 else ''} - ID: {result['binary_id']} - Model: {result['model_name']} - Created at: {result['creation'].split('T')[0]} {result['creation'].split('T')[1].split('.')[0]}"
40-
options.append(option)
4143
log_info(f"RevEng.AI | Analysis: {option}")
42-
# TODO: put the current binary id first in the list
44+
if result['binary_id'] == binary_id:
45+
options.insert(0, option)
46+
else:
47+
options.append(option)
4348

4449
return options
4550
except Exception as e:

features/configuration/config.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@ def __init__(self):
99
self.host = ""
1010
self.sha256 = ""
1111
self.is_configured = False
12-
self.binary_id = 0
13-
self.analysis_id = 0
1412
self._load_config()
1513

1614

@@ -46,7 +44,7 @@ def save_config(self) -> bool:
4644
log_info(f"RevEng.AI | Testing configuration: {self.host} {self.api_key[:4]}...")
4745

4846
if not self.check_auth():
49-
raise(f"RevEng.AI | Authentication failed.")
47+
raise Exception(f"RevEng.AI | Authentication failed.")
5048

5149
self.is_configured = True
5250

@@ -83,34 +81,34 @@ def get_all_analyses(self):
8381
all_analyses = settings.get_json("revengai.all_analyses", None)
8482
if all_analyses == "null":
8583
return {}
86-
return all_analyses
84+
return json.loads(all_analyses)
8785

8886
def set_current_info(self, binary_id):
8987
binary_id = int(binary_id)
9088
self.binary_id = binary_id
9189

9290
all_analyses = self.get_all_analyses()
9391
all_analyses[self.sha256] = {"binary_id": binary_id}
94-
log_info(f"RevEng.AI | All analyses: {all_analyses}")
92+
#log_info(f"RevEng.AI | All analyses: {all_analyses}")
9593
settings = Settings()
9694

9795
settings.set_json("revengai.all_analyses", json.dumps(all_analyses))
9896
log_info(f"RevEng.AI | Updated analysis for SHA256: {self.sha256[:8]}... with binary_id: {binary_id}")
9997

100-
10198
def init_config(self, bv: BinaryView):
10299
try:
103100
if not self.check_auth():
104101
self.is_configured = False
105-
raise(f"RevEng.AI | Authentication failed.")
102+
raise Exception("RevEng.AI | Authentication failed.")
106103

107104
self.is_configured = True
108105

109106
self.sha256 = re_binary_id(bv.file.filename)
110107
log_info(f"RevEng.AI | SHA256: {self.sha256}")
111108

112-
all_analyses = self.get_all_analyses()
109+
all_analyses = self.get_all_analyses()
113110
if self.sha256 in all_analyses:
111+
log_info(f"RevEng.AI | Binary found in saved configurations, binary_id: {all_analyses[self.sha256]['binary_id']}")
114112
self.binary_id = all_analyses[self.sha256]["binary_id"]
115113
else:
116114
search_results = RE_search(fpath=bv.file.filename).json()["query_results"]
@@ -123,3 +121,10 @@ def init_config(self, bv: BinaryView):
123121
log_error(f"RevEng.AI | Failed to initialize configuration: {str(e)}")
124122
return False, str(e)
125123

124+
def get_binary_id(self, bv: BinaryView):
125+
self.sha256 = re_binary_id(bv.file.filename)
126+
all_analyses = self.get_all_analyses()
127+
if self.sha256 in all_analyses:
128+
return all_analyses[self.sha256]["binary_id"]
129+
else:
130+
return 0

0 commit comments

Comments
 (0)