manticore/scripts/qemu.py
Yan 2916d7e3ae Support tracing (#247)
* Script for generating syscall tables

* Add generated syscall table

* Reintroduce tracing script

* Add configuration options needed by verify.py

* Clean up verify; remove dependency on experimental after_hook

* trace experiments

* reorg verify.py

* Update after merge

* Remove Manticore param

* Remove unused vars

* Use regfile api; redo last_instr check

* Fix gdb->mcore name descrepancy

* Move kwargs to explicit args for Linux/SLinux

 * Maintain options in makeLinux to not overcomplicate the Manticore
   class

* Address merge issues

* remove debug stmt

* Reintroduce options

* Revert linux.py/manticore.py from master

* Use the qemu -s and -R flags

* Import syscalls table from master

* And import extract_syscalls.py script

* Fix verify reference

* Move syscall to arg

* Update register references

* Simplify last instruction check

* Add logging filter to TRACE logger as well

* Be consistent with state synchronization

* Be explicit about gdb types

* Improve mmap debug output

* Return error if ioctl is not implemented

* Fix syscall sync

* Make logging more self-contained

* Use errno const in ioctl impl
2017-06-05 16:16:54 -04:00

93 lines
2.4 KiB
Python

import copy
import traceback
import os
import sys
import time
import subprocess
import logging
logger = logging.getLogger("QEMU")
count = 0
subproc = None
stats = None
_arch = None
def get_lines(n=1):
lines = []
str_buffer = ''
received_lines = 0
while received_lines < n:
c = subproc.stdout.read(1)
str_buffer += c
if c == '\n':
lines.append(str_buffer)
str_buffer = ''
received_lines += 1
return lines
def parse_mmu_debug_output(s):
d = {}
# Get guest address space
d['reserved'] = int(s.pop(0).split()[1], 0)
d['host_mmap_min_addr'] = int(s.pop(0).split('=')[1], 0)
d['guest_base'] = int(s.pop(0).split()[1], 0)
# get rid of mapping heading
s.pop(0)
d['maps'] = []
while '-' in s[0]:
line = s.pop(0)
range, size, protections = line.split()
start, end = range.split('-')
d['maps'].append((int(start, 16),
int(end, 16),
int(size, 16),
protections))
while s:
line = s.pop(0)
if not line:
continue
var, addr = line.split()
d[var] = int(addr, 0)
return d
def start(arch, argv, port=1234, va_size=0xc0000000, stack_size=0x20000):
global subproc, stats
aslr_file = '/proc/sys/kernel/randomize_va_space'
try:
with open(aslr_file, 'r') as f:
if f.read().strip() != '0':
logger.warning("Disable ASLR before running qemu-user")
logger.warning(" sudo sh -c 'echo 0 > %s'", aslr_file)
finally:
pass
args = ['qemu-%s'%(arch,), '-g', port, '-d', 'mmu', '-R', va_size, '-s', stack_size] + argv
args = map(str, args)
print("Running: %s"%(' '.join(args),))
subproc = subprocess.Popen(args, stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
mmu_debug_output = get_lines(16)
stats = parse_mmu_debug_output(mmu_debug_output)
for m in stats['maps']:
start, end, size, perms = m
print '{:x}-{:x}, {}, {}'.format(*m)
def correspond(text):
"""Communicate with the child process without closing stdin."""
if text:
subproc.stdin.write(text)
subproc.stdin.flush()
return get_lines()