Top

miasm2.jitter.emulatedsymbexec module

import miasm2.expression.expression as m2_expr
from miasm2.ir.symbexec import SymbolicExecutionEngine


class EmulatedSymbExec(SymbolicExecutionEngine):
    """Symbolic exec instance linked with a jitter"""

    x86_cpuid = {
        0: {
            0: 0xa,
            1: 0x756E6547,
            2: 0x6C65746E,
            3: 0x49656E69,
        },
        1: {
            0: 0x00020652,
            1: 0x00000800,
            2: 0x00000209,
            3: 0x078bf9ff
        },
    }

    def __init__(self, cpu, vm, *args, **kwargs):
        """Instanciate an EmulatedSymbExec, associated to CPU @cpu and bind
        memory accesses.
        @cpu: JitCpu instance
        """
        super(EmulatedSymbExec, self).__init__(*args, **kwargs)
        self.cpu = cpu
        self.vm = vm
        self.func_read = self._func_read
        self.func_write = self._func_write

    def reset_regs(self):
        """Set registers value to 0. Ignore register aliases"""
        for reg in self.ir_arch.arch.regs.all_regs_ids_no_alias:
            self.symbols.symbols_id[reg] = m2_expr.ExprInt(0, size=reg.size)

    # Memory management
    def _func_read(self, expr_mem):
        """Memory read wrapper for symbolic execution
        @expr_mem: ExprMem"""

        addr = expr_mem.arg
        if not addr.is_int():
            return expr_mem
        addr = int(addr)
        size = expr_mem.size / 8
        value = self.cpu.get_mem(addr, size)
        if self.vm.is_little_endian():
            value = value[::-1]
        self.vm.add_mem_read(addr, size)

        return m2_expr.ExprInt(int(value.encode("hex"), 16),
                               expr_mem.size)

    def _func_write(self, symb_exec, dest, data):
        """Memory read wrapper for symbolic execution
        @symb_exec: symbexec instance
        @dest: ExprMem instance
        @data: Expr instance"""

        # Get the content to write
        data = self.expr_simp(data)
        if not isinstance(data, m2_expr.ExprInt):
            raise RuntimeError("A simplification is missing: %s" % data)
        to_write = data.arg.arg

        # Format information
        addr = dest.arg.arg.arg
        size = data.size / 8
        content = hex(to_write).replace("0x", "").replace("L", "")
        content = "0" * (size * 2 - len(content)) + content
        content = content.decode("hex")

        if self.vm.is_little_endian():
            content = content[::-1]

        # Write in VmMngr context
        self.cpu.set_mem(addr, content)
        self.vm.add_mem_write(addr, len(content))

    # Interaction symbexec <-> jitter
    def update_cpu_from_engine(self):
        """Updates @cpu instance according to new CPU values"""

        for symbol in self.symbols:
            if isinstance(symbol, m2_expr.ExprId):
                if hasattr(self.cpu, symbol.name):
                    value = self.symbols.symbols_id[symbol]
                    if not isinstance(value, m2_expr.ExprInt):
                        raise ValueError("A simplification is missing: %s" % value)

                    setattr(self.cpu, symbol.name, value.arg.arg)
            else:
                raise NotImplementedError("Type not handled: %s" % symbol)


    def update_engine_from_cpu(self):
        """Updates CPU values according to @cpu instance"""

        for symbol in self.symbols:
            if isinstance(symbol, m2_expr.ExprId):
                if hasattr(self.cpu, symbol.name):
                    value = m2_expr.ExprInt(getattr(self.cpu, symbol.name),
                                            symbol.size)
                    self.symbols.symbols_id[symbol] = value
            else:
                raise NotImplementedError("Type not handled: %s" % symbol)

    # CPU specific simplifications
    def _simp_handle_segm(self, e_s, expr):
        """Handle 'segm' operation"""
        if not expr.is_op_segm():
            return expr
        if not expr.args[0].is_int():
            return expr
        segm_nb = int(expr.args[0])
        segmaddr = self.cpu.get_segm_base(segm_nb)
        return e_s(m2_expr.ExprInt(segmaddr, expr.size) + expr.args[1])

    def _simp_handle_x86_cpuid(self, e_s, expr):
        """From miasm2/jitter/op_semantics.h: x86_cpuid"""
        if expr.op != "x86_cpuid":
            return expr

        if any(not arg.is_int() for arg in expr.args):
            return expr
        a, reg_num = (int(arg) for arg in expr.args)

        # Not found error is keeped on purpose
        return m2_expr.ExprInt(self.x86_cpuid[a][reg_num], expr.size)

    def enable_emulated_simplifications(self):
        """Enable simplifications needing a CPU instance on associated
        ExpressionSimplifier
        """
        self.expr_simp.enable_passes({
            m2_expr.ExprOp: [self._simp_handle_segm, self._simp_handle_x86_cpuid],
        })

