<commit_before>#!/usr/bin/env python

import logging
l = logging.getLogger("simuvex.plugins.memory")

import claripy
from ..plugins.plugin import SimStatePlugin

class AddressWrapper(object):
    """
    AddressWrapper is used in SimAbstractMemory, which provides extra meta information for an address (or a ValueSet
    object) that is normalized from an integer/BVV/StridedInterval.
    """

    def __init__(self, region, address, is_on_stack, function_address):
        """
        Constructor for the class AddressWrapper.

        :param region: Name of the memory regions it belongs to
        :param address: An address (not a ValueSet object)
        :param is_on_stack: Whether this address is on a stack region or not
        :param function_address: Related function address (if any)
        """

        self.region = region
        self.address = address
        self.is_on_stack = is_on_stack
        self.function_address = function_address

    def __hash__(self):
        return hash((self.region, self.address))

    def __eq__(self, other):
        return self.region == other.region and self.address == other.address

    def __repr__(self):
        return "<%s> %s" % (self.region, hex(self.address))

class MemoryStoreRequest(object):
    '''
    A MemoryStoreRequest is used internally by SimMemory to track memory request data.
    '''

    def __init__(self, addr, data=None, size=None, condition=None, endness=None):
        self.addr = addr
        self.data = data
        self.size = size
        self.condition = condition
        self.endness = endness

        # was this store done?
        self.completed = False

        # stuff that's determined during handling
        self.actual_addresses = None
        self.constraints = [ ]

        self.fallback_values = None
        self.symbolic_sized_values = None
        self.conditional_values = None
        self.simplified_values = None
        self.stored_values = None

class SimMemory(SimStatePlugin):
    def __init__(self, endness=None, abstract_backer=None):
        SimStatePlugin.__init__(self)
        self.id = None
        self.endness = "Iend_BE" if endness is None else endness

        # Whether this memory is internally used inside SimAbstractMemory
        self._abstract_backer = abstract_backer

    def _resolve_location_name(self, name):
        if self.id == 'reg':
            return self.state.arch.registers[name]
        elif name[0] == '*':
            return self.state.registers.load(name[1:]), None
        else:
            raise SimMemoryError("Trying to address memory with a register name.")

    def store(self, addr, data, size=None, condition=None, add_constraints=None, endness=None, action=None):
        '''
        Stores content into memory.

        @param addr: a claripy expression representing the address to store at
        @param data: the data to store (claripy expression or something convertable to a
                    claripy expression)
        @param size: a claripy expression representing the size of the data to store
        @param condition: (optional) a claripy expression representing a condition
                          if the store is conditional
        @param add_constraints: add constraints resulting from the merge (default: True)
        @param endness: The endianness for the data
        @param action: a SimActionData to fill out with the final written value and constraints
        '''
        addr_e = _raw_ast(addr)
        data_e = _raw_ast(data)
        size_e = _raw_ast(size)
        condition_e = _raw_ast(condition)
        add_constraints = True if add_constraints is None else add_constraints

        if isinstance(addr, str):
            named_addr, named_size = self._resolve_location_name(addr)
            addr = named_addr
            addr_e = addr
            if size is None:
                size = named_size
                size_e = size

        # store everything as a BV
        if type(data_e) is str:
            # Convert the string into a BitVecVal, *regardless of endness*
            bits = len(data_e) * 8
            data_e = self.state.BVV(data_e, bits)
        elif type(data_e) in (int, long):
            data_e = self.state.se.BVV(data_e, size_e*8 if size_e is not None else self.state.arch.bits)
        else:
            data_e = data_e.to_bv()

        if self.id == 'reg': self.state._inspect('reg_write', BP_BEFORE, reg_write_offset=addr_e, reg_write_length=size_e, reg_write_expr=data_e)
        if self.id == 'mem': self.state._inspect('mem_write', BP_BEFORE, mem_write_address=addr_e, mem_write_length=size_e, mem_write_expr=data_e)

        request = MemoryStoreRequest(addr_e, data=data_e, size=size_e, condition=condition_e, endness=endness)
        self._store(request)

        if self.id == 'reg': self.state._inspect('reg_write', BP_AFTER)
        if self.id == 'mem': self.state._inspect('mem_write', BP_AFTER)

        if add_constraints and len(request.constraints) > 0:
            self.state.add_constraints(*request.constraints)

        if request.completed and o.AUTO_REFS in self.state.options and action is None:
            ref_size = size if size is not None else (data_e.size() / 8)
            action = SimActionData(self.state, self.id, 'write', addr=addr, data=data, size=ref_size, condition=condition)
            self.state.log.add_action(action)

        if request.completed and action is not None:<commit_msg>Make sure we convert concrete values to ASTs on memory stores.<commit_after>#!/usr/bin/env python

import logging
l = logging.getLogger("simuvex.plugins.memory")

import claripy
from ..plugins.plugin import SimStatePlugin

