REVEN-Axion 2017v1.4.0
slicer.py

The slicer script make use of REVEN data tainting capabilities to display a list of instructions that manipulate tainted data.

It uses reven.Project.taint method to retrieve the list of execution Point which deal with tainted data and print them.

1 #!/usr/bin/env python2
2 
3 import reven
4 import argparse
5 
6 def parse_args():
7  parser = argparse.ArgumentParser(description='Create a sliced trace based on some register taint propagation.')
8  parser.add_argument('--host', metavar='host', dest='host', help='the reven host', default="localhost")
9  parser.add_argument('--port', metavar='port', dest='port', type=int, help='the reven server port', default=13370)
10  parser.add_argument('-r', metavar='run', dest='run', help='the reven execution run name', default='Execution run')
11  parser.add_argument('-s', metavar='sequence', dest='sequence', type=int, help='the reven execution sequence', default=0)
12  parser.add_argument('-i', metavar='instruction', dest='instruction', type=int, help='the reven execution instruction', default=0)
13  parser.add_argument('-b', dest='backward', action='store_true', help='taint in backward direction')
14  parser.add_argument('-v', dest='verbose', action='store_true', help='print the tainted register/memory')
15 
16  parser.add_argument(metavar='registers', dest='registers', help='name of the registers to taint', nargs='+')
17 
18  args = parser.parse_args()
19 
20  return args
21 
22 # colors
23 green = "\033[1;32m"
24 red = "\033[1;31m"
25 reset = "\033[0m" # use to restore the default color
26 colored = lambda to_color, color: "%s%s%s" % (color, to_color, reset)
27 
28 def colored_list_diff_str(old, new):
29  string = "[ "
30  for reg in sorted(set(new) - set(old), key=str.lower):
31  string += "%s " % colored(reg, green)
32  for reg in sorted(set(old) - set(new), key=str.lower):
33  string += "%s " % colored(reg, red)
34  for reg in sorted(set(old).intersection(new), key=str.lower):
35  string += "%s " % reg
36  string += "]"
37  return string
38 
39 def fixed_size_str(string, size):
40  if len(string) > size:
41  new = string[:(size - 3)] + "..."
42  else:
43  new = string + " " * (size - len(string))
44  return new
45 
46 def tainted_list(old, taintdiff):
47  new = current + [symbolic.name for symbolic in taintdiff.tainted]
48  for symbolic in taintdiff.untainted:
49  new.remove(symbolic.name)
50  return new
51 
52 
53 if __name__ == '__main__':
54 
55  # Parse the input arguments
56  args = parse_args()
57 
58  # Connect to the reven project
59  project = reven.Project(args.host, args.port)
60 
61  # Get the target trace
62  trace = project.trace(args.run)
63 
64  # Get the taint range start point
65  start_point = trace.point(args.sequence, args.instruction)
66 
67  # Get the initially tainted registers (assume its a 4byte register).
68  symbolics = [ reven.SymbolicRegister(r, 4) for r in args.registers ]
69 
70  # Propagate the taint an unlimited number of times and timeout after 5s
71  count = 0
72  timeout = 5000
73  forward = False if args.backward else True
74  result = project.taint(start_point, symbolics, forward, count, timeout)
75 
76  # Display the sliced trace
77  if args.verbose:
78  current = [symbolic.name for symbolic in symbolics]
79 
80  for point in sorted(result.diffs.keys()):
81  location = "%d_%d - %s" % (point.sequence_index, point.instruction_index, point.symbol.name)
82  string = fixed_size_str(location, 45)
83 
84  if args.verbose:
85  new = tainted_list(current, result.diffs[point])
86  string += fixed_size_str(" %s" % point.instruction, 50)
87  string += " %s" % colored_list_diff_str(current, new)
88  current = new
89 
90  else:
91  string += " %s" % point.instruction
92 
93  print string