-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathgadget-stats
executable file
·90 lines (66 loc) · 2.09 KB
/
gadget-stats
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
#!/usr/bin/python
# vim: set fileencoding=utf-8 :
import sys
import subprocess
import argparse
import r2pipe
parser = argparse.ArgumentParser()
parser.add_argument('file_path')
parser.add_argument('--gadget-file', help='skip the gadget search and use the provided data.')
args = parser.parse_args()
fpath, gpath = args.file_path, args.gadget_file
def san(x, s=''):
return x.replace('\n', s).replace('\r', s)
def pptr(x):
return '0x%08x' % int(x, 16)
gfind = 'ROPgadget/ROPgadget.py'
print u"[-] Opening file: \"%s\" " % fpath
core = r2pipe.open(fpath)
print u" ✓ Analyzing ... "
print u' ➙ ' + u'-'*70
core.cmd('aaaa')
skip = '[Entrypoints]\nvaddr='
ep = core.cmd('ie')
print(u" ➙ Entrypoint: %s" % (ep[len(skip):ep.find(' ')]))
if gpath:
p = open(gpath)
else:
p = subprocess.Popen('%s --binary %s' % (gfind, fpath), shell=True,
stdout=subprocess.PIPE, close_fds=True).stdout
gadgets= [san(s) for s in p.readlines()[2:-2]]
print u' ➙ Gadgets: %i' % len(gadgets)
print u' ➙ ' + u'-'*70
ic, ec, pd = 0, 0, None
for g in gadgets:
addr = g.split(' ')[0]
raddr=san(core.cmd("s %s; s" % addr))
flags=san(core.cmd("ai"), ' ')
# print "RADDR: %s [ADDR: %s] = ( %s)" % (pptr(raddr), addr, flags)
if flags.count('func') != 0:
pd='pdb'
elif flags.count('exec') != 0:
'''
While this heuristics may produce false
positives, 32 bytes is usually enough
to let the instruction stream to 'heal'
itself thanks to the 16-byte block
alignment nop-sleds.
'''
pd='pd 20@-32'
else:
continue # section is not executable
explicit = san(core.cmd('%s~?%s' % (pd, pptr(raddr)))) == '1'
'''
In case the analysis of the func failed the addr will still
bear the 'func' flag but neither pdb/pdf will work so we fallback
to heuristics
'''
func_error = san(core.cmd('??')) == '-1'
if func_error:
explicit = san(core.cmd('pd 20@-32~?%s' % pptr(raddr))) == '1'
if explicit:
ec += 1
#print 'Explicit gadget: ', san(g)
else:
ic +=1
print u' ➙ Implicit: %i\n ➙ Explicit: %i\n ➙ Total: %i\n » Ratio: %.2f:1' % (ic, ec, ec+ic, float(ic)/float(ec))