class AddressWrapper(object):
    """
    AddressWrapper is used in SimAbstractMemory, which provides extra meta information for an address (or a ValueSet
    object) that is normalized from an integer/BVV/StridedInterval.
    """

    def __init__(self, region, address, is_on_stack, function_address):
        """
        Constructor for the class AddressWrapper.

        :param region: Name of the memory regions it belongs to
        :param address: An address (not a ValueSet object)
        :param is_on_stack: Whether this address is on a stack region or not
        :param function_address: Related function address (if any)
        """

        self.region = region
        self.address = address
        self.is_on_stack = is_on_stack
        self.function_address = function_address

    def __hash__(self):
        return hash((self.region, self.address))

    def __eq__(self, other):
        return self.region == other.region and self.address == other.address

    def __repr__(self):
        return "<%s> %s" % (self.region, hex(self.address))

class MemoryStoreRequest(object):
    '''
    A MemoryStoreRequest is used internally by SimMemory to track memory request data.
    '''

    def __init__(self, addr, data=None, size=None, condition=None, endness=None):
        self.addr = addr
        self.data = data
        self.size = size
        self.condition = condition
        self.endness = endness

        # was this store done?
        self.completed = False

        # stuff that's determined during handling
        self.actual_addresses = None
        self.constraints = [ ]

        self.fallback_values = None
        self.symbolic_sized_values = None
        self.conditional_values = None
        self.simplified_values = None
        self.stored_values = None

class SimMemory(SimStatePlugin):
    def __init__(self, endness=None, abstract_backer=None):
        SimStatePlugin.__init__(self)
        self.id = None
        self.endness = "Iend_BE" if endness is None else endness

        # Whether this memory is internally used inside SimAbstractMemory
        self._abstract_backer = abstract_backer

    def _resolve_location_name(self, name):
        if self.id == 'reg':
            return self.state.arch.registers[name]
        elif name[0] == '*':
            return self.state.registers.load(name[1:]), None
        else:
            raise SimMemoryError("Trying to address memory with a register name.")

    def _convert_to_ast(self, data_e, size_e=None):
        """
        Make an AST out of concrete @data_e
        """
        if type(data_e) is str:
            # Convert the string into a BitVecVal, *regardless of endness*
            bits = len(data_e) * 8
            data_e = self.state.BVV(data_e, bits)
        elif type(data_e) in (int, long):
            data_e = self.state.se.BVV(data_e, size_e*8 if size_e is not None
                                       else self.state.arch.bits)
        else:
            data_e = data_e.to_bv()

        return data_e

    def store(self, addr, data, size=None, condition=None, add_constraints=None, endness=None, action=None):
        '''
        Stores content into memory.

        @param addr: a claripy expression representing the address to store at
        @param data: the data to store (claripy expression or something convertable to a
                    claripy expression)
        @param size: a claripy expression representing the size of the data to store
        @param condition: (optional) a claripy expression representing a condition
                          if the store is conditional
        @param add_constraints: add constraints resulting from the merge (default: True)
        @param endness: The endianness for the data
        @param action: a SimActionData to fill out with the final written value and constraints
        '''
        addr_e = _raw_ast(addr)
        data_e = _raw_ast(data)
        size_e = _raw_ast(size)
        condition_e = _raw_ast(condition)
        add_constraints = True if add_constraints is None else add_constraints

        if isinstance(addr, str):
            named_addr, named_size = self._resolve_location_name(addr)
            addr = named_addr
            addr_e = addr
            if size is None:
                size = named_size
                size_e = size

        # store everything as a BV
        data_e = self._convert_to_ast(data_e)

        if type(size_e) in (int, long):
            size_e = self.state.se.BVV(size_e, self.state.arch.bits)

        if self.id == 'reg': self.state._inspect('reg_write', BP_BEFORE, reg_write_offset=addr_e, reg_write_length=size_e, reg_write_expr=data_e)
        if self.id == 'mem': self.state._inspect('mem_write', BP_BEFORE, mem_write_address=addr_e, mem_write_length=size_e, mem_write_expr=data_e)

        request = MemoryStoreRequest(addr_e, data=data_e, size=size_e, condition=condition_e, endness=endness)
        self._store(request)

        if self.id == 'reg': self.state._inspect('reg_write', BP_AFTER)
        if self.id == 'mem': self.state._inspect('mem_write', BP_AFTER)

        if add_constraints and len(request.constraints) > 0:
            self.state.add_constraints(*request.constraints)

        if request.completed and o.AUTO_REFS in self.state.options and action is None:
            ref_size = size if size is not None else (data_e.size() / 8)
            action = SimActionData(self.state, self.id, 'write', addr=addr, data=data, size=ref_size, condition=condition)
            self.state.log.add_action(action)

        if request.completed and action is not None:
{'fraction_non_alphanumeric': 0.08388012058875687, 'fraction_numerical': 0.001064018442986345, 'mean_word_length': 2.560290404040404, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7627517', 'n_tokens_mistral': 3276, 'n_tokens_neox': 3176, 'n_words': 966}