* WIP New Policy class * WIP pubsub * Update Signal tests * small fixes from github comments * Fix event decode_instruction signature * Good merge * Good good merge * WIP manticore refactor * Fix default old-style initial state * add -> enqueue * @m.init * Fix workspace url * Some test skipped * Ad Fixme to platform specific stuff in State * add -> enqueue * Enqueue created state * Fix m.init Use a messy hack to adhere to the spec (callback func receive 1 state argument) * Add _coverage_file ivar to Manticore * Fix symbolic files * remove extra enqueue * Fixing __main__ * comments * Experimental plugin system * tests fixed * Fix plugins * Some reporting moved to plugin * Fix assertions test * Add published events to classes that publish them * Update how we verify callbacks * Update Eventful._publish * Yet another flavor for event name checking * really it's a bunch of minimal bugfixes * Remove get_all_event_names from Plugin * Update where we get all events * Use new metaclass-based event registry * Initial concrete trace follower * Add extended (json) trace support * More stubs for condition gather * Update trace saving to new format * Produce trace regardless of contents * Record register deltas in trace * Move initialization to _start_run so we can call run() multiple times * Re-fix multiple workspace bug * Fix it correctly * Add extended trace and accessors * make sure did_execute_instruction is always published * Produce a consistent version * move extended tracing to separate class * Reorg of extended tracing plugins * Add concolic tracing script * Clean up old hooks * Sync memory as well; cleanups * Revert binary tests * simplify concolic follower * Move trace follower to plugin.py * Simplify follower * Add skip ranges to Follower * Update concolic.py * Remove redundant state init * Clean up driver script * Update header line * Move trace follower * Move Follower to follow_trace.py * rm unused import * Remove unnecessary property * rm ConcreteTraceFollower * Revert start_run behavior * Initial implementation of concolic algorithm (#574) * Fix coverage calculation vs. metadata (#529) * Fixes symbolic reentrancy example * Fix coverage Issue# 527 * Remove debug unused code * Various bug fixes. (#530) * Fixes #503 * Fixes #515 * Fixes 272. Concretize data written to a fd. * Revert debug hack and fix overly broad exception * Update did/will_exec_instr semantics * Clean up imports * Update logging and improve sys_open return * Update variable names+doc for consistency * Remove win32 support (#535) * Remove Windows support files * Remove Windows test files * Localize log formatting changes (#547) * Don't add custom format string to root logger * Fix handler propagation * Move inline function definitions out of the AbstractCPU's execute method (#538) * This change moves from inline function definitions out of the critical path of AbstractCpu's execute method. * Raise a mcore exception if we fail at emulation * Fix all integral type checks that forget long (#555) * [fix] Issue #550: generates extra workspace folder (#557) * [fix] Issue #550: generates extra workspace folder Signed-off-by: Cole Lightfighter <cole@onicsla.bz> * Slight workspace and store refactor * Handle file.tell() error, which will happen for special files (/dev/tty) (#559) * Fix SLOAD invalid memory access (#562) Check global_storage includes an entry at address before trying to load storage. * New API for EVM analysis (#551) * Fixes symbolic reentrancy example * Fix coverage Issue# 527 * Remove debug unused code * New solidity biased API and reporting * Updated examples to new api WIP * simple_mapping FIXED. new api * Simple transaction example added. msg.value can be symbolic now * Reentrancy symbolic now updated to new API + bugfixes * Add PCMPXSTRX Instructions (#507) * Add PCMPXSTRX Instructions * bug fixes * unittest related fixes * Full test of pcmpxstrx * Move tests * Fix typo per issue #552 - s/arm64/amd64/ (#561) * Added missing syscalls in decree syscall trace (#545) * added missing syscalls in decree syscall trace * added missing parameter in callback of BranchLimited policy * progress * can flip constraint set * hack around double decl issue * can gen input * what is this, a coding interview? * did it? * clean * finish * pretty log messages * comment, clean * more cleaning * cmt * Only really fork when there's multiple solutions (#569) * Update comment and path * Add UMD simple assert example (#573) * Manticore prints linux ret code as uint instead of int (#578) * Fixing raise issue #435 * syncing git * Fix Bug #570 * syncing * removed all binaries * missed one file * Updates travis cache to python 2.7.13 (#576) * Updating README with solc binary requirements (#575) * Updating README with solc binary requirements * Update README.md * Assert valid operand length (#558) * Assert valid bytecode and operand length EVM bytecode comes in 32-byte chunks, and contracts require at least one segment to be created. An example, originally written by @ggrieco-tob in issue #546, is included. Unsure what expected behavior should be, but initial state has a problem when a contract is created with a single byte. Also added some exception handling in `parse_operand()` to catch invalid instructions, e.g. a PUSH1 instruction followed by no bytes. Signed-off-by: Cole Lightfighter <cole@onicsla.bz> * Fix SLOAD invalid memory access Simple check to ensure address storage is in global_storage before attempting to load data. * Remove invalid assertions * Fix for issue 556 and 591 (#590) * version argument in manticore * Fix 591 - Exception Handler * Fix Issue: 597 - Remove unused policy argument in function State.solve_n (#598) * version argument in manticore * Fix 591 - Exception Handler * Issue 597 - Remove the unused policy argument * Fixes to thumb mode instruction implementations * Thumb specific fixes to the SUB, BX, and MOV instruction implementations * implemented hardcoded result for gettid syscall * Trace following mode (#513) * WIP New Policy class * WIP pubsub * Update Signal tests * small fixes from github comments * Fix event decode_instruction signature * Good merge * Good good merge * WIP manticore refactor * Fix default old-style initial state * add -> enqueue * @m.init * Fix workspace url * Some test skipped * Ad Fixme to platform specific stuff in State * add -> enqueue * Enqueue created state * Fix m.init Use a messy hack to adhere to the spec (callback func receive 1 state argument) * Add _coverage_file ivar to Manticore * Fix symbolic files * remove extra enqueue * Fixing __main__ * comments * Experimental plugin system * tests fixed * Fix plugins * Some reporting moved to plugin * Fix assertions test * Add published events to classes that publish them * Update how we verify callbacks * Update Eventful._publish * Yet another flavor for event name checking * really it's a bunch of minimal bugfixes * Remove get_all_event_names from Plugin * Update where we get all events * Use new metaclass-based event registry * Initial concrete trace follower * Add extended (json) trace support * More stubs for condition gather * Update trace saving to new format * Produce trace regardless of contents * Record register deltas in trace * Move initialization to _start_run so we can call run() multiple times * Re-fix multiple workspace bug * Fix it correctly * Add extended trace and accessors * make sure did_execute_instruction is always published * Produce a consistent version * move extended tracing to separate class * Reorg of extended tracing plugins * Add concolic tracing script * Clean up old hooks * Sync memory as well; cleanups * Revert binary tests * simplify concolic follower * Move trace follower to plugin.py * Simplify follower * Add skip ranges to Follower * Update concolic.py * Remove redundant state init * Clean up driver script * Update header line * Move trace follower * Move Follower to follow_trace.py * rm unused import * Remove unnecessary property * rm ConcreteTraceFollower * Revert start_run behavior * Centralize system call logging (#602) * Remove per-syscall logging * Make Cpu.read_string() stop reading at first symbolic byte * Centralize syscall logging * Update helper docstring * Update arg/ret expansion * Check for issymbolic first * Tiny hex format change * Log unimplemented instructions (issue 163) (#599) * Remove double printing of exception. * Pretty print the unimplemented instruction raised by unicorn (UcError). * Raise exception after unimplemented instruction error logging. * Ensure the raised exception is actually a unicorn invalid instruction error. * Resolve conflict * EVM assembler/disassembler doc and cleanup (#563) * Fixes symbolic reentrancy example * Fix coverage Issue# 527 * Remove debug unused code * New solidity biased API and reporting * Updated examples to new api WIP * simple_mapping FIXED. new api * Simple transaction example added. msg.value can be symbolic now * Reentrancy symbolic now updated to new API + bugfixes * Doc and cleanups in evm assembler * EVMInstruction -> Instruction * cleanups * typo * deepcopy in Constant * Better EVM-asm api and doc * some docs * More evm asm docs * Fix import * * typo * newline between text and param * similar phrasing to all the other flags * typo * typo * fix function name in comment * sphinx newline * documentation fixes * documentation fixes * EVMAssembler to EVMAsm * Fix evm @hook signature * EVMAsm * EVMasm refactor * EVM api refactor (#589) * Fixes symbolic reentrancy example * Fix coverage Issue# 527 * Remove debug unused code * New solidity biased API and reporting * Updated examples to new api WIP * simple_mapping FIXED. new api * Simple transaction example added. msg.value can be symbolic now * Reentrancy symbolic now updated to new API + bugfixes * Doc and cleanups in evm assembler * EVMInstruction -> Instruction * cleanups * typo * deepcopy in Constant * Better EVM-asm api and doc * some docs * More evm asm docs * Initial seth in place refactor * Fix import * * typo * newline between text and param * similar phrasing to all the other flags * typo * typo * fix function name in comment * sphinx newline * documentation fixes * documentation fixes * refactors * EVMAssembler to EVMAsm * Fix evm @hook signature * EVMAsm * WIP seth doc * WIP move seth * seth moved to manticore module * Fixed DUP and typo * Slightly better evm reporting * review * review * Removed unfinished refactor * Fixed Issue #533 (#606) * Remove Platform._path * Amend pr guidelines (#615) * Fixed Issue #619 (#623) Add newlines in .trace file generation * Hide legacy cli flags from cli help (#622) * Fixed Issue #533 * Removed --replay argument from cli help. Issue #617 * Update help description * Remove unused --size flag * Emit .input instead of .txt files in workspace (#625) Related: #612 * Update workspace.py Changed extension to .input * Update test_workspace.py * changed key value pair in test_workspace bc of change of extension to .input in workspace.py, fixed issue #618 * removed unwanted directories * Update seth.py * Update seth.py Change in Documentation issue #612 * EVM refactor and simple UI (#629) * Fixes symbolic reentrancy example * Fix coverage Issue# 527 * Remove debug unused code * New solidity biased API and reporting * Updated examples to new api WIP * simple_mapping FIXED. new api * Simple transaction example added. msg.value can be symbolic now * Reentrancy symbolic now updated to new API + bugfixes * Doc and cleanups in evm assembler * EVMInstruction -> Instruction * cleanups * typo * deepcopy in Constant * Better EVM-asm api and doc * some docs * More evm asm docs * Initial seth in place refactor * Fix import * * typo * newline between text and param * similar phrasing to all the other flags * typo * typo * fix function name in comment * sphinx newline * documentation fixes * documentation fixes * refactors * EVMAssembler to EVMAsm * Fix evm @hook signature * EVMAsm * WIP seth doc * WIP move seth * seth moved to manticore module * Fixed DUP and typo * Slightly better evm reporting * review * review * Removed unfinished refactor * Various refactors. Auxiliar for calculating % coverage * Change report in examples * Detailed transactions and reporting accessible to the user2 * Fix on Expression Array * Some documentation * Get full ABI from solc compiler * evm/examples -> bugfixes * Clarify try/except blocks * Code review * Code review * Initial eth cli based on solidse.py (#633) * Fixes symbolic reentrancy example * Fix coverage Issue# 527 * Remove debug unused code * New solidity biased API and reporting * Updated examples to new api WIP * simple_mapping FIXED. new api * Simple transaction example added. msg.value can be symbolic now * Reentrancy symbolic now updated to new API + bugfixes * Doc and cleanups in evm assembler * EVMInstruction -> Instruction * cleanups * typo * deepcopy in Constant * Better EVM-asm api and doc * some docs * More evm asm docs * Initial seth in place refactor * Fix import * * typo * newline between text and param * similar phrasing to all the other flags * typo * typo * fix function name in comment * sphinx newline * documentation fixes * documentation fixes * refactors * EVMAssembler to EVMAsm * Fix evm @hook signature * EVMAsm * WIP seth doc * WIP move seth * seth moved to manticore module * Fixed DUP and typo * Slightly better evm reporting * review * review * Removed unfinished refactor * Various refactors. Auxiliar for calculating % coverage * Change report in examples * Detailed transactions and reporting accessible to the user2 * Fix on Expression Array * Some documentation * Get full ABI from solc compiler * evm/examples -> bugfixes * Clarify try/except blocks * Code review * Code review * initially evm cli from solidse.py * rm prints, make import work it's just `import seth` because this file runs from the perspective of being inside the package. `from manticore.seth` doesn't work because manticore.py gets priority over the manticore package, and there is no seth entity inside manticore.py * rm wip cli file * add excess printing as a big comment * print minimal report * require .sol only * rm solidse again * rm fluff * evm: Make 'not enough funds' states finalized states (#636) * print on every * terminate not enough fund states * Better check * revert debug change * Implement initial evm workspace, fix small bugs (#638) * print on every * save the bytecode to look at later * update tuple * wip workspace files * wip * generate tx files * rm unused event handler * clean up solving for tx.data * Revert "print on every" 0caaae3658a169c9763c51544aa3c79a4e3940ca * Detectors () (#637) * Fixes symbolic reentrancy example * Fix coverage Issue# 527 * Remove debug unused code * New solidity biased API and reporting * Updated examples to new api WIP * simple_mapping FIXED. new api * Simple transaction example added. msg.value can be symbolic now * Reentrancy symbolic now updated to new API + bugfixes * Doc and cleanups in evm assembler * EVMInstruction -> Instruction * cleanups * typo * deepcopy in Constant * Better EVM-asm api and doc * some docs * More evm asm docs * Initial seth in place refactor * Fix import * * typo * newline between text and param * similar phrasing to all the other flags * typo * typo * fix function name in comment * sphinx newline * documentation fixes * documentation fixes * refactors * EVMAssembler to EVMAsm * Fix evm @hook signature * EVMAsm * WIP seth doc * WIP move seth * seth moved to manticore module * Fixed DUP and typo * Slightly better evm reporting * review * review * Removed unfinished refactor * Various refactors. Auxiliar for calculating % coverage * Change report in examples * Detailed transactions and reporting accessible to the user2 * Fix on Expression Array * Some documentation * Get full ABI from solc compiler * evm/examples -> bugfixes * Clarify try/except blocks * Code review * Code review * Code review * Code review * Code review * Initial detector plugin. integer overflow and unitialized mem * Better metadata handling and new events for detectors * detectors wip * Better name for internal findings context * Explicit detector register * review * Refactor concolic implementation (#601) * Refactor concolic.py * make arg name more descriptive * A few cleanups * Keep track of traces * Added perm() description * Rm meaningless paths variable * little comment * rm bug comment trace set is the correct solution; we need to filter out satisfiable but redundant paths that are generated by the dumb permuter * clean comments, debug stuff * Better EVM workspace output (#641) * Fixes symbolic reentrancy example * Fix coverage Issue# 527 * Remove debug unused code * New solidity biased API and reporting * Updated examples to new api WIP * simple_mapping FIXED. new api * Simple transaction example added. msg.value can be symbolic now * Reentrancy symbolic now updated to new API + bugfixes * Doc and cleanups in evm assembler * EVMInstruction -> Instruction * cleanups * typo * deepcopy in Constant * Better EVM-asm api and doc * some docs * More evm asm docs * Initial seth in place refactor * Fix import * * typo * newline between text and param * similar phrasing to all the other flags * typo * typo * fix function name in comment * sphinx newline * documentation fixes * documentation fixes * refactors * EVMAssembler to EVMAsm * Fix evm @hook signature * EVMAsm * WIP seth doc * WIP move seth * seth moved to manticore module * Fixed DUP and typo * Slightly better evm reporting * review * review * Removed unfinished refactor * Various refactors. Auxiliar for calculating % coverage * Change report in examples * Detailed transactions and reporting accessible to the user2 * Fix on Expression Array * Some documentation * Get full ABI from solc compiler * evm/examples -> bugfixes * Clarify try/except blocks * Code review * Code review * Code review * Code review * Code review * Initial detector plugin. integer overflow and unitialized mem * Better metadata handling and new events for detectors * detectors wip * Better name for internal findings context * Explicit detector register * review * New workspace output * Fix examples * wrog merge fix * Fix examples/new api * Fix examples/new api/output * More output * More doc * Broken examples deleted * Debug code removed * Wrong docstring * Update evm __main__ * Update evm __main__ * Update evm __main__ * Update evm __main__ * Update evm __main__ * Fix TODO * Fix for issue #642 (#643) * version argument in manticore * Fix 591 - Exception Handler * Issue 597 - Remove the unused policy argument * fix issue 642 * Fix z3 oddity: reset vs optimization (#627) * Fixes symbolic reentrancy example * Fix coverage Issue# 527 * Remove debug unused code * New solidity biased API and reporting * Updated examples to new api WIP * simple_mapping FIXED. new api * Simple transaction example added. msg.value can be symbolic now * Reentrancy symbolic now updated to new API + bugfixes * Doc and cleanups in evm assembler * EVMInstruction -> Instruction * cleanups * typo * deepcopy in Constant * Better EVM-asm api and doc * some docs * More evm asm docs * Initial seth in place refactor * Fix import * * typo * newline between text and param * similar phrasing to all the other flags * typo * typo * fix function name in comment * sphinx newline * documentation fixes * documentation fixes * refactors * EVMAssembler to EVMAsm * Fix evm @hook signature * EVMAsm * WIP seth doc * WIP move seth * seth moved to manticore module * Fixed DUP and typo * Slightly better evm reporting * review * review * Removed unfinished refactor * Mitigates the wrong objectives print in z3 4.4.x * Exception to SolveException * Fix compilation bug (#645) * fix for #608 using a local definition (#644) * refactor logs files content (#646) - if no logs just print nothing - output any printable bytes in the memlog as a convenience in case they logged strings
282 lines
8.5 KiB
Python
Executable File
282 lines
8.5 KiB
Python
Executable File
#!/usr/bin/env python
|
|
|
|
'''
|
|
Rough concolic execution implementation
|
|
|
|
Limitations
|
|
- tested only on the simpleassert example program in examples/
|
|
- only works for 3 ints of stdin
|
|
|
|
Bugs
|
|
- Will probably break if a newly discovered branch gets more input/does another read(2)
|
|
- possibly unnecessary deepcopies
|
|
|
|
'''
|
|
|
|
import Queue
|
|
import struct
|
|
import itertools
|
|
|
|
from manticore import Manticore
|
|
from manticore.core.plugin import ExtendedTracer, Follower, Plugin
|
|
from manticore.core.smtlib.constraints import ConstraintSet
|
|
from manticore.core.smtlib import Z3Solver, solver
|
|
from manticore.core.smtlib.visitors import pretty_print as pp
|
|
|
|
import copy
|
|
from manticore.core.smtlib.expression import *
|
|
|
|
prog = '../linux/simpleassert'
|
|
endd = 0x400ae9
|
|
VERBOSITY = 0
|
|
|
|
def _partition(pred, iterable):
|
|
t1, t2 = itertools.tee(iterable)
|
|
return (list(itertools.ifilterfalse(pred, t1)), filter(pred, t2))
|
|
|
|
def log(s):
|
|
print '[+]', s
|
|
|
|
class TraceReceiver(Plugin):
|
|
def __init__(self, tracer):
|
|
self._trace = None
|
|
self._tracer = tracer
|
|
super(self.__class__, self).__init__()
|
|
|
|
@property
|
|
def trace(self):
|
|
return self._trace
|
|
|
|
def will_generate_testcase_callback(self, state, test_id, msg):
|
|
self._trace = state.context[self._tracer.context_key]
|
|
|
|
instructions, writes = _partition(lambda x: x['type'] == 'regs', self._trace)
|
|
total = len(self._trace)
|
|
log('Recorded concrete trace: {}/{} instructions, {}/{} writes'.format(
|
|
len(instructions), total, len(writes), total))
|
|
|
|
def flip(constraint):
|
|
'''
|
|
flips a constraint (Equal)
|
|
|
|
(Equal (BitVecITE Cond IfC ElseC) IfC)
|
|
->
|
|
(Equal (BitVecITE Cond IfC ElseC) ElseC)
|
|
'''
|
|
equal = copy.deepcopy(constraint)
|
|
|
|
assert len(equal.operands) == 2
|
|
# assume they are the equal -> ite form that we produce on standard branches
|
|
ite, forcepc = equal.operands
|
|
assert isinstance(ite, BitVecITE) and isinstance(forcepc, BitVecConstant)
|
|
assert len(ite.operands) == 3
|
|
cond, iifpc, eelsepc = ite.operands
|
|
assert isinstance(iifpc, BitVecConstant) and isinstance(eelsepc, BitVecConstant)
|
|
|
|
equal.operands[1] = eelsepc if forcepc.value == iifpc.value else iifpc
|
|
|
|
return equal
|
|
|
|
def eq(a, b):
|
|
# this ignores checking the conditions, only checks the 2 possible pcs
|
|
# the one that it is forced to
|
|
|
|
ite1, force1 = a.operands
|
|
ite2, force2 = b.operands
|
|
|
|
if force1.value != force2.value:
|
|
return False
|
|
|
|
_, first1, second1 = ite1.operands
|
|
_, first2, second2 = ite1.operands
|
|
|
|
if first1.value != first2.value:
|
|
return False
|
|
if second1.value != second2.value:
|
|
return False
|
|
|
|
return True
|
|
|
|
def perm(lst, func):
|
|
''' Produce permutations of `lst`, where permutations are mutated by `func`. Used for flipping constraints. highly
|
|
possible that returned constraints can be unsat this does it blindly, without any attention to the constraints
|
|
themselves
|
|
|
|
Considering lst as a list of constraints, e.g.
|
|
|
|
[ C1, C2, C3 ]
|
|
|
|
we'd like to consider scenarios of all possible permutations of flipped constraints, excluding the original list.
|
|
So we'd like to generate:
|
|
|
|
[ func(C1), C2 , C3 ],
|
|
[ C1 , func(C2), C3 ],
|
|
[ func(C1), func(C2), C3 ],
|
|
[ C1 , C2 , func(C3)],
|
|
.. etc
|
|
|
|
This is effectively treating the list of constraints as a bitmask of width len(lst) and counting up, skipping the
|
|
0th element (unmodified array).
|
|
|
|
The code below yields lists of constraints permuted as above by treating list indeces as bitmasks from 1 to
|
|
2**len(lst) and applying func to all the set bit offsets.
|
|
|
|
'''
|
|
for i in range(1, 2**len(lst)):
|
|
yield [func(item) if (1<<j)&i else item for (j, item) in enumerate(lst)]
|
|
|
|
def constraints_to_constraintset(constupl):
|
|
x = ConstraintSet()
|
|
x._constraints = list(constupl)
|
|
return x
|
|
|
|
def input_from_cons(constupl, datas):
|
|
' solve bytes in |datas| based on '
|
|
newset = constraints_to_constraintset(constupl)
|
|
|
|
ret = ''
|
|
for data in datas:
|
|
for c in data:
|
|
ret += chr(solver.get_value(newset, c))
|
|
return ret
|
|
|
|
# Run a concrete run with |inp| as stdin
|
|
def concrete_run_get_trace(inp):
|
|
m1 = Manticore.linux(prog, concrete_start=inp, workspace_url='mem:')
|
|
t = ExtendedTracer()
|
|
r = TraceReceiver(t)
|
|
m1.verbosity(VERBOSITY)
|
|
m1.register_plugin(t)
|
|
m1.register_plugin(r)
|
|
m1.run(procs=1)
|
|
return r.trace
|
|
|
|
|
|
def symbolic_run_get_cons(trace):
|
|
'''
|
|
Execute a symbolic run that follows a concrete run; return constraints generated
|
|
and the stdin data produced
|
|
'''
|
|
|
|
m2 = Manticore.linux(prog, workspace_url='mem:')
|
|
f = Follower(trace)
|
|
m2.verbosity(VERBOSITY)
|
|
m2.register_plugin(f)
|
|
|
|
@m2.hook(endd)
|
|
def x(s):
|
|
with m2.locked_context() as ctx:
|
|
readdata = []
|
|
for name, fd, data in s.platform.syscall_trace:
|
|
if name in ('_receive', '_read') and fd == 0:
|
|
readdata.append(data)
|
|
ctx['readdata'] = readdata
|
|
ctx['constraints'] = list(s.constraints.constraints)
|
|
|
|
m2.run()
|
|
|
|
constraints = m2.context['constraints']
|
|
datas = m2.context['readdata']
|
|
|
|
return constraints, datas
|
|
|
|
def contains(new, olds):
|
|
'__contains__ operator using the `eq` function'
|
|
return any(eq(new, old) for old in olds)
|
|
|
|
def getnew(oldcons, newcons):
|
|
"return all constraints in newcons that aren't in oldcons"
|
|
return [new for new in newcons if not contains(new, oldcons)]
|
|
|
|
def constraints_are_sat(cons):
|
|
'Whether constraints are sat'
|
|
return solver.check(constraints_to_constraintset(cons))
|
|
|
|
def get_new_constrs_for_queue(oldcons, newcons):
|
|
ret = []
|
|
|
|
# i'm pretty sure its correct to assume newcons is a superset of oldcons
|
|
|
|
new_constraints = getnew(oldcons, newcons)
|
|
if not new_constraints:
|
|
return ret
|
|
|
|
perms = perm(new_constraints, flip)
|
|
|
|
for p in perms:
|
|
candidate = oldcons + p
|
|
# candidate new constraint sets might not be sat because we blindly
|
|
# permute the new constraints that the path uncovered and append them
|
|
# back onto the original set. we do this without regard for how the
|
|
# permutation of the new constraints combines with the old constratins
|
|
# to affect the satisfiability of the whole
|
|
if constraints_are_sat(candidate):
|
|
ret.append(candidate)
|
|
|
|
return ret
|
|
|
|
def inp2ints(inp):
|
|
a, b, c = struct.unpack('<iii', inp)
|
|
return 'a={} b={} c={}'.format(a, b, c)
|
|
|
|
def ints2inp(*ints):
|
|
return struct.pack('<'+'i'*len(ints), *ints)
|
|
|
|
traces = set()
|
|
def concrete_input_to_constraints(ci, prev=None):
|
|
global traces
|
|
if prev is None:
|
|
prev = []
|
|
trc = concrete_run_get_trace(ci)
|
|
|
|
# Only heed new traces
|
|
trace_rips = tuple(x['values']['RIP'] for x in trc if x['type'] == 'regs')
|
|
if trace_rips in traces:
|
|
return [], []
|
|
traces.add(trace_rips)
|
|
|
|
log("getting constraints from symbolic run")
|
|
cons, datas = symbolic_run_get_cons(trc)
|
|
# hmmm ideally do some smart stuff so we don't have to check if the
|
|
# constraints are unsat. something like the compare the constraints set
|
|
# which you used to generate the input, and the constraint set you got
|
|
# from the symex. sounds pretty hard
|
|
#
|
|
# but maybe a dumb way where we blindly permute the constraints
|
|
# and just check if they're sat before queueing will work
|
|
new_constraints = get_new_constrs_for_queue(prev, cons)
|
|
log('permuting constraints and adding {} constraints sets to queue'.format(len(new_constraints)))
|
|
return new_constraints, datas
|
|
|
|
|
|
def main():
|
|
|
|
q = Queue.Queue()
|
|
|
|
# todo randomly generated concrete start
|
|
stdin = ints2inp(0, 5, 0)
|
|
|
|
log('seed input generated ({}), running initial concrete run.'.format(inp2ints(stdin)))
|
|
|
|
to_queue, datas = concrete_input_to_constraints(stdin)
|
|
for each in to_queue:
|
|
q.put(each)
|
|
|
|
# hmmm probably issues with the datas stuff here? probably need to store
|
|
# the datas in the q or something. what if there was a new read(2) deep in the program, changing the datas
|
|
while not q.empty():
|
|
log('get constraint set from queue, queue size: {}'.format(q.qsize()))
|
|
cons = q.get()
|
|
inp = input_from_cons(cons, datas)
|
|
to_queue, new_datas = concrete_input_to_constraints(inp, cons)
|
|
if len(new_datas) > 0:
|
|
datas = new_datas
|
|
|
|
for each in to_queue:
|
|
q.put(each)
|
|
|
|
log('paths found: {}'.format(len(traces)))
|
|
|
|
if __name__=='__main__':
|
|
main()
|