diff options
| author | Camille Mougey <commial@gmail.com> | 2017-03-14 08:27:13 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-03-14 08:27:13 +0100 |
| commit | 67117bf808b8348a103f91ca64749d46de3f2db5 (patch) | |
| tree | 0317a4ba83bd3fe0cc21a89855139271d04af318 /miasm2/ir | |
| parent | 5ee794990ff30ca18909dd3815eda26ac267cbf4 (diff) | |
| parent | f1a2d7456c8a7482939d43ac5c1d6b829db4cdaf (diff) | |
| download | miasm-67117bf808b8348a103f91ca64749d46de3f2db5.tar.gz miasm-67117bf808b8348a103f91ca64749d46de3f2db5.zip | |
Merge pull request #497 from serpilliere/rename_symb
Rename symb
Diffstat (limited to '')
| -rw-r--r-- | miasm2/ir/analysis.py | 41 | ||||
| -rw-r--r-- | miasm2/ir/ir.py | 132 | ||||
| -rw-r--r-- | miasm2/ir/symbexec.py | 53 | ||||
| -rw-r--r-- | miasm2/ir/translators/C.py | 4 | ||||
| -rw-r--r-- | miasm2/ir/translators/smt2.py | 4 | ||||
| -rw-r--r-- | miasm2/ir/translators/z3_ir.py | 4 |
6 files changed, 156 insertions, 82 deletions
diff --git a/miasm2/ir/analysis.py b/miasm2/ir/analysis.py index 73391bb2..4f7b321f 100644 --- a/miasm2/ir/analysis.py +++ b/miasm2/ir/analysis.py @@ -2,8 +2,8 @@ import logging -from miasm2.ir.symbexec import symbexec -from miasm2.ir.ir import ir, AssignBlock +from miasm2.ir.symbexec import SymbolicExecutionEngine +from miasm2.ir.ir import IntermediateRepresentation, AssignBlock from miasm2.expression.expression \ import ExprAff, ExprCond, ExprId, ExprInt, ExprMem, ExprOp @@ -14,14 +14,17 @@ log.addHandler(console_handler) log.setLevel(logging.WARNING) -class ira(ir): +class ira(IntermediateRepresentation): """IR Analysis This class provides higher level manipulations on IR, such as dead instruction removals. - This class can be used as a common parent with `miasm2.ir.ir::ir` class. + This class can be used as a common parent with + `miasm2.ir.ir::IntermediateRepresentation` class. + For instance: class ira_x86_16(ir_x86_16, ira) + """ def ira_regs_ids(self): @@ -84,14 +87,14 @@ class ira(ir): useful = set() for node in self.graph.nodes(): - if node not in self.blocs: + if node not in self.blocks: continue - block = self.blocs[node] + block = self.blocks[node] successors = self.graph.successors(node) has_son = bool(successors) for p_son in successors: - if p_son not in self.blocs: + if p_son not in self.blocks: # Leaf has lost its son: don't remove anything # reaching this block for r in self.ira_regs_ids(): @@ -136,7 +139,7 @@ class ira(ir): useful.add(elem) irb_label, irs_ind, dst = elem - assignblk = self.blocs[irb_label].irs[irs_ind] + assignblk = self.blocks[irb_label].irs[irs_ind] ins = assignblk.dst2ExprAff(dst) # Handle dependencies of used variables in ins @@ -161,10 +164,10 @@ class ira(ir): """ useful = self._mark_useful_code() modified = False - for block in self.blocs.values(): - modified |= self.remove_dead_instr(block, useful) + for irblock in self.blocks.values(): + modified |= self.remove_dead_instr(irblock, useful) # Remove useless structures - for assignblk in block.irs: + for assignblk in irblock.irs: del assignblk._cur_kill del assignblk._prev_kill del assignblk._cur_reach @@ -214,7 +217,7 @@ class ira(ir): # Compute reach from predecessors for n_pred in self.graph.predecessors(irb.label): - p_block = self.blocs[n_pred] + p_block = self.blocks[n_pred] # Handle each register definition for c_reg in self.ira_regs_ids(): @@ -253,8 +256,8 @@ class ira(ir): fixed = True for node in self.graph.nodes(): - if node in self.blocs: - irb = self.blocs[node] + if node in self.blocks: + irb = self.blocks[node] for assignblk in irb.irs: if (assignblk._cur_reach != assignblk._prev_reach or assignblk._cur_kill != assignblk._prev_kill): @@ -276,8 +279,8 @@ class ira(ir): log.debug('iteration...') while not fixed_point: for node in self.graph.nodes(): - if node in self.blocs: - self.compute_reach_block(self.blocs[node]) + if node in self.blocks: + self.compute_reach_block(self.blocks[node]) fixed_point = self._test_kill_reach_fix() def dead_simp(self): @@ -288,7 +291,7 @@ class ira(ir): Source : Kennedy, K. (1979). A survey of data flow analysis techniques. IBM Thomas J. Watson Research Division, page 43 """ - # Update r/w variables for all irblocs + # Update r/w variables for all irblocks self.get_rw(self.ira_regs_ids()) # Liveness step self.compute_reach() @@ -297,10 +300,10 @@ class ira(ir): self.simplify_blocs() def gen_equations(self): - for irb in self.blocs.values(): + for irb in self.blocks.values(): symbols_init = dict(self.arch.regs.all_regs_ids_init) - sb = symbexec(self, dict(symbols_init)) + sb = SymbolicExecutionEngine(self, dict(symbols_init)) sb.emulbloc(irb) eqs = [] for n_w in sb.symbols: diff --git a/miasm2/ir/ir.py b/miasm2/ir/ir.py index 0a7d68ce..5ebb51ec 100644 --- a/miasm2/ir/ir.py +++ b/miasm2/ir/ir.py @@ -17,13 +17,15 @@ # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # +import warnings + from itertools import chain import miasm2.expression.expression as m2_expr from miasm2.expression.expression_helper import get_missing_interval from miasm2.expression.simplifications import expr_simp -from miasm2.core.asmbloc import asm_symbol_pool, expr_is_label, asm_label, \ - asm_bloc +from miasm2.core.asmblock import AsmSymbolPool, expr_is_label, AsmLabel, \ + AsmBlock from miasm2.core.graph import DiGraph @@ -95,7 +97,7 @@ class AssignBlock(dict): # Build the merging expression args = list(e_colision.union(remaining)) - args.sort(key=lambda x:x[1]) + args.sort(key=lambda x: x[1]) starts = [start for (_, start, _) in args] assert len(set(starts)) == len(starts) args = [expr for (expr, _, _) in args] @@ -108,7 +110,7 @@ class AssignBlock(dict): """Return an Expr list of extra expressions needed during the object instanciation""" if not isinstance(src, m2_expr.ExprCompose): - raise ValueError("Get mod slice not on expraff slice", str(self)) + raise ValueError("Get mod slice not on expraff slice", str(src)) modified_s = [] for index, arg in src.iter_args(): if not (isinstance(arg, m2_expr.ExprSlice) and @@ -160,10 +162,20 @@ class AssignBlock(dict): return m2_expr.ExprAff(dst, self[dst]) -class irbloc(object): +class IRBlock(object): + """Intermediate representation block object. + + Stand for an intermediate representation basic block. + """ def __init__(self, label, irs, lines=None): - assert(isinstance(label, asm_label)) + """ + @label: AsmLabel of the IR basic block + @irs: list of AssignBlock + @lines: list of native instructions + """ + + assert isinstance(label, AsmLabel) if lines is None: lines = [] self.label = label @@ -196,7 +208,7 @@ class irbloc(object): assignblk = self.irs[self._dst_linenb] for dst in assignblk: if isinstance(dst, m2_expr.ExprId) and dst.name == "IRDst": - del(assignblk[dst]) + del assignblk[dst] assignblk[dst] = value # Sanity check is already done in _get_dst break @@ -240,6 +252,17 @@ class irbloc(object): return "\n".join(out) +class irbloc(IRBlock): + """ + DEPRECATED object + Use IRBlock instead of irbloc + """ + + def __init__(self, label, irs, lines=None): + warnings.warn('DEPRECATION WARNING: use "IRBlock" instead of "irblock"') + super(irbloc, self).__init__(label, irs, lines) + + class DiGraphIR(DiGraph): """DiGraph for IR instances""" @@ -297,13 +320,18 @@ class DiGraphIR(DiGraph): return super(DiGraphIR, self).dot() -class ir(object): +class IntermediateRepresentation(object): + """ + Intermediate representation object + + Allow native assembly to intermediate representation traduction + """ def __init__(self, arch, attrib, symbol_pool=None): if symbol_pool is None: - symbol_pool = asm_symbol_pool() + symbol_pool = AsmSymbolPool() self.symbol_pool = symbol_pool - self.blocs = {} + self.blocks = {} self.pc = arch.getpc(attrib) self.sp = arch.getsp(attrib) self.arch = arch @@ -311,6 +339,11 @@ class ir(object): # Lazy structure self._graph = None + @property + def get_blocs(self): + warnings.warn('DEPRECATION WARNING: use ".blocks" instead of ".blocs"') + return self.blocks + def get_ir(self, instr): raise NotImplementedError("Abstract Method") @@ -326,13 +359,13 @@ class ir(object): @ad: an ExprId/ExprInt/label/int""" if (isinstance(ad, m2_expr.ExprId) and - isinstance(ad.name, asm_label)): + isinstance(ad.name, AsmLabel)): ad = ad.name if isinstance(ad, m2_expr.ExprInt): ad = int(ad) - if type(ad) in [int, long]: + if isinstance(ad, (int, long)): ad = self.symbol_pool.getby_offset_create(ad) - elif isinstance(ad, asm_label): + elif isinstance(ad, AsmLabel): ad = self.symbol_pool.getby_name_create(ad.name) return ad @@ -341,16 +374,16 @@ class ir(object): @ad: an ExprId/ExprInt/label/int""" label = self.get_label(ad) - return self.blocs.get(label, None) + return self.blocks.get(label, None) def add_instr(self, l, ad=0, gen_pc_updt=False): - b = asm_bloc(self.gen_label()) + b = AsmBlock(self.gen_label()) b.lines = [l] self.add_bloc(b, gen_pc_updt) def getby_offset(self, offset): out = set() - for irb in self.blocs.values(): + for irb in self.blocks.values(): for l in irb.lines: if l.offset <= offset < l.offset + l.l: out.add(irb) @@ -360,7 +393,7 @@ class ir(object): c.irs.append(AssignBlock([m2_expr.ExprAff(self.pc, m2_expr.ExprInt(l.offset, self.pc.size) - )])) + )])) c.lines.append(l) def pre_add_instr(self, block, instr, irb_cur, ir_blocks_all, gen_pc_updt): @@ -398,7 +431,7 @@ class ir(object): if irb_cur is None: return None - assignblk, ir_blocs_extra = self.instr2ir(instr) + assignblk, ir_blocks_extra = self.instr2ir(instr) if gen_pc_updt is not False: self.gen_pc_update(irb_cur, instr) @@ -406,14 +439,14 @@ class ir(object): irb_cur.irs.append(assignblk) irb_cur.lines.append(instr) - if ir_blocs_extra: - for b in ir_blocs_extra: - b.lines = [instr] * len(b.irs) - ir_blocks_all += ir_blocs_extra + if ir_blocks_extra: + for irblock in ir_blocks_extra: + irblock.lines = [instr] * len(irblock.irs) + ir_blocks_all += ir_blocks_extra irb_cur = None return irb_cur - def add_bloc(self, block, gen_pc_updt = False): + def add_bloc(self, block, gen_pc_updt=False): """ Add a native block to the current IR @block: native assembly block @@ -425,7 +458,7 @@ class ir(object): for instr in block.lines: if irb_cur is None: label = self.get_instr_label(instr) - irb_cur = irbloc(label, [], []) + irb_cur = IRBlock(label, [], []) ir_blocks_all.append(irb_cur) irb_cur = self.add_instr_to_irblock(block, instr, irb_cur, ir_blocks_all, gen_pc_updt) @@ -449,27 +482,26 @@ class ir(object): return ir return None - def set_empty_dst_to_next(self, bloc, ir_blocs): - for b in ir_blocs: - if b.dst is not None: + def set_empty_dst_to_next(self, block, ir_blocks): + for irblock in ir_blocks: + if irblock.dst is not None: continue - next_lbl = bloc.get_next() + next_lbl = block.get_next() if next_lbl is None: - dst = m2_expr.ExprId(self.get_next_label(bloc.lines[-1]), + dst = m2_expr.ExprId(self.get_next_label(block.lines[-1]), self.pc.size) else: dst = m2_expr.ExprId(next_lbl, self.pc.size) - b.irs.append(AssignBlock([m2_expr.ExprAff(self.IRDst, dst)])) - b.lines.append(b.lines[-1]) + irblock.irs.append(AssignBlock([m2_expr.ExprAff(self.IRDst, dst)])) + irblock.lines.append(irblock.lines[-1]) - def post_add_bloc(self, bloc, ir_blocs): - self.set_empty_dst_to_next(bloc, ir_blocs) + def post_add_bloc(self, block, ir_blocks): + self.set_empty_dst_to_next(block, ir_blocks) - for irb in ir_blocs: - self.irbloc_fix_regs_for_mode(irb, self.attrib) - - self.blocs[irb.label] = irb + for irblock in ir_blocks: + self.irbloc_fix_regs_for_mode(irblock, self.attrib) + self.blocks[irblock.label] = irblock # Forget graph if any self._graph = None @@ -490,8 +522,8 @@ class ir(object): return l def simplify_blocs(self): - for irb in self.blocs.values(): - for assignblk in irb.irs: + for irblock in self.blocks.values(): + for assignblk in irblock.irs: for dst, src in assignblk.items(): del assignblk[dst] assignblk[expr_simp(dst)] = expr_simp(src) @@ -509,8 +541,8 @@ class ir(object): """ if regs_ids is None: regs_ids = [] - for b in self.blocs.values(): - b.get_rw(regs_ids) + for irblock in self.blocks.values(): + irblock.get_rw(regs_ids) def _extract_dst(self, todo, done): """ @@ -522,7 +554,7 @@ class ir(object): dst = todo.pop() if expr_is_label(dst): done.add(dst) - elif isinstance(dst, m2_expr.ExprMem) or isinstance(dst, m2_expr.ExprInt): + elif isinstance(dst, (m2_expr.ExprMem, m2_expr.ExprInt)): done.add(dst) elif isinstance(dst, m2_expr.ExprCond): todo.add(dst.src1) @@ -561,8 +593,8 @@ class ir(object): """ Gen irbloc digraph """ - self._graph = DiGraphIR(self.blocs) - for lbl, b in self.blocs.iteritems(): + self._graph = DiGraphIR(self.blocks) + for lbl, b in self.blocks.iteritems(): self._graph.add_node(lbl) dst = self.dst_trackback(b) for d in dst: @@ -579,3 +611,15 @@ class ir(object): if self._graph is None: self._gen_graph() return self._graph + + + +class ir(IntermediateRepresentation): + """ + DEPRECATED object + Use IntermediateRepresentation instead of ir + """ + + def __init__(self, label, irs, lines=None): + warnings.warn('DEPRECATION WARNING: use "IntermediateRepresentation" instead of "ir"') + super(ir, self).__init__(label, irs, lines) diff --git a/miasm2/ir/symbexec.py b/miasm2/ir/symbexec.py index 8e04c45b..ab873cfd 100644 --- a/miasm2/ir/symbexec.py +++ b/miasm2/ir/symbexec.py @@ -1,13 +1,12 @@ +import warnings +import logging + import miasm2.expression.expression as m2_expr from miasm2.expression.modint import int32 from miasm2.expression.simplifications import expr_simp -from miasm2.core import asmbloc +from miasm2.core import asmblock from miasm2.ir.ir import AssignBlock from miasm2.core.interval import interval -from miasm2.core.utils import get_caller_name -import warnings - -import logging log = logging.getLogger("symbexec") @@ -17,7 +16,10 @@ log.addHandler(console_handler) log.setLevel(logging.INFO) -class symbols(object): +class SymbolsMngr(object): + """ + Store registers and memory symbolic values + """ def __init__(self, init=None): if init is None: @@ -81,13 +83,13 @@ class symbols(object): [x[0] for x in self.symbols_mem.values()]) def copy(self): - new_symbols = symbols() + new_symbols = SymbolsMngr() new_symbols.symbols_id = dict(self.symbols_id) new_symbols.symbols_mem = dict(self.symbols_mem) return new_symbols def inject_info(self, info): - new_symbols = symbols() + new_symbols = SymbolsMngr() for expr, value in self.items(): expr = expr_simp(expr.replace_expr(info)) value = expr_simp(value.replace_expr(info)) @@ -95,13 +97,17 @@ class symbols(object): return new_symbols -class symbexec(object): +class SymbolicExecutionEngine(object): + """ + Symbolic execution engine + Allow IR code emulation in symbolic domain + """ def __init__(self, ir_arch, known_symbols, func_read=None, func_write=None, sb_expr_simp=expr_simp): - self.symbols = symbols() + self.symbols = SymbolsMngr() for expr, value in known_symbols.items(): self.symbols[expr] = value self.func_read = func_read @@ -199,7 +205,7 @@ class symbexec(object): elif isinstance(expr, m2_expr.ExprInt): return expr elif isinstance(expr, m2_expr.ExprId): - if isinstance(expr.name, asmbloc.asm_label) and expr.name.offset is not None: + if isinstance(expr.name, asmblock.AsmLabel) and expr.name.offset is not None: ret = m2_expr.ExprInt(expr.name.offset, expr.size) else: ret = state.get(expr, expr) @@ -441,7 +447,7 @@ class symbexec(object): print '_' * 80 return self.eval_expr(self.ir_arch.IRDst) - def emul_ir_bloc(self, myir, addr, step=False): + def emul_ir_bloc(self, _, addr, step=False): warnings.warn('DEPRECATION WARNING: use "emul_ir_block(self, addr, step=False)" instead of emul_ir_bloc') return self.emul_ir_block(addr, step) @@ -451,7 +457,7 @@ class symbexec(object): addr = self.emulbloc(irblock, step=step) return addr - def emul_ir_blocs(self, myir, addr, lbl_stop=None, step=False): + def emul_ir_blocs(self, _, addr, lbl_stop=None, step=False): warnings.warn('DEPRECATION WARNING: use "emul_ir_blocks(self, addr, lbl_stop=None, step=False):" instead of emul_ir_blocs') return self.emul_ir_blocks(addr, lbl_stop, step) @@ -466,6 +472,11 @@ class symbexec(object): return addr 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) for mem_addr, (mem, _) in self.symbols.symbols_mem.items(): diff = self.expr_simp(mem_addr - stack_ptr) @@ -487,3 +498,19 @@ class symbexec(object): ret = self.eval_expr(expr) return ret + +class symbexec(SymbolicExecutionEngine): + """ + DEPRECATED object + Use SymbolicExecutionEngine instead of symbexec + """ + + def __init__(self, ir_arch, known_symbols, + func_read=None, + func_write=None, + sb_expr_simp=expr_simp): + warnings.warn("Deprecated API: use SymbolicExecutionEngine") + super(symbexec, self).__init__(ir_arch, known_symbols, + func_read, + func_write, + sb_expr_simp=expr_simp) diff --git a/miasm2/ir/translators/C.py b/miasm2/ir/translators/C.py index c7913ea8..1dfdbb00 100644 --- a/miasm2/ir/translators/C.py +++ b/miasm2/ir/translators/C.py @@ -1,5 +1,5 @@ from miasm2.ir.translators.translator import Translator -from miasm2.core import asmbloc +from miasm2.core import asmblock from miasm2.expression.modint import size2mask @@ -23,7 +23,7 @@ class TranslatorC(Translator): def from_ExprId(self, expr): - if isinstance(expr.name, asmbloc.asm_label): + if isinstance(expr.name, asmblock.AsmLabel): return "0x%x" % expr.name.offset return str(expr) diff --git a/miasm2/ir/translators/smt2.py b/miasm2/ir/translators/smt2.py index 5d5fb26b..26ff9127 100644 --- a/miasm2/ir/translators/smt2.py +++ b/miasm2/ir/translators/smt2.py @@ -1,7 +1,7 @@ import logging import operator -from miasm2.core.asmbloc import asm_label +from miasm2.core.asmblock import AsmLabel from miasm2.ir.translators.translator import Translator from miasm2.expression.smt2_helper import * @@ -134,7 +134,7 @@ class TranslatorSMT2(Translator): return bit_vec_val(expr.arg.arg, expr.size) def from_ExprId(self, expr): - if isinstance(expr.name, asm_label): + if isinstance(expr.name, AsmLabel): if expr.name.offset is not None: return bit_vec_val(str(expr.name.offset), expr.size) else: diff --git a/miasm2/ir/translators/z3_ir.py b/miasm2/ir/translators/z3_ir.py index ccb14b4f..d8b550d9 100644 --- a/miasm2/ir/translators/z3_ir.py +++ b/miasm2/ir/translators/z3_ir.py @@ -3,7 +3,7 @@ import operator import z3 -from miasm2.core.asmbloc import asm_label +from miasm2.core.asmblock import AsmLabel from miasm2.ir.translators.translator import Translator log = logging.getLogger("translator_z3") @@ -121,7 +121,7 @@ class TranslatorZ3(Translator): return z3.BitVecVal(expr.arg.arg, expr.size) def from_ExprId(self, expr): - if isinstance(expr.name, asm_label) and expr.name.offset is not None: + if isinstance(expr.name, AsmLabel) and expr.name.offset is not None: return z3.BitVecVal(expr.name.offset, expr.size) else: return z3.BitVec(str(expr), expr.size) |