import claripy
from ..smart_find_mixin import SmartFindMixin
[docs]class StaticFindMixin(SmartFindMixin): # pylint:disable=abstract-method
"""
Implements data finding for abstract memory.
"""
[docs] def find(
self,
addr,
data,
max_search,
default=None,
endness=None,
chunk_size=None,
max_symbolic_bytes=None,
condition=None,
char_size=1,
**kwargs,
): # pylint:disable=arguments-differ
if endness is None:
endness = self.endness
if endness is None:
endness = "Iend_BE"
char_num = self._calc_char_num(data, char_size)
# chunk_size is the number of bytes to cache in memory for comparison
if chunk_size is None:
chunk_size = min(max_search, max(0x80, char_num))
match_indices = []
for i, (_, element) in enumerate(
self._find_iter_items(
addr, char_num, char_size, chunk_size, max_search, endness, condition, max_symbolic_bytes, **kwargs
)
):
comparison, concrete_comparison = self._find_compare(element, data, **kwargs)
if comparison:
match_indices.append(i)
if concrete_comparison is True:
break
r_union = claripy.ESI(self.state.arch.bits)
for index in match_indices:
r_union = r_union.union(addr + index)
return r_union, [], match_indices
def _find_compare(self, element, target, **kwargs):
elem_si = element._model_vsa # pylint:disable=protected-access
target_si = target._model_vsa # pylint:disable=protected-access
comparison, concrete_comparison = False, False
# we only support strided intervals
if isinstance(elem_si, claripy.vsa.StridedInterval):
comparison = not elem_si.intersection(target_si).is_empty
concrete_comparison = elem_si.identical(target_si)
return comparison, concrete_comparison
def _find_are_bytes_symbolic(self, b):
# we only support strided intervals
return not isinstance(b._model_vsa, claripy.vsa.StridedInterval) # pylint:disable=protected-access