-
Notifications
You must be signed in to change notification settings - Fork 478
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
evm: aggressively check & migrate expressions into current ConstraintSet in case they are global/external #1009
Conversation
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If a user does something like cs.new_bitvec(name='myvar')
then that variable will get a new name like myvar_1
via _get_new_name
. that new name is what's used as the dict key. so if a user then goes to do cs.get_variable('myvar')
it won't work, right?
I guess so. The |
I see. that's very non-obvious :) why do we need to do the from a user perspective it would be very nice to just pick a name for the variable and be able to use that throughout. |
If it does not exist the name the user picked would be the same as in the returned var.name. |
my mistake, didn't read the pr closely enough yet.
very roughly, here's an idea
|
manticore/ethereum.py
Outdated
@@ -631,7 +631,7 @@ def get_source_for(self, asm_offset, runtime=True): | |||
|
|||
@property | |||
def signatures(self): | |||
return dict(((b, a) for (a, b) in self._hashes.items())) | |||
return dict(((b.encode(), a) for (a, b) in self._hashes.items())) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if we want to ref them as bytes should probably just store them as bytes rather than decoding every item on each access to signatures.
since its a hex string, should probably just be str no? this is where python static typing stuff would be handy
rename=True/False instead of avoid_name_collision=True/False ? |
i do think avoid_name_collision is pretty clunky, i didn't put much thought into it :) . but i'm not sure if alternatively what if we have
if you specify name, it must not exist, otherwise an error will be thrown.
I think it should raise there. trying to a create a "new" one with an existing name is an error condition imo. users should probably check to see if a name exists before trying to make a new one. i guess they would use |
my understanding is that there two main users of the
the the manticore/manticore/core/smtlib/solver.py Line 406 in 24cb4bd
where the name is somewhat auto generated, and doesn't particularly matter to anyone anyway, so it's fine to change it. this could all be overcomplicating things though. i'm fine with the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewable status: 0 of 5 files reviewed, 2 unresolved discussions (waiting on @feliam)
manticore/core/state.py, line 211 at r4 (raw file):
label = options.get('label', 'buffer') taint = options.get('taint', frozenset()) expr = self._constraints.new_array(name=label, index_max=nbytes, value_bits=8, taint=taint, avoid_collisions=True)
since this is a user API, I think this should be avoid_collisions=False, if they gave a label/name, otherwise avoid_collissions=True. same below
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this looks awesome, really great work! i don't have a lot of really substantial comments. a lot of it is naming/readability related. a few thoughts on use of avoid_collisions
Reviewable status: 0 of 5 files reviewed, 15 unresolved discussions (waiting on @feliam)
manticore/ethereum.py, line 1198 at r4 (raw file):
value=100000 ) ''' return self.constraints.new_array(index_bits=256, name=name, index_max=size, value_bits=8, taint=frozenset(), avoid_collisions=True)
i'm also thinking avoid_collisions here should depend on whether a name was given
manticore/ethereum.py, line 1239 at r4 (raw file):
state_constraints = state.constraints migration_bindings = state.context.get('migration_bindings')
can be simplified to .get('migration_bindings', {})
manticore/ethereum.py, line 1242 at r4 (raw file):
if migration_bindings is None: migration_bindings = {} migrated_constraint = state_constraints.migrate(constraint, migration_bindings=migration_bindings)
we should use state.migrate_expression here? it looks copypastad
manticore/ethereum.py, line 1784 at r4 (raw file):
return self.accounts[name] def __migrate_tx_expressions(self, state, caller, address, value, data):
nit, i think we should use 1 underscore here. 2 means something special i think
manticore/ethereum.py, line 1796 at r4 (raw file):
if migration_bindings is None: migration_bindings = {} if issymbolic(caller):
imo we should add some comments here to explain why, it's not super obvious. I guess the reason is that commonly users will be making these symbolic by creating global symbolic variables via ManticoreEVM.make_.... and those global expressions need to be imported into each state when a tx actually happens
manticore/core/state.py, line 281 at r4 (raw file):
def can_be_true(self, expr): expr = self.migrate_expression(expr)
i wonder if it's necessary to sprinkle this everywhere now. maybe the user should be aware when they are mixing expressions with unrelated states/constraintsets and call migrate_expression first?
manticore/core/smtlib/constraints.py, line 213 at r4 (raw file):
return self.to_string() def _get_new_name(self, name='VAR'):
nit, while we're here maybe we can rename this to _make_unique_name
manticore/core/smtlib/constraints.py, line 219 at r4 (raw file):
return name def migrate(self, expression, migration_bindings=None):
maybe migrate_expression would be a better name here. it took me a bit to understand that the only affect on the state here was adding variables, but didn't automatically apply the expression/constraint. not totally sure about this, maybe migrate is enough. might be enough to just add some more details to the docstring on how this function basically just creates the needed variables in the constraint set
manticore/core/smtlib/constraints.py, line 225 at r4 (raw file):
:param migration_bindings: a name to name mapping of already migrated variables ''' if migration_bindings is None:
i think this name is also a bit confusing, rather than call them bindings, maybe "map". i think a little more verbose description of what this variable is would be useful.
manticore/core/smtlib/constraints.py, line 231 at r4 (raw file):
# Based on the name mapping in migration_bindings build an object to # object mapping to be used in the replacing of variables fat_bindings = {}
i think we should choose a better name for fat_bindings, it's not very clear what it is based on the name. it's the actual map from "alient" expression object, to the newly created native object. maybe something like foreign_to_native_expression_map? but that is pretty verbose. i think throughout this code could be made more readable by deciding on a convention like "foreign"/"native" or alien/local etc etc and using those in the variable names throughout. i can submit a PR with what i think could be more readable
manticore/core/smtlib/constraints.py, line 236 at r4 (raw file):
for old_name in expression_variables: migrated_name = migration_bindings.get(old_name) if migrated_name in declared_names:
rather than have this declared_names variable, we could use self.get_variable
for this check? e.g
native_var = self.get_variable(migrated_name)
if native_var is not None:
fat_bindings[....] = native_var
it would make this a bit easier to read by reducing the number of local vars
manticore/core/smtlib/constraints.py, line 255 at r4 (raw file):
if name in self._declarations: name = self._get_new_name(var.name + '_migrated') if name in self._declarations:
should we use a loop here? the point is to get a unique name right? loop bumping some int until we have a unique name?
manticore/core/smtlib/constraints.py, line 265 at r4 (raw file):
new_var = self.new_array(index_max=var.index_max, index_bits=var.index_bits, value_bits=var.value_bits, name=name).array else: raise NotImplemented("Unknown type {}".format(type(var)))
this err msg could be a bit more verbose, "Unknown expression type encountered during expression migration"
manticore/core/smtlib/constraints.py, line 220 at r7 (raw file): Previously, mossberg (Mark Mossberg) wrote…
The idea is that when you migrate the same variable twice it maps to the same local variable. It maps alien names with local declared names. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewable status: 5 of 8 files reviewed, 6 unresolved discussions (waiting on @Mossberg and @feliam)
manticore/core/smtlib/constraints.py, line 215 at r5 (raw file):
Previously, mossberg (Mark Mossberg) wrote…
we should just do
if name in self._declarations
Done.
manticore/core/smtlib/constraints.py, line 269 at r5 (raw file):
Previously, mossberg (Mark Mossberg) wrote…
I still don't see why we need to create that list of tuples. get_variables() returns a set. why can't we just iter through the set?
for expression_var in get_variables(expression): # blah blah expression_var.name
Done.
manticore/core/smtlib/constraints.py, line 271 at r5 (raw file):
Previously, mossberg (Mark Mossberg) wrote…
ok, i reread this, and i'm still having trouble understanding it exactly.
--
is it correct to say that object_migration_map's keys should ALWAYS be external/foreign expressions, and its values should ALWAYS be internal/local expressions?
if this is the case, this invariant can be violated if
- expression_var is a local ConstraintSet variable
- expression_name is in migration_map and it's value corresponds to an expression that is also in this ConstraintSet
in which keys object_migration_map will record a mapping from a local expression to another local expression, which I don't understand, since there is no migration necessary in this case?
--
i'm also confused by this .get() call. is the intention for this loop body to do nothing if expression_name is not in the name_migration_map? right now i can see that it is implicitly doing nothing, because the .get() will return None, which will cause get_variable() to return None. however this is pretty convoluted. if this is the intention, I think we should have an explicit
if migrated_name is None: continue
line
is it correct to say that object_migration_map's keys should ALWAYS be external/foreign expressions, and its values should ALWAYS be internal/local expressions?
that's correct.
Let see how the new arrangement holds up with that invariant in mind.. actually I'm adding it as a comment.
manticore/core/smtlib/constraints.py, line 284 at r5 (raw file):
Previously, mossberg (Mark Mossberg) wrote…
i'm confused by this check in the first place. when would this if succeed?
shouldn't we instead be checking if var exists as a key in object_migration_map? the point here is to check if it already has a replacement assigned, right?
so right now we're checking if it's in the values. from what i see, all of the values in object_migration_map belong to the local ConstraintSet. therefore, they would appear in get_declared_variables, and above get_declared_variables check would succeed. so i don't quite see how we would get past this if.
Done.
manticore/core/smtlib/constraints.py, line 216 at r8 (raw file):
Previously, mossberg (Mark Mossberg) wrote…
i'd like to add a comment here
"the while loop is necessary because appending the result of _get_sid() is not guaranteed to make a unique name on the first try; a colliding name could have been added previously"
Done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
great, algorithm looks sound to me now, and i love that it's not 2 loops :)
Reviewed 3 of 3 files at r9.
Reviewable status: all files reviewed, 9 unresolved discussions (waiting on @feliam)
manticore/core/smtlib/constraints.py, line 223 at r9 (raw file):
return name def migrate(self, expression, name_migration_map=None):
ok, i finally understand name_migration_map. it took a while for it to click to me that this is persistently stored in the State and passed into this on each migration. I think to make this code more readable, I'd like to propose renaming name_migration_map
to previously_migrated_map
manticore/core/smtlib/constraints.py, line 234 at r9 (raw file):
``` from manticore.core.smtlib import *
now that there's a unit test can we rm this? it will just become bitrotted and outdated.
manticore/core/smtlib/constraints.py, line 261 at r9 (raw file):
:param expression: the potentially foreign expression :param name_migration_map: a name to name mapping of already migrated variables
would like to expand on this:
:param previously_migrated_map: mapping of already migrated variables. maps from string name of foreign variable to its currently existing migrated string name
manticore/core/smtlib/constraints.py, line 278 at r9 (raw file):
# do nothing if it is a known/declared variable object if any(expression_var is x for x in self.get_declared_variables()):
this strikes me as worth being a ConstraintSet method. will make this already complex function easier to read. if self.is_declared(expression_var)
or if expression_var in self
?
manticore/core/smtlib/constraints.py, line 285 at r9 (raw file):
migrated_name = name_migration_map[expression_var.name] native_var = self.get_variable(migrated_name) if native_var is None:
this actually looks more appropriate for an assert to me. this is not an error condition that we expect to ever happen, assert native_var is not None
is a strict invariant? it seems like a serious internal error if name_migration_map/previously_migrated_map contains a value which does not exist.
manticore/core/smtlib/constraints.py, line 286 at r9 (raw file):
native_var = self.get_variable(migrated_name) if native_var is None: raise Exception("name_migration_map contains an unknown variable")
i'd say "contains a variable that does not exist in this ConstraintSet" to be very clear
manticore/core/smtlib/constraints.py, line 289 at r9 (raw file):
object_migration_map[expression_var] = native_var #continue if there is already a migrated variable for it continue
i think we would also improve the readability by removing the "continue" and using an explicit "else" block for the below block where a new_var is created. what do you think?
if expression_var in self: # or whatever
continue
# what about this? just for readability I guess. at this point, we've confirmed it's foreign. this naming throughout helps the reader understand the key invariant commented above.
foreign_var = expression_var
if foreign_var.name in previously_migrated_map:
#
native_var = ....
else:
# make new_var
native_var = new_var
previously_migrated[foreign_var.name] = new_var.name
object_migration_map[foreign_var] = native_var
manticore/core/smtlib/constraints.py, line 292 at r9 (raw file):
# expression_var was not found in the local declared variables nor # any variable with the dsame name was previously migrated
dsame typo
tests/test_models.py, line 30 at r9 (raw file):
def _clear_constraints(self): self.state.context['migration_map']=None
why is this necessary exactly? should the migration stuff be able to gracefully default if 'migration_map' is not in the context? migration stuff has no relevance to model tests, so i don't really think this should be here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewable status: all files reviewed, 9 unresolved discussions (waiting on @feliam and @Mossberg)
manticore/core/smtlib/constraints.py, line 234 at r9 (raw file):
Previously, mossberg (Mark Mossberg) wrote…
now that there's a unit test can we rm this? it will just become bitrotted and outdated.
Done.
manticore/core/smtlib/constraints.py, line 278 at r9 (raw file):
Previously, mossberg (Mark Mossberg) wrote…
this strikes me as worth being a ConstraintSet method. will make this already complex function easier to read.
if self.is_declared(expression_var)
orif expression_var in self
?
Done.
manticore/core/smtlib/constraints.py, line 285 at r9 (raw file):
Previously, mossberg (Mark Mossberg) wrote…
this actually looks more appropriate for an assert to me. this is not an error condition that we expect to ever happen,
assert native_var is not None
is a strict invariant? it seems like a serious internal error if name_migration_map/previously_migrated_map contains a value which does not exist.
Done.
manticore/core/smtlib/constraints.py, line 289 at r9 (raw file):
Previously, mossberg (Mark Mossberg) wrote…
i think we would also improve the readability by removing the "continue" and using an explicit "else" block for the below block where a new_var is created. what do you think?
if expression_var in self: # or whatever continue # what about this? just for readability I guess. at this point, we've confirmed it's foreign. this naming throughout helps the reader understand the key invariant commented above. foreign_var = expression_var if foreign_var.name in previously_migrated_map: # native_var = .... else: # make new_var native_var = new_var previously_migrated[foreign_var.name] = new_var.name object_migration_map[foreign_var] = native_var
I tried to pre-filter the list of variable so we do not need to "continue"
manticore/core/smtlib/constraints.py, line 292 at r9 (raw file):
Previously, mossberg (Mark Mossberg) wrote…
dsame typo
Done.
tests/test_models.py, line 30 at r9 (raw file):
Previously, mossberg (Mark Mossberg) wrote…
why is this necessary exactly? should the migration stuff be able to gracefully default if 'migration_map' is not in the context? migration stuff has no relevance to model tests, so i don't really think this should be here.
This is trying to clean the constraints of a constraintset in a state and re use it. If you keep old migration mappings there is trouble. I can skip the test that make problem if you prefer and you fix them later?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewable status: 7 of 8 files reviewed, 5 unresolved discussions (waiting on @Mossberg and @feliam)
manticore/core/smtlib/constraints.py, line 227 at r10 (raw file):
if not isinstance(expression_var, Variable): raise ValueError("Expression must be a Variable") return any(expression_var is x for x in self.get_declared_variables()):
watch out! stray colon!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed 1 of 1 files at r10.
Reviewable status: all files reviewed, 3 unresolved discussions (waiting on @feliam)
manticore/core/smtlib/constraints.py, line 242 at r10 (raw file):
:param name_migration_map: mapping of already migrated variables. maps from string name of foreign variable to its currently existing migrated string name. this is updated during this migration. :return: a migrated expresion where all the variables are fresh BoolVariable. name_migration_map is updated
are all the variables in the returned expression BoolVariable? couldn't they just be regular variables? for example, if a BitVecAdd
with 2 BitVec
children was "migrated", wouldn't the returned expression look the same? There would be no BoolVariables
?
manticore/core/smtlib/constraints.py, line 265 at r10 (raw file):
assert native_var is not None, "name_migration_map contains a variable that does not exist in this ConstraintSet" object_migration_map[foreign_var] = native_var #continue if there is already a migrated variable for it
don't need this comment anymore
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewable status: all files reviewed, 5 unresolved discussions (waiting on @feliam)
manticore/core/smtlib/constraints.py, line 173 at r10 (raw file):
def get_variable(self, name): ''' Returns the variable declared under name or None if it does not exists ''' if name not in self._declarations:
return self._declarations.get(name, None)
?
manticore/core/smtlib/constraints.py, line 275 at r10 (raw file):
migrated_name = self._make_unique_name(foreign_var.name + '_migrated') # Create and declare a new variable of given type if isinstance(foreign_var, Bool):
This pattern comes up pretty regularly (in Solver.get_all_values
, Solver.get_value
, here), should we make a Expression.clone()
method that a few relevant classes can override?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewable status: all files reviewed, 5 unresolved discussions (waiting on @feliam)
manticore/core/smtlib/constraints.py, line 275 at r10 (raw file):
Previously, yan (Yan Ivnitskiy) wrote…
This pattern comes up pretty regularly (in
Solver.get_all_values
,Solver.get_value
, here), should we make aExpression.clone()
method that a few relevant classes can override?
i generally agree, but i think we should save that for a different PR. this one already has a lot of complexity
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewable status: all files reviewed, 5 unresolved discussions (waiting on @feliam, @Mossberg, and @yan)
manticore/core/smtlib/constraints.py, line 242 at r10 (raw file):
Previously, mossberg (Mark Mossberg) wrote…
are all the variables in the returned expression BoolVariable? couldn't they just be regular variables? for example, if a
BitVecAdd
with 2BitVec
children was "migrated", wouldn't the returned expression look the same? There would be noBoolVariables
?
Done.
manticore/core/smtlib/constraints.py, line 265 at r10 (raw file):
Previously, mossberg (Mark Mossberg) wrote…
don't need this comment anymore
Done.
manticore/core/smtlib/constraints.py, line 275 at r10 (raw file):
Previously, mossberg (Mark Mossberg) wrote…
i generally agree, but i think we should save that for a different PR. this one already has a lot of complexity
diff pr
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed 1 of 1 files at r11.
Reviewable status: all files reviewed, 2 unresolved discussions (waiting on @feliam and @yan)
manticore/core/smtlib/constraints.py, line 173 at r10 (raw file):
Previously, yan (Yan Ivnitskiy) wrote…
return self._declarations.get(name, None)
?
+1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewable status: all files reviewed, 2 unresolved discussions (waiting on @yan)
manticore/core/smtlib/constraints.py, line 173 at r10 (raw file):
Previously, mossberg (Mark Mossberg) wrote…
+1
Done.
manticore/core/smtlib/constraints.py, line 275 at r10 (raw file):
Previously, feliam (feliam) wrote…
diff pr
Let's make an issue maybe?
manticore/core/smtlib/constraints.py, line 275 at r10 (raw file): Previously, feliam (feliam) wrote…
#1059 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewable status: 7 of 8 files reviewed, 2 unresolved discussions (waiting on @Mossberg and @yan)
manticore/core/smtlib/constraints.py, line 275 at r10 (raw file):
Previously, feliam (feliam) wrote…
#1059
done!
Done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed 1 of 1 files at r12, 1 of 1 files at r13.
Reviewable status: all files reviewed, 2 unresolved discussions (waiting on @yan)
* Python 3; optimization / stylization pass * cleanup list() from automation tools * style; use dict comprehensions * style; use set literals * Experiment reporting the finding at a JUMPI (#949) * Experiment reporting the finding at a JUMPI * Fix taint. Detect returned overflowded data * Fix contract names in benchmark * Move default plugin registration * merge * rm make_evm (#978) * Yolo dev evm fix address concretization (#1002) * DAO detector + bugfixes * The actual benchmark tests * The actual benchmark tests * CC * Experiment reporting the finding at a JUMPI * Fix taint. Detect returned overflowded data * DAO -> Reentrancy * DAO -> reentrancy, C -> Benchmark * DAO -> reentrancy, C -> Benchmark * Allow function names to have numbers * Fix contract names in benchmark * Fix contract names in benchmark * Move default plugin registration * Better regexp * Fix minimal_bytecode example * Fix Array Slice and test * add tests * correct other bug * implement bytesM * BROKEN partial progress * need bytearray here * rm cmt * add basic tests for bytesM and bytes symbolic * correct bytes symbolic test * Refactor, clean bytesM handling * Add initial symbolic 'bytes' handling * refactor tests * Unify symbolic/concrete bytes handling in bytesM/bytes * Rm import * Rm debug assert * cc * Visitor/migrate/simplify fixes to make the seth refactor pass * Fix concolic? * Fix concolic? * CC * bytesM fix * Fix address and caller concretization on symb tx * Fix account policy refactor * CC * cleanup * numbers.Integral * super() * remove/update deprecated * Report test coverage to CodeClimate (#1004) This PR enables the reporting of test coverage of all the test jobs (`eth` and `tests`) to CodeClimate. This uses S3 to temporarily store results between jobs and later upload them to CC. Fixes #1000 * codeclimate * codeclimate - bump similar-code thresh; false positive * Fix CC coverage (#1007) This fix does two things: 1. Ignores non-manticore files from the coverage report to limit what can fail. 2. Changes how travis runs s3 sync on completion. (Fixes #1006) * Report test coverage to CodeClimate (#1004) This PR enables the reporting of test coverage of all the test jobs (`eth` and `tests`) to CodeClimate. This uses S3 to temporarily store results between jobs and later upload them to CC. Fixes #1000 * Fix CC coverage (#1007) This fix does two things: 1. Ignores non-manticore files from the coverage report to limit what can fail. 2. Changes how travis runs s3 sync on completion. (Fixes #1006) * re-enable and fix eth regression 808 (#1011) * cleanup examples (#1010) * resolves #1008 (#1014) * Addresses performance issues; * reimplement caching for `arithmetic_simplifier` and `constant_folder` * optimize `ArithmeticSimplifier.visit_ArraySelect` * File mode fix - resolves #1018 * Fixes closed file serialization (#955) Fixes #954 * Add unit test for 954 (#1022) * Change how we query for version (#1023) Fixes #1021 This also should decrease how many times we invoke z3. (The instance used to query version should stick around) * Use capstone 3.0.5 and no longer rc2 (#1026) * binja cleanup * fixes docker - resolves #991 * Dev yolo retvalthing (#1001) * DAO detector + bugfixes * The actual benchmark tests * The actual benchmark tests * CC * Experiment reporting the finding at a JUMPI * Fix taint. Detect returned overflowded data * DAO -> Reentrancy * DAO -> reentrancy, C -> Benchmark * DAO -> reentrancy, C -> Benchmark * Allow function names to have numbers * Fix contract names in benchmark * Fix contract names in benchmark * Move default plugin registration * Better regexp * Fix minimal_bytecode example * Fix Array Slice and test * add tests * correct other bug * implement bytesM * BROKEN partial progress * need bytearray here * rm cmt * add basic tests for bytesM and bytes symbolic * correct bytes symbolic test * Refactor, clean bytesM handling * Add initial symbolic 'bytes' handling * refactor tests * Unify symbolic/concrete bytes handling in bytesM/bytes * Rm import * Rm debug assert * cc * Visitor/migrate/simplify fixes to make the seth refactor pass * Fix concolic? * Fix concolic? * CC * bytesM fix * Fix address and caller concretization on symb tx * Fix/refactor symbolic address/caller concretization * Fix caller concretization * Fix expression visiting * Fix account policy refactor * Accept numbers in function names abitypes * Simplify installation instructions to recommend install manticore only for the current user * Run some tests in parallel (#970) This PR splits the current test runner into three environments: 1. Linux examples 2. Ethereum tests 3. Remaining tests to faster complete each testing run. Ethereum tests include a number of integration tests that execute scripts to completion, which takes a while. We run them concurrently with other tests to save on execution time. The split is done by naming Ethereum tests differently (`eth_*.py` vs `test_*.py`) and updating what pattern unittest's `discover` uses. This change also updates the installation script and chooses to forego installing Keystone for EVM tests as it takes a while, and it adds a `setup.cfg` config file so that Nose finds the eth tests as well by default. * Be less verbose when testing * Fix slicing wrongly reference to proxyArray. Fix #912 * Only export human/external tx in the testcase (#972) * Make ManticoreEVM.make_symbolic_value size adjustable (#974) * Make size adjustable * Default to 256 * Dev evm yolo fix gas (#975) * Fix gas stipend on CALL and check dao * Add order dependence 1 * Going linter. Report/Detect that thing when code does not check returned value * cleaner example of fail * Update retval_crazy.sol * new solc for travis * CC * Remove duplicated ReentrancyDetector * POrt to py3 * POrt to py3 * P0rt to py3 * CC * Tests doc * CC * review changes * remove stray comment * missed one * resolves #992 (#1033) * resolves #992 * fix sys_write logger output (#1024) * fix sys_write logger output - resolves #1020 * write/writev/read fixes * openat((int32)dirfd, ...) resolves #940, syscall logging * disable E701, interferes with PEP484/526 * readme Ethereum update issue #1003 (#1034) * readme ethereum update issue #1003 * simplify * Update README.md * ignore resource warnings (e.g. unclosed files) (#1038) * Test manticore on MacOS (#1032) * Test manticore on MacOS like test_binaries.py for path to binary to test * MacOS compatibility achieved Replacement of /bin/ls in tests Use of basename in test_load_maps * Fix gast (#1039) * Readme updates (#1037) * add some more heft to the Ethereum section * no longer needed * Integrate requirements into installation * Update README.md * Update README.md * Update README.md * Update README.md * Duplicate commands for docker quick start * Rm --process-dependency-links note, moved into the faq on the wiki * Small tweaks * pedantic formatting * Emphasize new python requirement (#1041) * Emphasize new python requirement * Consistent formatting * Port remaining examples to py3 (#1042) * port use_def * port some scripts, cleanup * ported `scripts/gdb.py` - untested * misc * Manticore 0.2.0 (#1043) * Bump version * Initial changelog changes * Bump version in setup.py * Add skeleton and externals * Fill in 0.2.0 readme * Updates * Add logo to readme (#1046) * add logo to README * Fix missing profiling data (#1057) * fix missing profiling data - resolves #982 * unit test * Code cleanup and coverage (#1035) * dead code elimination, __init__ cleanup * `binary.Elf` bugfix, add `binary` package tests * Serialization cleanup (#1048) * refactor serialization / recursion limit handling * evm: aggressively check & migrate expressions into current ConstraintSet in case they are global/external (#1009) * Be mega forgiving on global expression usage - EVM * Refactor new_bitvector api * Fix neW_bool * CC * rename avoid_collisions collision * rename avoid_collisions collision * migrate on state.constraint too.. * Migration bugfixes * CC bugfixes * invalid assert removed * move rep code to method * reviewing the codes * CC * Change variable names * typo * Some mini docstrings and a unittest * Add migration integration testion * Keep fuzz-refactoring it * CC * Bugfixfixfixfix * CC * re refactor mig algorithm * better cleaner stronger. (reviewing) * CC * Small refactor and Fix strange strcmp test. * CC * re re refactor for readability * CC * rev * forgoten var * Fix for #1008 (#1063) * Fix for #1008 * add test for funcall output * Implements support for function overloading in ethereum (#1049) * implements `signature` kwarg for overloaded functions - resolves #810 * Fix typo mistake in multi-million word (#1073) * eth: add selfdestruct detector & misc bug fixes (#1068) * Don't keep selfdestruct states alive * Use avoid_collisions=True for internal uses of the .new_ methods * Better err msgs * Output pc in hex * Fix ignored workspace cli flag * hex pc * hex pc one last time * add selfdestruct detector * Add cli support * Add ok selfdestruct test * Add selfdestruct not ok - true positive * Add selfdestruct crazy - true negative * Reorganize plugin/detectors. Add LoopDepthLimiter plugin + cli flag * rename files * add another test * Add initial selfdestruct tests * Move integer overflow detector test into eth_detectors * cc * add missing import * add other missing import * Added --txnoether option to avoid sending ether to contracts (#1078) * added --txnoether option * Improved command line description * eth: add ether leak detector (#1077) * Add initial ether leak detector * Initial test * correct * Add another neg * rm stray print * initial tests refactoring + ether leak tests * finding name * initial refactor * clean comment * correct this test * update tests * Add fp comment * add other test * remove unnecessary payable function * make LoopDepthLimiter configurable * Use real pc * cc * Add other test * Add cli interface * Create readthedocs.yml (#1085) * Fix rtd (#1086) * test * wrong number * sorry Popen :( * mocking * x * clean * better explain this arcane stuff * don't need io * Improved printing of constructor call with decoded constructor arguments and transaction result (#1080) * added printing of decoded constructor arguments * Fixed test * Add --no-testcases flag (#1083) * Update the README (#1064) <!-- Reviewable:start --> This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/trailofbits/manticore/1064) <!-- Reviewable:end --> * Add detector for plain external call (#1087) * initial refactor etherleak to also do general external call * refactor * Update users * Update tests * Update * Fix tests * Don't use signed operator, check != 0 * Record constraint * Record constraint * Use did_evm_execute So we don't falsely report if the CALL were to fail * Revert "Use did_evm_execute" 96a84f2 * simplify deref logic * clean up derefs; rename backing array * reduce write calls * simplify * add name field * Detection of environmental and potentially manipulable instruction/data (#1096) * unittest * CC * import fix * typo * forgotten test * eth: new/alternative reentrancy detector (#1082) * initial second one * update * polish * correct * Correctly check gas * Record gas constraint and save in finding * simplify logic * Check if destination is a contract * Revert "Check if destination is a contract" 901be37 * better context key * Be lenient with Constants * Add new simpler/less input required reentrancy detector, use in the cli * Fix bad merge import * Fix import * Add final missing import * add an iter() interface to Memory * Add env instruction detector to cli (#1105) * Sha3 rework and performance enhancements (#1031) * DAO detector + bugfixes * The actual benchmark tests * The actual benchmark tests * CC * Experiment reporting the finding at a JUMPI * Fix taint. Detect returned overflowded data * DAO -> Reentrancy * DAO -> reentrancy, C -> Benchmark * DAO -> reentrancy, C -> Benchmark * Allow function names to have numbers * Fix contract names in benchmark * Fix contract names in benchmark * Move default plugin registration * Better regexp * Fix minimal_bytecode example * Fix Array Slice and test * add tests * correct other bug * implement bytesM * BROKEN partial progress * need bytearray here * rm cmt * add basic tests for bytesM and bytes symbolic * correct bytes symbolic test * Refactor, clean bytesM handling * Add initial symbolic 'bytes' handling * refactor tests * Unify symbolic/concrete bytes handling in bytesM/bytes * Rm import * Rm debug assert * cc * Visitor/migrate/simplify fixes to make the seth refactor pass * Fix concolic? * Fix concolic? * CC * bytesM fix * Fix address and caller concretization on symb tx * Fix/refactor symbolic address/caller concretization * Fix caller concretization * Fix expression visiting * Fix account policy refactor * Accept numbers in function names abitypes * Simplify installation instructions to recommend install manticore only for the current user * Run some tests in parallel (#970) This PR splits the current test runner into three environments: 1. Linux examples 2. Ethereum tests 3. Remaining tests to faster complete each testing run. Ethereum tests include a number of integration tests that execute scripts to completion, which takes a while. We run them concurrently with other tests to save on execution time. The split is done by naming Ethereum tests differently (`eth_*.py` vs `test_*.py`) and updating what pattern unittest's `discover` uses. This change also updates the installation script and chooses to forego installing Keystone for EVM tests as it takes a while, and it adds a `setup.cfg` config file so that Nose finds the eth tests as well by default. * Be less verbose when testing * Fix slicing wrongly reference to proxyArray. Fix #912 * Only export human/external tx in the testcase (#972) * Make ManticoreEVM.make_symbolic_value size adjustable (#974) * Make size adjustable * Default to 256 * Dev evm yolo fix gas (#975) * Fix gas stipend on CALL and check dao * Add order dependence 1 * Going linter. Report/Detect that thing when code does not check returned value * cleaner example of fail * Update retval_crazy.sol * new solc for travis * CC * Remove duplicated ReentrancyDetector * POrt to py3 * POrt to py3 * P0rt to py3 * CC * Be mega forgiving on global expression usage - EVM * Tests doc * Refactor new_bitvector api * function id to binary * Fix neW_bool * CC * rename avoid_collisions collision * rename avoid_collisions collision * migrate on state.constraint too.. * Migration bugfixes * CC bugfixes * invalid assert removed * move rep code to method * unittets fixes and CC * CC * Refactor result_ref out in favor of change_last_result() * CC * reviewing the codes * CC * Change variable names * typo * Basic refactors and output enhancements * Some minid docstrings and a unittest * Some mini docstrings and a unittest * Add migration integration testion * Keep fuzz-refactoring it * CC * Bugfixfixfixfix * CC * re refactor mig algorithm * better cleaner stronger. (reviewing) * CC * Small refactor and Fix strange strcmp test. * CC * funtion selector abinary * bugfix.. waiting for migreation PR * convenient tx abi parsing func * convenient tx abi parsing func * convenient tx abi parsing func * convenient tx abi parsing func * re re refactor for readability * CC * rev * CC * forgoten var * CC * CC * review * typo * CC * review * Adding single example to sha3 trick when there are not know examples * CC * review * CC * Forgotten rollback * CC * Detect the odd delegatecall instruction (#1108) * DAO detector + bugfixes * The actual benchmark tests * The actual benchmark tests * CC * Experiment reporting the finding at a JUMPI * Fix taint. Detect returned overflowded data * DAO -> Reentrancy * DAO -> reentrancy, C -> Benchmark * DAO -> reentrancy, C -> Benchmark * Allow function names to have numbers * Fix contract names in benchmark * Fix contract names in benchmark * Move default plugin registration * Better regexp * Fix minimal_bytecode example * Fix Array Slice and test * add tests * correct other bug * implement bytesM * BROKEN partial progress * need bytearray here * rm cmt * add basic tests for bytesM and bytes symbolic * correct bytes symbolic test * Refactor, clean bytesM handling * Add initial symbolic 'bytes' handling * refactor tests * Unify symbolic/concrete bytes handling in bytesM/bytes * Rm import * Rm debug assert * cc * Visitor/migrate/simplify fixes to make the seth refactor pass * Fix concolic? * Fix concolic? * CC * bytesM fix * Fix address and caller concretization on symb tx * Fix/refactor symbolic address/caller concretization * Fix caller concretization * Fix expression visiting * Fix account policy refactor * Accept numbers in function names abitypes * Simplify installation instructions to recommend install manticore only for the current user * Run some tests in parallel (#970) This PR splits the current test runner into three environments: 1. Linux examples 2. Ethereum tests 3. Remaining tests to faster complete each testing run. Ethereum tests include a number of integration tests that execute scripts to completion, which takes a while. We run them concurrently with other tests to save on execution time. The split is done by naming Ethereum tests differently (`eth_*.py` vs `test_*.py`) and updating what pattern unittest's `discover` uses. This change also updates the installation script and chooses to forego installing Keystone for EVM tests as it takes a while, and it adds a `setup.cfg` config file so that Nose finds the eth tests as well by default. * Be less verbose when testing * Fix slicing wrongly reference to proxyArray. Fix #912 * Only export human/external tx in the testcase (#972) * Make ManticoreEVM.make_symbolic_value size adjustable (#974) * Make size adjustable * Default to 256 * Dev evm yolo fix gas (#975) * Fix gas stipend on CALL and check dao * Add order dependence 1 * Going linter. Report/Detect that thing when code does not check returned value * cleaner example of fail * Update retval_crazy.sol * new solc for travis * CC * Remove duplicated ReentrancyDetector * POrt to py3 * POrt to py3 * P0rt to py3 * CC * Be mega forgiving on global expression usage - EVM * Tests doc * Refactor new_bitvector api * function id to binary * Fix neW_bool * CC * rename avoid_collisions collision * rename avoid_collisions collision * migrate on state.constraint too.. * Migration bugfixes * CC bugfixes * invalid assert removed * move rep code to method * unittets fixes and CC * CC * Refactor result_ref out in favor of change_last_result() * CC * reviewing the codes * CC * Change variable names * typo * Basic refactors and output enhancements * Some minid docstrings and a unittest * Some mini docstrings and a unittest * Add migration integration testion * Keep fuzz-refactoring it * CC * Bugfixfixfixfix * CC * re refactor mig algorithm * better cleaner stronger. (reviewing) * CC * Small refactor and Fix strange strcmp test. * CC * funtion selector abinary * bugfix.. waiting for migreation PR * convenient tx abi parsing func * convenient tx abi parsing func * convenient tx abi parsing func * convenient tx abi parsing func * re re refactor for readability * CC * rev * CC * forgoten var * CC * CC * Delete duplicated detector * WIP delegatecall. Lot of fixes. Recursion fix. * review * typo * CC * Sha3 random concre example when none. Concretize SIZE/OFFSET more. Initial calldata size management * remove debug print * Add check in constraints.add * review * Adding single example to sha3 trick when there are not know examples * CC * review * CC * about to merge sha3 * cleanups * make gas budget configurable by user * cleanups * cleanups * CC: * CC * Fix typo in tests * Fix import typo * pump some gas * typo in skipping slow/big test * skipping more test to make travis happy * skipping more test to make travis happy * debugging travis like a caveman * dbg * dbg * dbg * undbg * undbg * undbg * undbg * undbg and fixed * undbg and fixed * CC * Updates to README.md relating to Python 3 migration and sudo within virtualenv setup (#1109) * updated README.md to use python3 commands * updated README.md to add sudo to system pip3 install commands Line 186 uses a path to the specific pip3 binary (as per https://stackoverflow.com/questions/41429988/inside-virtual-env-sudo-pip-links-to-the-global-python-pip ). * Manticore 0.2.1 (#1106) * Bump version num * changelog skeleton * Switch to agpl * readme license update * update * gas * Add dc * Date update * Add last minute contributions * Release 0.2.1c (#1111) * Fix the versioning hell (#1112) * Fix version number / release (#1113) * Manticore 0.2.1-berlin (#1114) * Manticore 0.2.1-b (#1115) * manticore 0.2.1.1 (#1116) * start scan_mem refactor * Fix DecodeException message * Only import mapped memory * get a single value, instead of all, when decoding * clean up instruction decoding * simplify scan_mem * Changed instances of Concretice to Concretize (#1118) * Fix typo * rename a field * Attempt decoding with an arraystore simplifier * python3 update to linux example makefile (#1122) Ubuntu 18.04 doesn't alias python to python3 * Update decoding logic * Simplify [skip] importing read-only maps * Fix name serialization with anonmaps
this pr introduces advanced functionality (state.migrate_expression, and friends) for migration of potentially external/global ("foreign") expression objects into a particular ConstraintSet. with recent developments in the Ethereum API specifically (global expressions via `ManticoreEVM.make_....1), we expect foreign expressions to be passed into these interfaces fairly frequently now, so that PR "aggressively" adds a call to this function in nearly every interface that accepts an expression object, in order to be as safe as possible
This change is![Reviewable](https://camo.githubusercontent.com/1541c4039185914e83657d3683ec25920c672c6c5c7ab4240ee7bff601adec0b/68747470733a2f2f72657669657761626c652e696f2f7265766965775f627574746f6e2e737667)