* 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
93 lines
2.4 KiB
Python
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()
|