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)
- SymbExecTop
- SymbExecTopNoMem
- miasm2.ir.symbexec.SymbolicExecutionEngine
- __builtin__.object
Class variables
Instance variables
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)
- SymbolicStateTop
- miasm2.ir.symbexec.StateEngine
- __builtin__.object
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)