Classes

class EmulatedSymbExec

Symbolic exec instance linked with a jitter

class EmulatedSymbExec(SymbolicExecutionEngine):
    """Symbolic exec instance linked with a jitter"""

    x86_cpuid = {
        0: {
            0: 0xa,
            1: 0x756E6547,
            2: 0x6C65746E,
            3: 0x49656E69,
        },
        1: {
            0: 0x00020652,
            1: 0x00000800,
            2: 0x00000209,
            3: 0x078bf9ff
        },
    }

    def __init__(self, cpu, vm, *args, **kwargs):
        """Instanciate an EmulatedSymbExec, associated to CPU @cpu and bind
        memory accesses.
        @cpu: JitCpu instance
        """
        super(EmulatedSymbExec, self).__init__(*args, **kwargs)
        self.cpu = cpu
        self.vm = vm
        self.func_read = self._func_read
        self.func_write = self._func_write

    def reset_regs(self):
        """Set registers value to 0. Ignore register aliases"""
        for reg in self.ir_arch.arch.regs.all_regs_ids_no_alias:
            self.symbols.symbols_id[reg] = m2_expr.ExprInt(0, size=reg.size)

    # Memory management
    def _func_read(self, expr_mem):
        """Memory read wrapper for symbolic execution
        @expr_mem: ExprMem"""

        addr = expr_mem.arg
        if not addr.is_int():
            return expr_mem
        addr = int(addr)
        size = expr_mem.size / 8
        value = self.cpu.get_mem(addr, size)
        if self.vm.is_little_endian():
            value = value[::-1]
        self.vm.add_mem_read(addr, size)

        return m2_expr.ExprInt(int(value.encode("hex"), 16),
                               expr_mem.size)

    def _func_write(self, symb_exec, dest, data):
        """Memory read wrapper for symbolic execution
        @symb_exec: symbexec instance
        @dest: ExprMem instance
        @data: Expr instance"""

        # Get the content to write
        data = self.expr_simp(data)
        if not isinstance(data, m2_expr.ExprInt):
            raise RuntimeError("A simplification is missing: %s" % data)
        to_write = data.arg.arg

        # Format information
        addr = dest.arg.arg.arg
        size = data.size / 8
        content = hex(to_write).replace("0x", "").replace("L", "")
        content = "0" * (size * 2 - len(content)) + content
        content = content.decode("hex")

        if self.vm.is_little_endian():
            content = content[::-1]

        # Write in VmMngr context
        self.cpu.set_mem(addr, content)
        self.vm.add_mem_write(addr, len(content))

    # Interaction symbexec <-> jitter
    def update_cpu_from_engine(self):
        """Updates @cpu instance according to new CPU values"""

        for symbol in self.symbols:
            if isinstance(symbol, m2_expr.ExprId):
                if hasattr(self.cpu, symbol.name):
                    value = self.symbols.symbols_id[symbol]
                    if not isinstance(value, m2_expr.ExprInt):
                        raise ValueError("A simplification is missing: %s" % value)

                    setattr(self.cpu, symbol.name, value.arg.arg)
            else:
                raise NotImplementedError("Type not handled: %s" % symbol)


    def update_engine_from_cpu(self):
        """Updates CPU values according to @cpu instance"""

        for symbol in self.symbols:
            if isinstance(symbol, m2_expr.ExprId):
                if hasattr(self.cpu, symbol.name):
                    value = m2_expr.ExprInt(getattr(self.cpu, symbol.name),
                                            symbol.size)
                    self.symbols.symbols_id[symbol] = value
            else:
                raise NotImplementedError("Type not handled: %s" % symbol)

    # CPU specific simplifications
    def _simp_handle_segm(self, e_s, expr):
        """Handle 'segm' operation"""
        if not expr.is_op_segm():
            return expr
        if not expr.args[0].is_int():
            return expr
        segm_nb = int(expr.args[0])
        segmaddr = self.cpu.get_segm_base(segm_nb)
        return e_s(m2_expr.ExprInt(segmaddr, expr.size) + expr.args[1])

    def _simp_handle_x86_cpuid(self, e_s, expr):
        """From miasm2/jitter/op_semantics.h: x86_cpuid"""
        if expr.op != "x86_cpuid":
            return expr

        if any(not arg.is_int() for arg in expr.args):
            return expr
        a, reg_num = (int(arg) for arg in expr.args)

        # Not found error is keeped on purpose
        return m2_expr.ExprInt(self.x86_cpuid[a][reg_num], expr.size)

    def enable_emulated_simplifications(self):
        """Enable simplifications needing a CPU instance on associated
        ExpressionSimplifier
        """
        self.expr_simp.enable_passes({
            m2_expr.ExprOp: [self._simp_handle_segm, self._simp_handle_x86_cpuid],
        })

