-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathghidra_function_name_import.py
93 lines (78 loc) · 4.19 KB
/
ghidra_function_name_import.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
#TODO Imports function names from a file containing two columns of function names and addresses. Function names have spaces and brackets and there contents removed. Addresses are in hex format. For very large files the script may need to be run multiple times.
#@author Finn Hartshorn
#@category _NEW_
#@keybinding
#@menupath
#@toolbar
import os.path
from ghidra.program.model.symbol import SourceType #.SourceType import USER_DEFINED
def remove_text_inside_brackets(text, brackets="()[]"):
count = [0] * (len(brackets) // 2) # count open/close brackets
saved_chars = []
for character in text:
for i, b in enumerate(brackets):
if character == b: # found bracket
kind, is_close = divmod(i, 2)
count[kind] += (-1)**is_close # `+1`: open, `-1`: close
if count[kind] < 0: # unbalanced bracket
count[kind] = 0 # keep it
else: # found bracket to remove
break
else: # character is not a [balanced] bracket
if not any(count): # outside brackets
saved_chars.append(character)
return ''.join(saved_chars)
def log_line(file_obj, line):
file_obj.writelines([line, "\n"])
def add_plate_comment(address, comment, log_file):
existing_comment = getPlateComment(address)
if existing_comment and existing_comment != comment:
log_line(log_file, "Comment already exists at address {} with comment {}".format(address, existing_comment))
print("Comment already exists at address {} with comment {}".format(address, existing_comment))
return
elif not existing_comment:
log_line(log_file, "Adding comment {} to address {}".format(comment, address))
print("Adding comment {} to address {}".format(comment, address))
setPlateComment(address, comment)
functionManager = currentProgram.getFunctionManager()
f = askFile("Give me a file to open", "Go baby go!")
file_name = f.getAbsolutePath()
file_name_no_extension, extension = os.path.splitext(file_name)
log_file_name = file_name_no_extension + ".log"
with open(file_name, "r") as ida_export, open(log_file_name, "w") as ida_import_log:
for line in ida_export:
pieces = line.split(" 0x")
if len(pieces) != 2:
print("Error parsing symbol {} ({})".format(line, len(pieces)))
continue
function_name = remove_text_inside_brackets(pieces[0], brackets="()").replace(" ", "")
function_signature = pieces[0]
address = toAddr("0x" + pieces[1]).add(int("0x10000000", 16))
existing_comment = getPlateComment(address)
print("Existing comment: {}".format(existing_comment))
func = functionManager.getFunctionAt(address)
if func is not None:
old_name = func.getName()
if old_name == function_name:
add_plate_comment(address, function_signature, ida_import_log)
continue
try:
if function_name.startswith(".") and not old_name.startswith("FUN"):
log_line(ida_import_log, "Not renaming {} to {}".format(old_name, function_name))
continue
func.setName(function_name, SourceType.USER_DEFINED)
log_line(ida_import_log, "Renamed function {} to {} at address {}".format(old_name, function_name, address))
add_plate_comment(address, function_signature, ida_import_log)
except Exception as e:
print("Failed to rename function from {} to {} because {}".format(old_name, function_name, e))
log_line(ida_import_log, "Failed to rename function from {} to {}".format(old_name, function_name))
continue
else:
try:
func = createFunction(address, function_name)
log_line(ida_import_log, "Created function {} at address {}".format(function_name, address))
add_plate_comment(address, function_signature, ida_import_log)
except:
print("Failed to create function {}".format(function_name))
log_line(ida_import_log, "Failed to create function {}".format(function_name))
continue