REVEN-Axion User Documentation 2015-v1
slicer.py

The slicer will show how to use the tainter to show only the instructions that are interesting to get to an instruction.

It uses services run_search_tainted_instructions to retrieve the list of interesting instruction locations, then for each point, it prints the instructions themselves.

#!/usr/bin/env python
import reven
host = raw_input('Enter the reven host [localhost]: ')
if not host:
host = "localhost"
try:
port = int(raw_input('Enter the reven port [13370]: '))
except ValueError as e:
port = 13370
try:
rvn = reven.reven_connection(host, port)
except:
print("[!] Reven not found on port %d" % port)
sys.exit(1)
print("[+] Connected to reven on %s:%d" % (host, port))
runs = rvn.run_get_all()
if len(runs) == 0:
sys.stderr.write("[!] No run detected.\n")
sys.exit(1)
# Usually the interesting run will always be the first one, unless we are using the fuzzer.
run = runs[0]
try:
start_sequence = int(raw_input("Enter the initial sequence [0]: "))
except ValueError as e:
start_sequence = 0
try:
start_instruction = int(raw_input("Enter the initial instruction [0]: "))
except ValueError as e:
start_instruction = 0
try:
stop_sequence = int(raw_input("Enter the ending sequence [1]: "))
except ValueError as e:
stop_sequence = 1
stop_instruction = 0
reg = raw_input("Enter the initialy tainted register [eax]: ")
if not reg:
reg = "eax"
# Here we only taint one register, we could create more of them if desired.
register_tainted = [reg]
# We can also taint some memories by uncommenting the last part of the following lines:
# Memory range (last is excluded)
first_memory_tainted = reven.logical_address(0,0) #reven.logical_address(0x7b,0xbffff55c)
last_memory_tainted = reven.logical_address(0,0) #reven.logical_address(0x7b,0xbffff58c)
initial_taint = reven.vector_of_symbolic()
#####################################################################################################
start_point = reven.execution_point(run, start_sequence, start_instruction)
stop_point = reven.execution_point(run, stop_sequence, stop_instruction)
# Create the list of registers to taint. We just convert any item in register_tainted to the proper format.
for sym in register_tainted:
smem = reven.symbolic()
smem.name = reg
smem.type = reven.symbolic_type.register_all_purpose
initial_taint.append(smem)
# Append memories
offset_tainted = first_memory_tainted.offset
# We do exactly the same for memories. In the memories case, we also have to get their physical address
# because the tainter works by physical addresses.
segment = first_memory_tainted.segment
for offset in range(first_memory_tainted.offset, last_memory_tainted.offset):
smem = reven.symbolic()
smem.name = "0x%x:0x%x" % (segment, offset)
smem.type = reven.symbolic_type.memory_physical
smem.physical_address = rvn.memory_get_physical_address(start_point, reven.logical_address(segment, offset))
initial_taint.append(smem)
# Propagate taint, may took some times
print "[*] Tainting ..."
tainted_points = rvn.run_search_tainted_instructions(start_point, stop_point, 5000, initial_taint, False)
print("[*] Tracking ")
for i in initial_taint:
print("%s, " % (i.name), '', None)
print("from #%d:%d to #%d:%d" % (start_sequence,
start_instruction,
stop_sequence,
0))
print("-----------------------------------------------\n")
# Now, in tainted_points, we have all points where the taint is changed.
for entry in tainted_points:
k = entry.key()
v = entry.data()
if not len(v.new) and not len(v.old):
# Ignore when the taint hasn't changed
continue
# Request the instructions of the point
sequences = rvn.run_get_instructions_range(reven.execution_range(run, k.sequence_identifier, 1, 0))
seq = sequences[0]
ins = seq.instructions[k.instruction_index]
# Print the instruction itself
mnemonic = " "
if ins.prefixes: mnemonic = "%s " % ins.prefixes
mnemonic += ins.mnemonic
if ins.operand_one: mnemonic += " " + ins.operand_one
if ins.operand_two: mnemonic += ", " + ins.operand_two
if ins.operand_three: mnemonic += ", " + ins.operand_three
symbol = "%s+%x" % (seq.sequence.symbol.name, seq.sequence.symbol.offset)
print("%-32s: #%d_%d: %s" % (symbol, k.sequence_identifier, k.instruction_index, mnemonic))