Ancestors (in MRO)

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

Class variables

var StateEngine

var x86_cpuid

Instance variables

var cpu

var func_read

var func_write

var state

Return the current state of the SymbolicEngine

var vm

Methods

def __init__(

self, cpu, vm, *args, **kwargs)

Instanciate an EmulatedSymbExec, associated to CPU @cpu and bind memory accesses. @cpu: JitCpu instance

def __init__(self, cpu, vm, *args, **kwargs):
    """Instanciate an EmulatedSymbExec, associated to CPU @cpu and bind
    memory accesses.
    @cpu: JitCpu instance
    """
    super(EmulatedSymbExec, self).__init__(*args, **kwargs)
    self.cpu = cpu
    self.vm = vm
    self.func_read = self._func_read
    self.func_write = self._func_write

def apply_change(

self, dst, src)

Apply @dst = @src on the current state WITHOUT evaluating both side @dst: Expr, destination @src: Expr, source

def apply_change(self, dst, src):
    """
    Apply @dst = @src on the current state WITHOUT evaluating both side
    @dst: Expr, destination
    @src: Expr, source
    """
    if dst.is_mem():
        self.mem_write(dst, src)
    else:
        self.symbols.write(dst, src)

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 enable_emulated_simplifications(

self)

Enable simplifications needing a CPU instance on associated ExpressionSimplifier

def enable_emulated_simplifications(self):
    """Enable simplifications needing a CPU instance on associated
    ExpressionSimplifier
    """
    self.expr_simp.enable_passes({
        m2_expr.ExprOp: [self._simp_handle_segm, self._simp_handle_x86_cpuid],
    })

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)

Evaluate @expr @expr: Expresion instance to evaluate @cache: None or dictionary linking variables to their values

def eval_expr(self, expr, eval_cache=None):
    """
    Evaluate @expr
    @expr: Expresion instance to evaluate
    @cache: None or dictionary linking variables to their values
    """
    if eval_cache is None:
        eval_cache = {}
    ret = self.eval_expr_visitor(expr, cache=eval_cache)
    assert ret is not None
    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:
        args.append(self.eval_expr_visitor(arg, **kwargs))
    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)
    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"""
    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)

[DEV]: Evaluate an ExprLoc using the current state

def eval_exprloc(self, expr, **kwargs):
    """[DEV]: Evaluate an ExprLoc using the current state"""
    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)
        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)
    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"""
    state = self.StateEngine(dict(self.symbols))
    return state

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 reset_regs(

self)

Set registers value to 0. Ignore register aliases

def reset_regs(self):
    """Set registers value to 0. Ignore register aliases"""
    for reg in self.ir_arch.arch.regs.all_regs_ids_no_alias:
        self.symbols.symbols_id[reg] = m2_expr.ExprInt(0, size=reg.size)

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

def update_cpu_from_engine(

self)

Updates @cpu instance according to new CPU values

def update_cpu_from_engine(self):
    """Updates @cpu instance according to new CPU values"""
    for symbol in self.symbols:
        if isinstance(symbol, m2_expr.ExprId):
            if hasattr(self.cpu, symbol.name):
                value = self.symbols.symbols_id[symbol]
                if not isinstance(value, m2_expr.ExprInt):
                    raise ValueError("A simplification is missing: %s" % value)
                setattr(self.cpu, symbol.name, value.arg.arg)
        else:
            raise NotImplementedError("Type not handled: %s" % symbol)

def update_engine_from_cpu(

self)

Updates CPU values according to @cpu instance

def update_engine_from_cpu(self):
    """Updates CPU values according to @cpu instance"""
    for symbol in self.symbols:
        if isinstance(symbol, m2_expr.ExprId):
            if hasattr(self.cpu, symbol.name):
                value = m2_expr.ExprInt(getattr(self.cpu, symbol.name),
                                        symbol.size)
                self.symbols.symbols_id[symbol] = value
        else:
            raise NotImplementedError("Type not handled: %s" % symbol)