Repository: angr/angr

Issue:
ClaripyZeroDivisionError without actual zero
When stepping through a BB with symbolic registers, 
division by symbolic register causes state.step() to fail with ClaripyZeroDivisionError.

Example binary [MALWARE!!!]: https://www.dropbox.com/s/n9drwyle246ai86/E022DE72CCE8129BD5AC8A0675996318?dl=0


Example code:

```
# coding=utf-8
import angr
p = angr.Project('E022DE72CCE8129BD5AC8A0675996318', load_options={"auto_load_libs": False})
rebase_delta = p.loader.main_object.image_base_delta
start_state = p.factory.blank_state(addr=rebase_delta + 0x4470)
start_state.step()
```


Discussion:
so it's not the division by a symbolic register, it's the division by a symbolic register and then using the result as a memory address. it's a bad time.

I think I can fix this by making it so that in cases where this pops up, we add the extra constraint that the expression we're requesting a solution for is constrained to an unused variable, which does nothing other than make sure that the expression can be safely evaluated.

Resolving patch:
diff --git a/angr/concretization_strategies/__init__.py b/angr/concretization_strategies/__init__.py
--- a/angr/concretization_strategies/__init__.py
+++ b/angr/concretization_strategies/__init__.py
@@ -1,3 +1,5 @@
+import claripy
+
 class SimConcretizationStrategy(object):
     """
     Concretization strategies control the resolution of symbolic memory indices
@@ -18,29 +20,41 @@ def __init__(self, filter=None, exact=True): #pylint:disable=redefined-builtin
         self._exact = exact
         self._filter = filter
 
+    @staticmethod
+    def _tweak(addr, kwargs):
+        """
+        Utility method used from in here that adds a bogus constraint to extra_constraints making it so that the addr
+        expression can actually be evaluated in all cases
+        """
+        kwargs['extra_constraints'] = kwargs.get('extra_constraints', ()) + (addr == claripy.BVS('TEMP', len(addr)),)
+
     def _min(self, memory, addr, **kwargs):
         """
         Gets the minimum solution of an address.
         """
-        return memory.state.se.min(addr, exact=kwargs.pop('exact', self._exact), **kwargs)
+        self._tweak(addr, kwargs)
+        return memory.state.solver.min(addr, exact=kwargs.pop('exact', self._exact), **kwargs)
 
     def _max(self, memory, addr, **kwargs):
         """
         Gets the maximum solution of an address.
         """
-        return memory.state.se.max(addr, exact=kwargs.pop('exact', self._exact), **kwargs)
+        self._tweak(addr, kwargs)
+        return memory.state.solver.max(addr, exact=kwargs.pop('exact', self._exact), **kwargs)
 
     def _any(self, memory, addr, **kwargs):
         """
         Gets any solution of an address.
         """
-        return memory.state.se.eval(addr, exact=kwargs.pop('exact', self._exact), **kwargs)
+        self._tweak(addr, kwargs)
+        return memory.state.solver.eval(addr, exact=kwargs.pop('exact', self._exact), **kwargs)
 
     def _eval(self, memory, addr, n, **kwargs):
         """
         Gets n solutions for an address.
         """
-        return memory.state.se.eval_upto(addr, n, exact=kwargs.pop('exact', self._exact), **kwargs)
+        self._tweak(addr, kwargs)
+        return memory.state.solver.eval_upto(addr, n, exact=kwargs.pop('exact', self._exact), **kwargs)
 
     def _range(self, memory, addr, **kwargs):
         """


Test patch: