Top

miasm2.ir.symbexec_top module

from miasm2.ir.symbexec import SymbolicExecutionEngine, StateEngine
from miasm2.expression.simplifications import expr_simp
from miasm2.expression.expression import ExprId, ExprInt, ExprSlice,\
    ExprMem, ExprCond, ExprCompose, ExprOp


TOPSTR = "TOP"

def exprid_top(expr):
    """Return a TOP expression (ExprId("TOP") of size @expr.size
    @expr: expression to replace with TOP
    """
    return ExprId(TOPSTR, expr.size)


class SymbolicStateTop(StateEngine):

    def __init__(self, dct, regstop):
        self._symbols = frozenset(dct.items())
        self._regstop = frozenset(regstop)

    def __hash__(self):
        return hash((self.__class__, self._symbols, self._regstop))

    def __str__(self):
        out = []
        for dst, src in sorted(self._symbols):
            out.append("%s = %s" % (dst, src))
        for dst in self._regstop:
            out.append('TOP %s' %dst)
        return "\n".join(out)

    def __eq__(self, other):
        if self is other:
            return True
        if self.__class__ != other.__class__:
            return False
        return (self.symbols == other.symbols and
                self.regstop == other.regstop)

    def __ne__(self, other):
        return not self.__eq__(other)

    def __iter__(self):
        for dst, src in self._symbols:
            yield dst, src

    def merge(self, other):
        """Merge two symbolic states
        Only equal expressions are kept in both states
        @other: second symbolic state
        """
        symb_a = self.symbols
        symb_b = other.symbols
        intersection = set(symb_a.keys()).intersection(symb_b.keys())
        diff = set(symb_a.keys()).union(symb_b.keys()).difference(intersection)
        symbols = {}
        regstop = set()
        for dst in diff:
            if dst.is_id():
                regstop.add(dst)
        for dst in intersection:
            if symb_a[dst] == symb_b[dst]:
                symbols[dst] = symb_a[dst]
            else:
                regstop.add(dst)
        return self.__class__(symbols, regstop)

    @property
    def symbols(self):
        """Return the dictionnary of known symbols"""
        return dict(self._symbols)

    @property
    def regstop(self):
        """Return the set of expression with TOP values"""
        return self._regstop

class SymbExecTopNoMem(SymbolicExecutionEngine):
    """
    Symbolic execution, include TOP value.
    ExprMem are not propagated.
    Any computation involving a TOP will generate TOP.
    """

    StateEngine = SymbolicStateTop

    def __init__(self, ir_arch, state, regstop,
                 func_read=None,
                 func_write=None,
                 sb_expr_simp=expr_simp):
        known_symbols = dict(state)
        super(SymbExecTopNoMem, self).__init__(ir_arch, known_symbols,
                                               func_read,
                                               func_write,
                                               sb_expr_simp)
        self.regstop = set(regstop)

    def get_state(self):
        """Return the current state of the SymbolicEngine"""
        return self.StateEngine(self.symbols, self.regstop)

    def eval_expr(self, expr, eval_cache=None):
        if expr in self.regstop:
            return exprid_top(expr)
        if eval_cache is None:
            eval_cache = {}
        ret = self.apply_expr_on_state_visit_cache(expr, self.symbols, eval_cache)
        return ret

    def manage_mem(self, expr, state, cache, level):
        ptr = self.apply_expr_on_state_visit_cache(expr.arg, state, cache, level+1)
        ret = ExprMem(ptr, expr.size)
        ret = self.get_mem_state(ret)
        if ret.is_mem() and not ret.arg.is_int() and ret.arg == ptr:
            ret = exprid_top(expr)
        assert expr.size == ret.size
        return ret


    def eval_exprid(self, expr, **kwargs):
        """[DEV]: Evaluate an ExprId using the current state"""
        if expr in self.regstop:
            ret = exprid_top(expr)
        else:
            ret = self.symbols.read(expr)
        return ret

    def eval_exprloc(self, expr, **kwargs):
        offset = self.ir_arch.loc_db.get_location_offset(expr.loc_key)
        if offset is not None:
            ret = ExprInt(offset, expr.size)
        else:
            ret = expr
        return ret

    def eval_exprcond(self, expr, **kwargs):
        """[DEV]: Evaluate an ExprCond using the current state"""
        cond = self.eval_expr_visitor(expr.cond, **kwargs)
        src1 = self.eval_expr_visitor(expr.src1, **kwargs)
        src2 = self.eval_expr_visitor(expr.src2, **kwargs)
        if cond.is_id(TOPSTR) or src1.is_id(TOPSTR) or src2.is_id(TOPSTR):
            ret = exprid_top(expr)
        else:
            ret = ExprCond(cond, src1, src2)
        return ret

    def eval_exprslice(self, expr, **kwargs):
        """[DEV]: Evaluate an ExprSlice using the current state"""
        arg = self.eval_expr_visitor(expr.arg, **kwargs)
        if arg.is_id(TOPSTR):
            ret = exprid_top(expr)
        else:
            ret = ExprSlice(arg, expr.start, expr.stop)
        return ret

    def eval_exprop(self, expr, **kwargs):
        """[DEV]: Evaluate an ExprOp using the current state"""
        args = []
        for oarg in expr.args:
            arg = self.eval_expr_visitor(oarg, **kwargs)
            if arg.is_id(TOPSTR):
                return exprid_top(expr)
            args.append(arg)
        ret = ExprOp(expr.op, *args)
        return ret

    def eval_exprcompose(self, expr, **kwargs):
        """[DEV]: Evaluate an ExprCompose using the current state"""
        args = []
        for arg in expr.args:
            arg = self.eval_expr_visitor(arg, **kwargs)
            if arg.is_id(TOPSTR):
                return exprid_top(expr)
            args.append(arg)
        ret = ExprCompose(*args)
        return ret

    def apply_change(self, dst, src):
        eval_cache = {}
        if dst.is_mem():
            # If Write to TOP, forget all memory information
            ret = self.eval_expr(dst.arg, eval_cache)
            if ret.is_id(TOPSTR):
                to_del = set()
                for dst_tmp in self.symbols:
                    if dst_tmp.is_mem():
                        to_del.add(dst_tmp)
                for dst_to_del in to_del:
                    del self.symbols[dst_to_del]
            return
        src_o = self.expr_simp(src)

        # Force update. Ex:
        # EBX += 1 (state: EBX = EBX+1)
        # EBX -= 1 (state: EBX = EBX, must be updated)
        if dst in self.regstop:
            self.regstop.discard(dst)
        self.symbols[dst] = src_o

        if dst == src_o:
            # Avoid useless X = X information
            del self.symbols[dst]

        if src_o.is_id(TOPSTR):
            if dst in self.symbols:
                del self.symbols[dst]
            self.regstop.add(dst)

class SymbExecTop(SymbExecTopNoMem):
    """
    Symbolic execution, include TOP value.
    ExprMem are propagated.
    Any computation involving a TOP will generate TOP.
    WARNING: avoid memory aliases here!
    """

    def manage_mem(self, expr, state, cache, level):
        ptr = self.apply_expr_on_state_visit_cache(expr.arg, state, cache, level+1)
        ret = ExprMem(ptr, expr.size)
        ret = self.get_mem_state(ret)
        assert expr.size == ret.size
        return ret

Module variables

var TOPSTR

Functions

def exprid_top(

expr)

Return a TOP expression (ExprId("TOP") of size @expr.size @expr: expression to replace with TOP

def exprid_top(expr):
    """Return a TOP expression (ExprId("TOP") of size @expr.size
    @expr: expression to replace with TOP
    """
    return ExprId(TOPSTR, expr.size)

Classes

class SymbExecTop

Symbolic execution, include TOP value. ExprMem are propagated. Any computation involving a TOP will generate TOP. WARNING: avoid memory aliases here!

class SymbExecTop(SymbExecTopNoMem):
    """
    Symbolic execution, include TOP value.
    ExprMem are propagated.
    Any computation involving a TOP will generate TOP.
    WARNING: avoid memory aliases here!
    """

    def manage_mem(self, expr, state, cache, level):
        ptr = self.apply_expr_on_state_visit_cache(expr.arg, state, cache, level+1)
        ret = ExprMem(ptr, expr.size)
        ret = self.get_mem_state(ret)
        assert expr.size == ret.size
        return ret

Ancestors (in MRO)

Class variables

var StateEngine

Inheritance: SymbExecTopNoMem.StateEngine

Instance variables

var regstop

Inheritance: SymbExecTopNoMem.regstop

var state

Inheritance: SymbExecTopNoMem.state

Return the current state of the SymbolicEngine

Methods

def __init__(

self, ir_arch, state, regstop, func_read=None, func_write=None, sb_expr_simp=<miasm2.expression.simplifications.ExpressionSimplifier object at 0x7f19b240b1d0>)

Inheritance: SymbExecTopNoMem.__init__

def __init__(self, ir_arch, state, regstop,
             func_read=None,
             func_write=None,
             sb_expr_simp=expr_simp):
    known_symbols = dict(state)
    super(SymbExecTopNoMem, self).__init__(ir_arch, known_symbols,
                                           func_read,
                                           func_write,
                                           sb_expr_simp)
    self.regstop = set(regstop)

def apply_change(

self, dst, src)

Inheritance: SymbExecTopNoMem.apply_change

def apply_change(self, dst, src):
    eval_cache = {}
    if dst.is_mem():
        # If Write to TOP, forget all memory information
        ret = self.eval_expr(dst.arg, eval_cache)
        if ret.is_id(TOPSTR):
            to_del = set()
            for dst_tmp in self.symbols:
                if dst_tmp.is_mem():
                    to_del.add(dst_tmp)
            for dst_to_del in to_del:
                del self.symbols[dst_to_del]
        return
    src_o = self.expr_simp(src)
    # Force update. Ex:
    # EBX += 1 (state: EBX = EBX+1)
    # EBX -= 1 (state: EBX = EBX, must be updated)
    if dst in self.regstop:
        self.regstop.discard(dst)
    self.symbols[dst] = src_o
    if dst == src_o:
        # Avoid useless X = X information
        del self.symbols[dst]
    if src_o.is_id(TOPSTR):
        if dst in self.symbols:
            del self.symbols[dst]
        self.regstop.add(dst)

def apply_expr(

self, expr)

Inheritance: SymbExecTopNoMem.apply_expr

Deprecated version of eval_updt_expr

def apply_expr(self, expr):
    """Deprecated version of eval_updt_expr"""
    warnings.warn('DEPRECATION WARNING: use "eval_updt_expr" instead of apply_expr')
    return self.eval_updt_expr(expr)

def apply_expr_on_state(

self, expr, cache)

Inheritance: SymbExecTopNoMem.apply_expr_on_state

Deprecated version of eval_expr

def apply_expr_on_state(self, expr, cache):
    """Deprecated version of eval_expr"""
    warnings.warn('DEPRECATION WARNING: use "eval_expr" instead of apply_expr_on_state')
    if cache is None:
        cache = {}
    ret = self.eval_expr(expr, eval_cache=cache)
    return ret

def as_assignblock(

self)

Inheritance: SymbExecTopNoMem.as_assignblock

Return the current state as an AssignBlock

def as_assignblock(self):
    """Return the current state as an AssignBlock"""
    warnings.warn('DEPRECATION WARNING: use "modified(ids=True, mems=True)" instead of as_assignblock')
    out = []
    for dst, src in self.modified(ids=True, mems=True):
        out.append((dst, src))
    return AssignBlock(dict(out))

def del_mem_above_stack(

self, stack_ptr)

Inheritance: SymbExecTopNoMem.del_mem_above_stack

Remove all stored memory values with following properties: pointer based on initial stack value pointer below current stack pointer

def del_mem_above_stack(self, stack_ptr):
    """
    Remove all stored memory values with following properties:
    * pointer based on initial stack value
    * pointer below current stack pointer
    """
    stack_ptr = self.eval_expr(stack_ptr)
    base, stk_offset = get_expr_base_offset(stack_ptr)
    memarray = self.symbols.symbols_mem.base_to_memarray.get(base, None)
    if memarray:
        to_del = set()
        for offset in memarray:
            if ((offset - stk_offset) & int(stack_ptr.mask)) >> (stack_ptr.size - 1) != 0:
                to_del.add(offset)
        for offset in to_del:
            del memarray[offset]

def dump(

self, ids=True, mems=True)

Inheritance: SymbExecTopNoMem.dump

Display modififed variables @ids: display modified ids @mems: display modified memory

def dump(self, ids=True, mems=True):
    """
    Display modififed variables
    @ids: display modified ids
    @mems: display modified memory
    """
    for variable, value in self.modified(None, ids, mems):
        print "%-18s" % variable, "=", "%s" % value

def dump_id(

self)

Inheritance: SymbExecTopNoMem.dump_id

Deprecated version of dump(mems=False)

def dump_id(self):
    """Deprecated version of dump(mems=False)"""
    warnings.warn('DEPRECATION WARNING: use "dump(self, mems=False)" instead of dump_id')
    self.dump(mems=False)

def dump_mem(

self)

Inheritance: SymbExecTopNoMem.dump_mem

Deprecated version of dump(ids=False)

def dump_mem(self):
    """Deprecated version of dump(ids=False)"""
    warnings.warn('DEPRECATION WARNING: use "dump(self, ids=False)" instead of dump_mem')
    self.dump(ids=False)

def emul_ir_bloc(

self, _, addr, step=False)

Inheritance: SymbExecTopNoMem.emul_ir_bloc

Deprecated version of run_block_at

def emul_ir_bloc(self, _, addr, step=False):
    """Deprecated version of run_block_at"""
    warnings.warn('DEPRECATION WARNING: use "run_block_at(self, addr, step=False)" instead of emul_ir_bloc')
    return self.run_block_at(addr, step)

def emul_ir_block(

self, addr, step=False)

Inheritance: SymbExecTopNoMem.emul_ir_block

Deprecated version of run_block_at

def emul_ir_block(self, addr, step=False):
    """Deprecated version of run_block_at"""
    warnings.warn('DEPRECATION WARNING: use "run_block_at(self, addr, step=False)" instead of emul_ir_block')
    return self.run_block_at(addr, step)

def emul_ir_blocks(

self, addr, lbl_stop=None, step=False)

Inheritance: SymbExecTopNoMem.emul_ir_blocks

Deprecated version of run_at

def emul_ir_blocks(self, addr, lbl_stop=None, step=False):
    """Deprecated version of run_at"""
    warnings.warn('DEPRECATION WARNING: use "run_at(self, addr, lbl_stop=None, step=False):" instead of emul_ir_blocks')
    return self.run_at(addr, lbl_stop, step)

def emul_ir_blocs(

self, _, addr, lbl_stop=None, step=False)

Inheritance: SymbExecTopNoMem.emul_ir_blocs

Deprecated version of run_at

def emul_ir_blocs(self, _, addr, lbl_stop=None, step=False):
    """Deprecated version of run_at"""
    warnings.warn('DEPRECATION WARNING: use "run_at(self, addr, lbl_stop=None, step=False):" instead of emul_ir_blocs')
    return self.run_at(addr, lbl_stop, step)

def emulbloc(

self, irb, step=False)

Inheritance: SymbExecTopNoMem.emulbloc

Deprecated version of eval_updt_irblock(self, irb, step=False)

def emulbloc(self, irb, step=False):
    """Deprecated version of eval_updt_irblock(self, irb, step=False)"""
    warnings.warn('DEPRECATION WARNING: use "eval_updt_irblock(self, irb, step=False)" instead of emulbloc')
    return self.eval_updt_irblock(irb, step)

def eval_assignblk(

self, assignblk)

Inheritance: SymbExecTopNoMem.eval_assignblk

Evaluate AssignBlock using the current state

Returns a dictionary containing modified keys associated to their values

@assignblk: AssignBlock instance

def eval_assignblk(self, assignblk):
    """
    Evaluate AssignBlock using the current state
    Returns a dictionary containing modified keys associated to their values
    @assignblk: AssignBlock instance
    """
    pool_out = {}
    eval_cache = {}
    for dst, src in assignblk.iteritems():
        src = self.eval_expr(src, eval_cache)
        if dst.is_mem():
            ptr = self.eval_expr(dst.arg, eval_cache)
            # Test if mem lookup is known
            tmp = ExprMem(ptr, dst.size)
            pool_out[tmp] = src
        elif dst.is_id():
            pool_out[dst] = src
        else:
            raise ValueError("Unknown destination type", str(dst))
    return pool_out

def eval_expr(

self, expr, eval_cache=None)

Inheritance: SymbExecTopNoMem.eval_expr

def eval_expr(self, expr, eval_cache=None):
    if expr in self.regstop:
        return exprid_top(expr)
    if eval_cache is None:
        eval_cache = {}
    ret = self.apply_expr_on_state_visit_cache(expr, self.symbols, eval_cache)
    return ret

def eval_expr_visitor(

self, expr, cache=None)

Inheritance: SymbExecTopNoMem.eval_expr_visitor

[DEV]: Override to change the behavior of an Expr evaluation. This function recursively applies 'eval_expr*' to @expr. This function uses @cache to speedup re-evaluation of expression.

def eval_expr_visitor(self, expr, cache=None):
    """
    [DEV]: Override to change the behavior of an Expr evaluation.
    This function recursively applies 'eval_expr*' to @expr.
    This function uses @cache to speedup re-evaluation of expression.
    """
    if cache is None:
        cache = {}
    ret = cache.get(expr, None)
    if ret is not None:
        return ret
    new_expr = self.expr_simp(expr)
    ret = cache.get(new_expr, None)
    if ret is not None:
        return ret
    func = self.expr_to_visitor.get(new_expr.__class__, None)
    if func is None:
        raise TypeError("Unknown expr type")
    ret = func(new_expr, cache=cache)
    ret = self.expr_simp(ret)
    assert ret is not None
    cache[expr] = ret
    cache[new_expr] = ret
    return ret

def eval_exprcompose(

self, expr, **kwargs)

Inheritance: SymbExecTopNoMem.eval_exprcompose

[DEV]: Evaluate an ExprCompose using the current state

def eval_exprcompose(self, expr, **kwargs):
    """[DEV]: Evaluate an ExprCompose using the current state"""
    args = []
    for arg in expr.args:
        arg = self.eval_expr_visitor(arg, **kwargs)
        if arg.is_id(TOPSTR):
            return exprid_top(expr)
        args.append(arg)
    ret = ExprCompose(*args)
    return ret

def eval_exprcond(

self, expr, **kwargs)

Inheritance: SymbExecTopNoMem.eval_exprcond

[DEV]: Evaluate an ExprCond using the current state

def eval_exprcond(self, expr, **kwargs):
    """[DEV]: Evaluate an ExprCond using the current state"""
    cond = self.eval_expr_visitor(expr.cond, **kwargs)
    src1 = self.eval_expr_visitor(expr.src1, **kwargs)
    src2 = self.eval_expr_visitor(expr.src2, **kwargs)
    if cond.is_id(TOPSTR) or src1.is_id(TOPSTR) or src2.is_id(TOPSTR):
        ret = exprid_top(expr)
    else:
        ret = ExprCond(cond, src1, src2)
    return ret

def eval_exprid(

self, expr, **kwargs)

Inheritance: SymbExecTopNoMem.eval_exprid

[DEV]: Evaluate an ExprId using the current state

def eval_exprid(self, expr, **kwargs):
    """[DEV]: Evaluate an ExprId using the current state"""
    if expr in self.regstop:
        ret = exprid_top(expr)
    else:
        ret = self.symbols.read(expr)
    return ret

def eval_exprint(

self, expr, **kwargs)

Inheritance: SymbExecTopNoMem.eval_exprint

[DEV]: Evaluate an ExprInt using the current state

def eval_exprint(self, expr, **kwargs):
    """[DEV]: Evaluate an ExprInt using the current state"""
    return expr

def eval_exprloc(

self, expr, **kwargs)

Inheritance: SymbExecTopNoMem.eval_exprloc

def eval_exprloc(self, expr, **kwargs):
    offset = self.ir_arch.loc_db.get_location_offset(expr.loc_key)
    if offset is not None:
        ret = ExprInt(offset, expr.size)
    else:
        ret = expr
    return ret

def eval_exprmem(

self, expr, **kwargs)

Inheritance: SymbExecTopNoMem.eval_exprmem

[DEV]: Evaluate an ExprMem using the current state This function first evaluate the memory pointer value. Override 'mem_read' to modify the effective memory accesses

def eval_exprmem(self, expr, **kwargs):
    """[DEV]: Evaluate an ExprMem using the current state
    This function first evaluate the memory pointer value.
    Override 'mem_read' to modify the effective memory accesses
    """
    ptr = self.eval_expr_visitor(expr.arg, **kwargs)
    mem = ExprMem(ptr, expr.size)
    ret = self.mem_read(mem)
    return ret

def eval_exprop(

self, expr, **kwargs)

Inheritance: SymbExecTopNoMem.eval_exprop

[DEV]: Evaluate an ExprOp using the current state

def eval_exprop(self, expr, **kwargs):
    """[DEV]: Evaluate an ExprOp using the current state"""
    args = []
    for oarg in expr.args:
        arg = self.eval_expr_visitor(oarg, **kwargs)
        if arg.is_id(TOPSTR):
            return exprid_top(expr)
        args.append(arg)
    ret = ExprOp(expr.op, *args)
    return ret

def eval_exprslice(

self, expr, **kwargs)

Inheritance: SymbExecTopNoMem.eval_exprslice

[DEV]: Evaluate an ExprSlice using the current state

def eval_exprslice(self, expr, **kwargs):
    """[DEV]: Evaluate an ExprSlice using the current state"""
    arg = self.eval_expr_visitor(expr.arg, **kwargs)
    if arg.is_id(TOPSTR):
        ret = exprid_top(expr)
    else:
        ret = ExprSlice(arg, expr.start, expr.stop)
    return ret

def eval_ir(

self, assignblk)

Inheritance: SymbExecTopNoMem.eval_ir

Deprecated version of eval_updt_assignblk(self, assignblk)

def eval_ir(self, assignblk):
    """Deprecated version of eval_updt_assignblk(self, assignblk)"""
    warnings.warn('DEPRECATION WARNING: use "eval_assignblk(self, assignblk)" instead of eval_ir')
    return self.eval_updt_assignblk(assignblk)

def eval_ir_expr(

self, assignblk)

Inheritance: SymbExecTopNoMem.eval_ir_expr

Deprecated version of eval_ir_expr(self, assignblk)

def eval_ir_expr(self, assignblk):
    """Deprecated version of eval_ir_expr(self, assignblk)"""
    warnings.warn('DEPRECATION WARNING: use "eval_assignblk(self, assignblk)" instead of eval_ir_expr')
    return self.eval_assignblk(assignblk).iteritems()

def eval_updt_assignblk(

self, assignblk)

Inheritance: SymbExecTopNoMem.eval_updt_assignblk

Apply an AssignBlock on the current state @assignblk: AssignBlock instance

def eval_updt_assignblk(self, assignblk):
    """
    Apply an AssignBlock on the current state
    @assignblk: AssignBlock instance
    """
    mem_dst = []
    dst_src = self.eval_assignblk(assignblk)
    for dst, src in dst_src.iteritems():
        self.apply_change(dst, src)
        if dst.is_mem():
            mem_dst.append(dst)
    return mem_dst

def eval_updt_expr(

self, expr)

Inheritance: SymbExecTopNoMem.eval_updt_expr

Evaluate @expr and apply side effect if needed (ie. if expr is an assignment). Return the evaluated value

def eval_updt_expr(self, expr):
    """
    Evaluate @expr and apply side effect if needed (ie. if expr is an
    assignment). Return the evaluated value
    """
    # Update value if needed
    if expr.is_aff():
        ret = self.eval_expr(expr.src)
        self.eval_updt_assignblk(AssignBlock([expr]))
    else:
        ret = self.eval_expr(expr)
    return ret

def eval_updt_irblock(

self, irb, step=False)

Inheritance: SymbExecTopNoMem.eval_updt_irblock

Symbolic execution of the @irb on the current state @irb: irbloc instance @step: display intermediate steps

def eval_updt_irblock(self, irb, step=False):
    """
    Symbolic execution of the @irb on the current state
    @irb: irbloc instance
    @step: display intermediate steps
    """
    for assignblk in irb:
        if step:
            print 'Instr', assignblk.instr
            print 'Assignblk:'
            print assignblk
            print '_' * 80
        self.eval_updt_assignblk(assignblk)
        if step:
            self.dump(mems=False)
            self.dump(ids=False)
            print '_' * 80
    dst = self.eval_expr(self.ir_arch.IRDst)
    return dst

def get_state(

self)

Inheritance: SymbExecTopNoMem.get_state

Return the current state of the SymbolicEngine

def get_state(self):
    """Return the current state of the SymbolicEngine"""
    return self.StateEngine(self.symbols, self.regstop)

def manage_mem(

self, expr, state, cache, level)

Inheritance: SymbExecTopNoMem.manage_mem

def manage_mem(self, expr, state, cache, level):
    ptr = self.apply_expr_on_state_visit_cache(expr.arg, state, cache, level+1)
    ret = ExprMem(ptr, expr.size)
    ret = self.get_mem_state(ret)
    assert expr.size == ret.size
    return ret

def mem_read(

self, expr)

Inheritance: SymbExecTopNoMem.mem_read

[DEV]: Override to modify the effective memory reads

Read symbolic value at ExprMem @expr @expr: ExprMem

def mem_read(self, expr):
    """
    [DEV]: Override to modify the effective memory reads
    Read symbolic value at ExprMem @expr
    @expr: ExprMem
    """
    parts = self._resolve_mem_parts(expr)
    out = []
    for known, part in parts:
        if not known and part.is_mem() and self.func_read is not None:
            ret = self.func_read(part)
        else:
            ret = part
        out.append(ret)
    ret = self.expr_simp(ExprCompose(*out))
    assert ret.size == expr.size
    return ret

def mem_write(

self, dst, src)

Inheritance: SymbExecTopNoMem.mem_write

[DEV]: Override to modify the effective memory writes

Write symbolic value @src at ExprMem @dst @dst: destination ExprMem @src: source Expression

def mem_write(self, dst, src):
    """
    [DEV]: Override to modify the effective memory writes
    Write symbolic value @src at ExprMem @dst
    @dst: destination ExprMem
    @src: source Expression
    """
    if self.func_write is not None:
        self.func_write(self, dst, src)
    else:
        self.symbols.write(dst, src)

def modified(

self, init_state=None, ids=True, mems=True)

Inheritance: SymbExecTopNoMem.modified

Return the modified variables. @init_state: a base dictionary linking variables to their initial values to diff. Can be None. @ids: track ids only @mems: track mems only

def modified(self, init_state=None, ids=True, mems=True):
    """
    Return the modified variables.
    @init_state: a base dictionary linking variables to their initial values
    to diff. Can be None.
    @ids: track ids only
    @mems: track mems only
    """
    if init_state is None:
        init_state = {}
    if ids:
        for variable, value in self.symbols.symbols_id.iteritems():
            if variable in init_state and init_state[variable] == value:
                continue
            yield variable, value
    if mems:
        for mem, value in self.symbols.memory():
            if mem in init_state and init_state[mem] == value:
                continue
            yield mem, value

def modified_mems(

self, init_state=None)

Inheritance: SymbExecTopNoMem.modified_mems

Deprecated version of modified(ids=False)

def modified_mems(self, init_state=None):
    """Deprecated version of modified(ids=False)"""
    warnings.warn('DEPRECATION WARNING: use "modified(self, ids=False)" instead of modified_mems')
    for mem in self.modified(init_state=init_state, ids=False):
        yield mem

def modified_regs(

self, init_state=None)

Inheritance: SymbExecTopNoMem.modified_regs

Deprecated version of modified(mems=False)

def modified_regs(self, init_state=None):
    """Deprecated version of modified(mems=False)"""
    warnings.warn('DEPRECATION WARNING: use "modified(self, mems=False)" instead of modified_regs')
    for reg in self.modified(init_state=init_state, mems=False):
        yield reg

def run_at(

self, ircfg, addr, lbl_stop=None, step=False)

Inheritance: SymbExecTopNoMem.run_at

Symbolic execution starting at @addr @addr: address to execute (int or ExprInt or label) @lbl_stop: LocKey to stop execution on @step: display intermediate steps

def run_at(self, ircfg, addr, lbl_stop=None, step=False):
    """
    Symbolic execution starting at @addr
    @addr: address to execute (int or ExprInt or label)
    @lbl_stop: LocKey to stop execution on
    @step: display intermediate steps
    """
    while True:
        irblock = ircfg.get_block(addr)
        if irblock is None:
            break
        if irblock.loc_key == lbl_stop:
            break
        addr = self.eval_updt_irblock(irblock, step=step)
    return addr

def run_block_at(

self, ircfg, addr, step=False)

Inheritance: SymbExecTopNoMem.run_block_at

Symbolic execution of the block at @addr @addr: address to execute (int or ExprInt or label) @step: display intermediate steps

def run_block_at(self, ircfg, addr, step=False):
    """
    Symbolic execution of the block at @addr
    @addr: address to execute (int or ExprInt or label)
    @step: display intermediate steps
    """
    irblock = ircfg.get_block(addr)
    if irblock is not None:
        addr = self.eval_updt_irblock(irblock, step=step)
    return addr

def set_state(

self, state)

Inheritance: SymbExecTopNoMem.set_state

Restaure the @state of the engine @state: StateEngine instance

def set_state(self, state):
    """Restaure the @state of the engine
    @state: StateEngine instance
    """
    self.symbols = SymbolMngr(addrsize=self.ir_arch.addrsize, expr_simp=self.expr_simp)
    for dst, src in dict(state).iteritems():
        self.symbols[dst] = src

class SymbExecTopNoMem

Symbolic execution, include TOP value. ExprMem are not propagated. Any computation involving a TOP will generate TOP.

class SymbExecTopNoMem(SymbolicExecutionEngine):
    """
    Symbolic execution, include TOP value.
    ExprMem are not propagated.
    Any computation involving a TOP will generate TOP.
    """

    StateEngine = SymbolicStateTop

    def __init__(self, ir_arch, state, regstop,
                 func_read=None,
                 func_write=None,
                 sb_expr_simp=expr_simp):
        known_symbols = dict(state)
        super(SymbExecTopNoMem, self).__init__(ir_arch, known_symbols,
                                               func_read,
                                               func_write,
                                               sb_expr_simp)
        self.regstop = set(regstop)

    def get_state(self):
        """Return the current state of the SymbolicEngine"""
        return self.StateEngine(self.symbols, self.regstop)

    def eval_expr(self, expr, eval_cache=None):
        if expr in self.regstop:
            return exprid_top(expr)
        if eval_cache is None:
            eval_cache = {}
        ret = self.apply_expr_on_state_visit_cache(expr, self.symbols, eval_cache)
        return ret

    def manage_mem(self, expr, state, cache, level):
        ptr = self.apply_expr_on_state_visit_cache(expr.arg, state, cache, level+1)
        ret = ExprMem(ptr, expr.size)
        ret = self.get_mem_state(ret)
        if ret.is_mem() and not ret.arg.is_int() and ret.arg == ptr:
            ret = exprid_top(expr)
        assert expr.size == ret.size
        return ret


    def eval_exprid(self, expr, **kwargs):
        """[DEV]: Evaluate an ExprId using the current state"""
        if expr in self.regstop:
            ret = exprid_top(expr)
        else:
            ret = self.symbols.read(expr)
        return ret

    def eval_exprloc(self, expr, **kwargs):
        offset = self.ir_arch.loc_db.get_location_offset(expr.loc_key)
        if offset is not None:
            ret = ExprInt(offset, expr.size)
        else:
            ret = expr
        return ret

    def eval_exprcond(self, expr, **kwargs):
        """[DEV]: Evaluate an ExprCond using the current state"""
        cond = self.eval_expr_visitor(expr.cond, **kwargs)
        src1 = self.eval_expr_visitor(expr.src1, **kwargs)
        src2 = self.eval_expr_visitor(expr.src2, **kwargs)
        if cond.is_id(TOPSTR) or src1.is_id(TOPSTR) or src2.is_id(TOPSTR):
            ret = exprid_top(expr)
        else:
            ret = ExprCond(cond, src1, src2)
        return ret

    def eval_exprslice(self, expr, **kwargs):
        """[DEV]: Evaluate an ExprSlice using the current state"""
        arg = self.eval_expr_visitor(expr.arg, **kwargs)
        if arg.is_id(TOPSTR):
            ret = exprid_top(expr)
        else:
            ret = ExprSlice(arg, expr.start, expr.stop)
        return ret

    def eval_exprop(self, expr, **kwargs):
        """[DEV]: Evaluate an ExprOp using the current state"""
        args = []
        for oarg in expr.args:
            arg = self.eval_expr_visitor(oarg, **kwargs)
            if arg.is_id(TOPSTR):
                return exprid_top(expr)
            args.append(arg)
        ret = ExprOp(expr.op, *args)
        return ret

    def eval_exprcompose(self, expr, **kwargs):
        """[DEV]: Evaluate an ExprCompose using the current state"""
        args = []
        for arg in expr.args:
            arg = self.eval_expr_visitor(arg, **kwargs)
            if arg.is_id(TOPSTR):
                return exprid_top(expr)
            args.append(arg)
        ret = ExprCompose(*args)
        return ret

    def apply_change(self, dst, src):
        eval_cache = {}
        if dst.is_mem():
            # If Write to TOP, forget all memory information
            ret = self.eval_expr(dst.arg, eval_cache)
            if ret.is_id(TOPSTR):
                to_del = set()
                for dst_tmp in self.symbols:
                    if dst_tmp.is_mem():
                        to_del.add(dst_tmp)
                for dst_to_del in to_del:
                    del self.symbols[dst_to_del]
            return
        src_o = self.expr_simp(src)

        # Force update. Ex:
        # EBX += 1 (state: EBX = EBX+1)
        # EBX -= 1 (state: EBX = EBX, must be updated)
        if dst in self.regstop:
            self.regstop.discard(dst)
        self.symbols[dst] = src_o

        if dst == src_o:
            # Avoid useless X = X information
            del self.symbols[dst]

        if src_o.is_id(TOPSTR):
            if dst in self.symbols:
                del self.symbols[dst]
            self.regstop.add(dst)

Ancestors (in MRO)

  • SymbExecTopNoMem
  • miasm2.ir.symbexec.SymbolicExecutionEngine
  • __builtin__.object

Class variables

var StateEngine

Instance variables

var regstop

var state

Return the current state of the SymbolicEngine

Methods

def __init__(

self, ir_arch, state, regstop, func_read=None, func_write=None, sb_expr_simp=<miasm2.expression.simplifications.ExpressionSimplifier object at 0x7f19b240b1d0>)

def __init__(self, ir_arch, state, regstop,
             func_read=None,
             func_write=None,
             sb_expr_simp=expr_simp):
    known_symbols = dict(state)
    super(SymbExecTopNoMem, self).__init__(ir_arch, known_symbols,
                                           func_read,
                                           func_write,
                                           sb_expr_simp)
    self.regstop = set(regstop)

def apply_change(

self, dst, src)

def apply_change(self, dst, src):
    eval_cache = {}
    if dst.is_mem():
        # If Write to TOP, forget all memory information
        ret = self.eval_expr(dst.arg, eval_cache)
        if ret.is_id(TOPSTR):
            to_del = set()
            for dst_tmp in self.symbols:
                if dst_tmp.is_mem():
                    to_del.add(dst_tmp)
            for dst_to_del in to_del:
                del self.symbols[dst_to_del]
        return
    src_o = self.expr_simp(src)
    # Force update. Ex:
    # EBX += 1 (state: EBX = EBX+1)
    # EBX -= 1 (state: EBX = EBX, must be updated)
    if dst in self.regstop:
        self.regstop.discard(dst)
    self.symbols[dst] = src_o
    if dst == src_o:
        # Avoid useless X = X information
        del self.symbols[dst]
    if src_o.is_id(TOPSTR):
        if dst in self.symbols:
            del self.symbols[dst]
        self.regstop.add(dst)

def apply_expr(

self, expr)

Deprecated version of eval_updt_expr

def apply_expr(self, expr):
    """Deprecated version of eval_updt_expr"""
    warnings.warn('DEPRECATION WARNING: use "eval_updt_expr" instead of apply_expr')
    return self.eval_updt_expr(expr)

def apply_expr_on_state(

self, expr, cache)

Deprecated version of eval_expr

def apply_expr_on_state(self, expr, cache):
    """Deprecated version of eval_expr"""
    warnings.warn('DEPRECATION WARNING: use "eval_expr" instead of apply_expr_on_state')
    if cache is None:
        cache = {}
    ret = self.eval_expr(expr, eval_cache=cache)
    return ret

def as_assignblock(

self)

Return the current state as an AssignBlock

def as_assignblock(self):
    """Return the current state as an AssignBlock"""
    warnings.warn('DEPRECATION WARNING: use "modified(ids=True, mems=True)" instead of as_assignblock')
    out = []
    for dst, src in self.modified(ids=True, mems=True):
        out.append((dst, src))
    return AssignBlock(dict(out))

def del_mem_above_stack(

self, stack_ptr)

Remove all stored memory values with following properties: pointer based on initial stack value pointer below current stack pointer

def del_mem_above_stack(self, stack_ptr):
    """
    Remove all stored memory values with following properties:
    * pointer based on initial stack value
    * pointer below current stack pointer
    """
    stack_ptr = self.eval_expr(stack_ptr)
    base, stk_offset = get_expr_base_offset(stack_ptr)
    memarray = self.symbols.symbols_mem.base_to_memarray.get(base, None)
    if memarray:
        to_del = set()
        for offset in memarray:
            if ((offset - stk_offset) & int(stack_ptr.mask)) >> (stack_ptr.size - 1) != 0:
                to_del.add(offset)
        for offset in to_del:
            del memarray[offset]

def dump(

self, ids=True, mems=True)

Display modififed variables @ids: display modified ids @mems: display modified memory

def dump(self, ids=True, mems=True):
    """
    Display modififed variables
    @ids: display modified ids
    @mems: display modified memory
    """
    for variable, value in self.modified(None, ids, mems):
        print "%-18s" % variable, "=", "%s" % value

def dump_id(

self)

Deprecated version of dump(mems=False)

def dump_id(self):
    """Deprecated version of dump(mems=False)"""
    warnings.warn('DEPRECATION WARNING: use "dump(self, mems=False)" instead of dump_id')
    self.dump(mems=False)

def dump_mem(

self)

Deprecated version of dump(ids=False)

def dump_mem(self):
    """Deprecated version of dump(ids=False)"""
    warnings.warn('DEPRECATION WARNING: use "dump(self, ids=False)" instead of dump_mem')
    self.dump(ids=False)

def emul_ir_bloc(

self, _, addr, step=False)

Deprecated version of run_block_at

def emul_ir_bloc(self, _, addr, step=False):
    """Deprecated version of run_block_at"""
    warnings.warn('DEPRECATION WARNING: use "run_block_at(self, addr, step=False)" instead of emul_ir_bloc')
    return self.run_block_at(addr, step)

def emul_ir_block(

self, addr, step=False)

Deprecated version of run_block_at

def emul_ir_block(self, addr, step=False):
    """Deprecated version of run_block_at"""
    warnings.warn('DEPRECATION WARNING: use "run_block_at(self, addr, step=False)" instead of emul_ir_block')
    return self.run_block_at(addr, step)

def emul_ir_blocks(

self, addr, lbl_stop=None, step=False)

Deprecated version of run_at

def emul_ir_blocks(self, addr, lbl_stop=None, step=False):
    """Deprecated version of run_at"""
    warnings.warn('DEPRECATION WARNING: use "run_at(self, addr, lbl_stop=None, step=False):" instead of emul_ir_blocks')
    return self.run_at(addr, lbl_stop, step)

def emul_ir_blocs(

self, _, addr, lbl_stop=None, step=False)

Deprecated version of run_at

def emul_ir_blocs(self, _, addr, lbl_stop=None, step=False):
    """Deprecated version of run_at"""
    warnings.warn('DEPRECATION WARNING: use "run_at(self, addr, lbl_stop=None, step=False):" instead of emul_ir_blocs')
    return self.run_at(addr, lbl_stop, step)

def emulbloc(

self, irb, step=False)

Deprecated version of eval_updt_irblock(self, irb, step=False)

def emulbloc(self, irb, step=False):
    """Deprecated version of eval_updt_irblock(self, irb, step=False)"""
    warnings.warn('DEPRECATION WARNING: use "eval_updt_irblock(self, irb, step=False)" instead of emulbloc')
    return self.eval_updt_irblock(irb, step)

def eval_assignblk(

self, assignblk)

Evaluate AssignBlock using the current state

Returns a dictionary containing modified keys associated to their values

@assignblk: AssignBlock instance

def eval_assignblk(self, assignblk):
    """
    Evaluate AssignBlock using the current state
    Returns a dictionary containing modified keys associated to their values
    @assignblk: AssignBlock instance
    """
    pool_out = {}
    eval_cache = {}
    for dst, src in assignblk.iteritems():
        src = self.eval_expr(src, eval_cache)
        if dst.is_mem():
            ptr = self.eval_expr(dst.arg, eval_cache)
            # Test if mem lookup is known
            tmp = ExprMem(ptr, dst.size)
            pool_out[tmp] = src
        elif dst.is_id():
            pool_out[dst] = src
        else:
            raise ValueError("Unknown destination type", str(dst))
    return pool_out

def eval_expr(

self, expr, eval_cache=None)

def eval_expr(self, expr, eval_cache=None):
    if expr in self.regstop:
        return exprid_top(expr)
    if eval_cache is None:
        eval_cache = {}
    ret = self.apply_expr_on_state_visit_cache(expr, self.symbols, eval_cache)
    return ret

def eval_expr_visitor(

self, expr, cache=None)

[DEV]: Override to change the behavior of an Expr evaluation. This function recursively applies 'eval_expr*' to @expr. This function uses @cache to speedup re-evaluation of expression.

def eval_expr_visitor(self, expr, cache=None):
    """
    [DEV]: Override to change the behavior of an Expr evaluation.
    This function recursively applies 'eval_expr*' to @expr.
    This function uses @cache to speedup re-evaluation of expression.
    """
    if cache is None:
        cache = {}
    ret = cache.get(expr, None)
    if ret is not None:
        return ret
    new_expr = self.expr_simp(expr)
    ret = cache.get(new_expr, None)
    if ret is not None:
        return ret
    func = self.expr_to_visitor.get(new_expr.__class__, None)
    if func is None:
        raise TypeError("Unknown expr type")
    ret = func(new_expr, cache=cache)
    ret = self.expr_simp(ret)
    assert ret is not None
    cache[expr] = ret
    cache[new_expr] = ret
    return ret

def eval_exprcompose(

self, expr, **kwargs)

[DEV]: Evaluate an ExprCompose using the current state

def eval_exprcompose(self, expr, **kwargs):
    """[DEV]: Evaluate an ExprCompose using the current state"""
    args = []
    for arg in expr.args:
        arg = self.eval_expr_visitor(arg, **kwargs)
        if arg.is_id(TOPSTR):
            return exprid_top(expr)
        args.append(arg)
    ret = ExprCompose(*args)
    return ret

def eval_exprcond(

self, expr, **kwargs)

[DEV]: Evaluate an ExprCond using the current state

def eval_exprcond(self, expr, **kwargs):
    """[DEV]: Evaluate an ExprCond using the current state"""
    cond = self.eval_expr_visitor(expr.cond, **kwargs)
    src1 = self.eval_expr_visitor(expr.src1, **kwargs)
    src2 = self.eval_expr_visitor(expr.src2, **kwargs)
    if cond.is_id(TOPSTR) or src1.is_id(TOPSTR) or src2.is_id(TOPSTR):
        ret = exprid_top(expr)
    else:
        ret = ExprCond(cond, src1, src2)
    return ret

def eval_exprid(

self, expr, **kwargs)

[DEV]: Evaluate an ExprId using the current state

def eval_exprid(self, expr, **kwargs):
    """[DEV]: Evaluate an ExprId using the current state"""
    if expr in self.regstop:
        ret = exprid_top(expr)
    else:
        ret = self.symbols.read(expr)
    return ret

def eval_exprint(

self, expr, **kwargs)

[DEV]: Evaluate an ExprInt using the current state

def eval_exprint(self, expr, **kwargs):
    """[DEV]: Evaluate an ExprInt using the current state"""
    return expr

def eval_exprloc(

self, expr, **kwargs)

def eval_exprloc(self, expr, **kwargs):
    offset = self.ir_arch.loc_db.get_location_offset(expr.loc_key)
    if offset is not None:
        ret = ExprInt(offset, expr.size)
    else:
        ret = expr
    return ret

def eval_exprmem(

self, expr, **kwargs)

[DEV]: Evaluate an ExprMem using the current state This function first evaluate the memory pointer value. Override 'mem_read' to modify the effective memory accesses

def eval_exprmem(self, expr, **kwargs):
    """[DEV]: Evaluate an ExprMem using the current state
    This function first evaluate the memory pointer value.
    Override 'mem_read' to modify the effective memory accesses
    """
    ptr = self.eval_expr_visitor(expr.arg, **kwargs)
    mem = ExprMem(ptr, expr.size)
    ret = self.mem_read(mem)
    return ret

def eval_exprop(

self, expr, **kwargs)

[DEV]: Evaluate an ExprOp using the current state

def eval_exprop(self, expr, **kwargs):
    """[DEV]: Evaluate an ExprOp using the current state"""
    args = []
    for oarg in expr.args:
        arg = self.eval_expr_visitor(oarg, **kwargs)
        if arg.is_id(TOPSTR):
            return exprid_top(expr)
        args.append(arg)
    ret = ExprOp(expr.op, *args)
    return ret

def eval_exprslice(

self, expr, **kwargs)

[DEV]: Evaluate an ExprSlice using the current state

def eval_exprslice(self, expr, **kwargs):
    """[DEV]: Evaluate an ExprSlice using the current state"""
    arg = self.eval_expr_visitor(expr.arg, **kwargs)
    if arg.is_id(TOPSTR):
        ret = exprid_top(expr)
    else:
        ret = ExprSlice(arg, expr.start, expr.stop)
    return ret

def eval_ir(

self, assignblk)

Deprecated version of eval_updt_assignblk(self, assignblk)

def eval_ir(self, assignblk):
    """Deprecated version of eval_updt_assignblk(self, assignblk)"""
    warnings.warn('DEPRECATION WARNING: use "eval_assignblk(self, assignblk)" instead of eval_ir')
    return self.eval_updt_assignblk(assignblk)

def eval_ir_expr(

self, assignblk)

Deprecated version of eval_ir_expr(self, assignblk)

def eval_ir_expr(self, assignblk):
    """Deprecated version of eval_ir_expr(self, assignblk)"""
    warnings.warn('DEPRECATION WARNING: use "eval_assignblk(self, assignblk)" instead of eval_ir_expr')
    return self.eval_assignblk(assignblk).iteritems()

def eval_updt_assignblk(

self, assignblk)

Apply an AssignBlock on the current state @assignblk: AssignBlock instance

def eval_updt_assignblk(self, assignblk):
    """
    Apply an AssignBlock on the current state
    @assignblk: AssignBlock instance
    """
    mem_dst = []
    dst_src = self.eval_assignblk(assignblk)
    for dst, src in dst_src.iteritems():
        self.apply_change(dst, src)
        if dst.is_mem():
            mem_dst.append(dst)
    return mem_dst

def eval_updt_expr(

self, expr)

Evaluate @expr and apply side effect if needed (ie. if expr is an assignment). Return the evaluated value

def eval_updt_expr(self, expr):
    """
    Evaluate @expr and apply side effect if needed (ie. if expr is an
    assignment). Return the evaluated value
    """
    # Update value if needed
    if expr.is_aff():
        ret = self.eval_expr(expr.src)
        self.eval_updt_assignblk(AssignBlock([expr]))
    else:
        ret = self.eval_expr(expr)
    return ret

def eval_updt_irblock(

self, irb, step=False)

Symbolic execution of the @irb on the current state @irb: irbloc instance @step: display intermediate steps

def eval_updt_irblock(self, irb, step=False):
    """
    Symbolic execution of the @irb on the current state
    @irb: irbloc instance
    @step: display intermediate steps
    """
    for assignblk in irb:
        if step:
            print 'Instr', assignblk.instr
            print 'Assignblk:'
            print assignblk
            print '_' * 80
        self.eval_updt_assignblk(assignblk)
        if step:
            self.dump(mems=False)
            self.dump(ids=False)
            print '_' * 80
    dst = self.eval_expr(self.ir_arch.IRDst)
    return dst

def get_state(

self)

Return the current state of the SymbolicEngine

def get_state(self):
    """Return the current state of the SymbolicEngine"""
    return self.StateEngine(self.symbols, self.regstop)

def manage_mem(

self, expr, state, cache, level)

def manage_mem(self, expr, state, cache, level):
    ptr = self.apply_expr_on_state_visit_cache(expr.arg, state, cache, level+1)
    ret = ExprMem(ptr, expr.size)
    ret = self.get_mem_state(ret)
    if ret.is_mem() and not ret.arg.is_int() and ret.arg == ptr:
        ret = exprid_top(expr)
    assert expr.size == ret.size
    return ret

def mem_read(

self, expr)

[DEV]: Override to modify the effective memory reads

Read symbolic value at ExprMem @expr @expr: ExprMem

def mem_read(self, expr):
    """
    [DEV]: Override to modify the effective memory reads
    Read symbolic value at ExprMem @expr
    @expr: ExprMem
    """
    parts = self._resolve_mem_parts(expr)
    out = []
    for known, part in parts:
        if not known and part.is_mem() and self.func_read is not None:
            ret = self.func_read(part)
        else:
            ret = part
        out.append(ret)
    ret = self.expr_simp(ExprCompose(*out))
    assert ret.size == expr.size
    return ret

def mem_write(

self, dst, src)

[DEV]: Override to modify the effective memory writes

Write symbolic value @src at ExprMem @dst @dst: destination ExprMem @src: source Expression

def mem_write(self, dst, src):
    """
    [DEV]: Override to modify the effective memory writes
    Write symbolic value @src at ExprMem @dst
    @dst: destination ExprMem
    @src: source Expression
    """
    if self.func_write is not None:
        self.func_write(self, dst, src)
    else:
        self.symbols.write(dst, src)

def modified(

self, init_state=None, ids=True, mems=True)

Return the modified variables. @init_state: a base dictionary linking variables to their initial values to diff. Can be None. @ids: track ids only @mems: track mems only

def modified(self, init_state=None, ids=True, mems=True):
    """
    Return the modified variables.
    @init_state: a base dictionary linking variables to their initial values
    to diff. Can be None.
    @ids: track ids only
    @mems: track mems only
    """
    if init_state is None:
        init_state = {}
    if ids:
        for variable, value in self.symbols.symbols_id.iteritems():
            if variable in init_state and init_state[variable] == value:
                continue
            yield variable, value
    if mems:
        for mem, value in self.symbols.memory():
            if mem in init_state and init_state[mem] == value:
                continue
            yield mem, value

def modified_mems(

self, init_state=None)

Deprecated version of modified(ids=False)

def modified_mems(self, init_state=None):
    """Deprecated version of modified(ids=False)"""
    warnings.warn('DEPRECATION WARNING: use "modified(self, ids=False)" instead of modified_mems')
    for mem in self.modified(init_state=init_state, ids=False):
        yield mem

def modified_regs(

self, init_state=None)

Deprecated version of modified(mems=False)

def modified_regs(self, init_state=None):
    """Deprecated version of modified(mems=False)"""
    warnings.warn('DEPRECATION WARNING: use "modified(self, mems=False)" instead of modified_regs')
    for reg in self.modified(init_state=init_state, mems=False):
        yield reg

def run_at(

self, ircfg, addr, lbl_stop=None, step=False)

Symbolic execution starting at @addr @addr: address to execute (int or ExprInt or label) @lbl_stop: LocKey to stop execution on @step: display intermediate steps

def run_at(self, ircfg, addr, lbl_stop=None, step=False):
    """
    Symbolic execution starting at @addr
    @addr: address to execute (int or ExprInt or label)
    @lbl_stop: LocKey to stop execution on
    @step: display intermediate steps
    """
    while True:
        irblock = ircfg.get_block(addr)
        if irblock is None:
            break
        if irblock.loc_key == lbl_stop:
            break
        addr = self.eval_updt_irblock(irblock, step=step)
    return addr

def run_block_at(

self, ircfg, addr, step=False)

Symbolic execution of the block at @addr @addr: address to execute (int or ExprInt or label) @step: display intermediate steps

def run_block_at(self, ircfg, addr, step=False):
    """
    Symbolic execution of the block at @addr
    @addr: address to execute (int or ExprInt or label)
    @step: display intermediate steps
    """
    irblock = ircfg.get_block(addr)
    if irblock is not None:
        addr = self.eval_updt_irblock(irblock, step=step)
    return addr

def set_state(

self, state)

Restaure the @state of the engine @state: StateEngine instance

def set_state(self, state):
    """Restaure the @state of the engine
    @state: StateEngine instance
    """
    self.symbols = SymbolMngr(addrsize=self.ir_arch.addrsize, expr_simp=self.expr_simp)
    for dst, src in dict(state).iteritems():
        self.symbols[dst] = src

class SymbolicStateTop

class SymbolicStateTop(StateEngine):

    def __init__(self, dct, regstop):
        self._symbols = frozenset(dct.items())
        self._regstop = frozenset(regstop)

    def __hash__(self):
        return hash((self.__class__, self._symbols, self._regstop))

    def __str__(self):
        out = []
        for dst, src in sorted(self._symbols):
            out.append("%s = %s" % (dst, src))
        for dst in self._regstop:
            out.append('TOP %s' %dst)
        return "\n".join(out)

    def __eq__(self, other):
        if self is other:
            return True
        if self.__class__ != other.__class__:
            return False
        return (self.symbols == other.symbols and
                self.regstop == other.regstop)

    def __ne__(self, other):
        return not self.__eq__(other)

    def __iter__(self):
        for dst, src in self._symbols:
            yield dst, src

    def merge(self, other):
        """Merge two symbolic states
        Only equal expressions are kept in both states
        @other: second symbolic state
        """
        symb_a = self.symbols
        symb_b = other.symbols
        intersection = set(symb_a.keys()).intersection(symb_b.keys())
        diff = set(symb_a.keys()).union(symb_b.keys()).difference(intersection)
        symbols = {}
        regstop = set()
        for dst in diff:
            if dst.is_id():
                regstop.add(dst)
        for dst in intersection:
            if symb_a[dst] == symb_b[dst]:
                symbols[dst] = symb_a[dst]
            else:
                regstop.add(dst)
        return self.__class__(symbols, regstop)

    @property
    def symbols(self):
        """Return the dictionnary of known symbols"""
        return dict(self._symbols)

    @property
    def regstop(self):
        """Return the set of expression with TOP values"""
        return self._regstop

Ancestors (in MRO)

Instance variables

var regstop

Return the set of expression with TOP values

var symbols

Return the dictionnary of known symbols

Methods

def __init__(

self, dct, regstop)

def __init__(self, dct, regstop):
    self._symbols = frozenset(dct.items())
    self._regstop = frozenset(regstop)

def merge(

self, other)

Merge two symbolic states Only equal expressions are kept in both states @other: second symbolic state

def merge(self, other):
    """Merge two symbolic states
    Only equal expressions are kept in both states
    @other: second symbolic state
    """
    symb_a = self.symbols
    symb_b = other.symbols
    intersection = set(symb_a.keys()).intersection(symb_b.keys())
    diff = set(symb_a.keys()).union(symb_b.keys()).difference(intersection)
    symbols = {}
    regstop = set()
    for dst in diff:
        if dst.is_id():
            regstop.add(dst)
    for dst in intersection:
        if symb_a[dst] == symb_b[dst]:
            symbols[dst] = symb_a[dst]
        else:
            regstop.add(dst)
    return self.__class__(symbols, regstop)