manticore/examples/script/concolic.py
Yan Ivnitskiy 6896c227ef
Initial implementation of concolic algorithm (#653)
* 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
2017-12-21 17:02:44 -05:00

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()