-
Notifications
You must be signed in to change notification settings - Fork 20
/
__init__.py
128 lines (109 loc) · 4.61 KB
/
__init__.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
127
128
"""Binary Ninja plugin to import and export symbols and comments to x64dbg database format."""
import json
import pathlib
from binaryninja.enums import LogLevel, SymbolType
from binaryninja.interaction import get_save_filename_input, get_open_filename_input
from binaryninja.log import log
from binaryninja.plugin import PluginCommand
from binaryninja.settings import Settings
s = Settings()
s.register_group('dd', 'x64dbg Database Export')
setting = {
'description': 'Always export comments to the x64dbg database.',
'title': 'Export Comments',
'default': True,
'type': 'boolean'
}
s.register_setting('dd.comments', json.dumps(setting))
setting = {
'description': 'Overwrite LibraryFunctionSymbol name',
'title': 'Overwrite LibraryFunctionSymbol',
'default': False,
'type': 'boolean'
}
s.register_setting('dd.libfs', json.dumps(setting))
setting = {
'description': 'Overwrite ImportedFunctionSymbol name',
'title': 'Overwrite ImportedFunctionSymbol',
'default': False,
'type': 'boolean'
}
s.register_setting('dd.impfs', json.dumps(setting))
def export_db(bv):
"""Export symbols and optionally comments from Binary Ninja to an x64dbg database."""
db = dict()
module = pathlib.Path(bv.file.original_filename)
outpath = bv.file.database.globals.get('x64dbg_db_save_path', pathlib.Path(bv.file.filename).parent)
dbext = 'dd{}'.format(bv.arch.address_size * 8)
if not (f := get_save_filename_input('Export database', dbext, f'{outpath}/{module.stem}.{dbext}')):
return
file = pathlib.Path(f)
log(LogLevel.InfoLog, f'Exporting database: {file}')
# Export symbols to x64dbg labels
db['labels'] = [
{
'text': symbol.name,
'manual': not symbol.auto,
'module': module.name.lower(),
'address': '0x{:X}'.format(symbol.address - bv.start)
}
for symbol in bv.get_symbols()
]
log(LogLevel.DebugLog, 'Label(s) exported: {}'.format(len(db['labels'])))
s = Settings()
if s.get_bool('dd.comments'):
db['comments'] = [
{
'text': func.comments[address].replace('{', '{{').replace('}', '}}'),
'manual': True,
'module': module.name.lower(),
'address': '0x{:X}'.format(address - bv.start)
}
for func in bv.functions for address in func.comments
]
log(LogLevel.DebugLog, 'Comment(s) exported: {}'.format(len(db['comments'])))
file.write_text(json.dumps(db))
bv.file.database.write_global('x64dbg_db_save_path', str(file.parent))
log(LogLevel.InfoLog, 'Done!')
def import_db(bv):
"""Import x64dbg database to Binary Ninja."""
module = pathlib.Path(bv.file.original_filename).name.lower()
if not (f := get_open_filename_input('Import database', '*.dd{}'.format(bv.arch.default_int_size * 8))):
return
file = pathlib.Path(f)
log(LogLevel.InfoLog, f'Importing database: {file}')
db = json.load(file.open())
count = 0
labels = db.get('labels', list())
with bv.bulk_modify_symbols():
for label in labels:
if label['module'] != module:
continue
address = int(label['address'], 16) + bv.start
if not (func := bv.get_function_at(address)):
continue
if func.name == label['text']:
continue
if func.symbol.type is SymbolType.LibraryFunctionSymbol and not s.get_bool('dd.libfs'):
continue
if func.symbol.type is SymbolType.ImportedFunctionSymbol and not s.get_bool('dd.impfs'):
continue
func.name = label['text']
count += 1
log(LogLevel.DebugLog, 'Label(s) imported: {}/{}'.format(count, len(labels)))
count = 0
comments = db.get('comments', list())
for comment in comments:
if comment['module'] != module:
continue
address = int(comment['address'], 16) + bv.start
for func in bv.get_functions_containing(address):
func.set_comment_at(address, comment['text'])
count += 1
log(LogLevel.DebugLog, 'Comment(s) imported: {}/{}'.format(count, len(comments)))
log(LogLevel.InfoLog, 'Done!')
def is_valid(bv):
"""Determine if this is the correct arch."""
return 'x86' in bv.arch.name
PluginCommand.register('x64dbg\\Export database', 'Export x64dbg database', export_db, is_valid)
PluginCommand.register('x64dbg\\Import database', 'Import x64dbg database', import_db, is_valid)