forked from Vector35/binaryninja-api
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfeature_map.py
78 lines (63 loc) · 2.52 KB
/
feature_map.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
#!/usr/bin/env python
# headlessly draw the feature map of a given binary
import os, sys, binaryninja
from binaryninja.enums import SymbolType, StringType
WIDTH, HEIGHT = 100, 800
FeatureMapBaseColor = (16, 16, 16)
FeatureMapNavLineColor = (16, 16, 16)
FeatureMapNavHighlightColor = (237, 223, 179)
FeatureMapDataVariableColor = (144, 144, 144)
FeatureMapAsciiStringColor = (162, 217, 175)
FeatureMapUnicodeStringColor = (222, 143, 151)
FeatureMapFunctionColor = (128, 198, 233)
FeatureMapImportColor = (237, 189, 129)
FeatureMapExternColor = (237, 189, 129)
FeatureMapLibraryColor = (237, 189, 129)
bv = binaryninja.load(sys.argv[1], update_analysis=True)
imgdata = [FeatureMapBaseColor]*(WIDTH*HEIGHT)
data_len = sum([s.end - s.start for s in bv.segments])
image_len = WIDTH*HEIGHT
factor = image_len / data_len
def addr_to_fmap_offset(addr):
for (i,seg) in enumerate(bv.segments):
#print(f'segment {i}: [{seg.start:08X}, {seg.end:08X})')
if addr >= seg.start and addr < seg.end:
a = sum([s.end - s.start for s in bv.segments[0:i]]) + (addr - seg.start)
return int(factor * a)
assert False, f'address {addr:08X} was not in any segment'
for seg in bv.segments:
print(f'segment [{seg.start:08X}, {seg.end:08X}) -draw-> ' + \
f'[{addr_to_fmap_offset(seg.start):08X}, {addr_to_fmap_offset(seg.end-1):08X}]')
def highlight(a0, a1, color):
for i in range(addr_to_fmap_offset(a0), addr_to_fmap_offset(a1)):
imgdata[i] = color
# data variables
for (addr, var) in bv.data_vars.items():
sym = bv.get_symbol_at(addr)
if sym and sym.type in [SymbolType.ImportAddressSymbol, SymbolType.ImportedFunctionSymbol, SymbolType.ImportedDataSymbol]:
color = FeatureMapImportColor
elif sym and sym.type in [SymbolType.ExternalSymbol]:
color = FeatureMapExternColor
else:
color = FeatureMapDataVariableColor
highlight(addr, addr + len(var), color)
# strings
for s in bv.strings:
color = FeatureMapAsciiStringColor if s.type == StringType.AsciiString else FeatureMapUnicodeStringColor
highlight(s.start, s.start + len(s), color)
# functions
for f in bv.functions:
sym = f.symbol
if sym and sym.type == SymbolType.ImportedFunctionSymbol:
color = FeatureMapImportColor
elif sym and sym.type == SymbolType.LibraryFunctionSymbol:
color = FeatureMapLibraryColor
else:
color = FeatureMapFunctionColor
for bb in f.basic_blocks:
highlight(bb.start, bb.end, color)
# export image
import struct
from PIL import Image
data = b''.join([struct.pack('BBB', *rgb) for rgb in imgdata])
Image.frombytes('RGB', (WIDTH,HEIGHT), data).save('feature-map.png')