diff options
Diffstat (limited to 'miasm2/core')
| -rw-r--r-- | miasm2/core/asmbloc.py | 52 | ||||
| -rw-r--r-- | miasm2/core/bin_stream.py | 4 | ||||
| -rw-r--r-- | miasm2/core/cpu.py | 413 | ||||
| -rw-r--r-- | miasm2/core/interval.py | 124 | ||||
| -rw-r--r-- | miasm2/core/parse_asm.py | 86 | ||||
| -rw-r--r-- | miasm2/core/utils.py | 4 |
6 files changed, 231 insertions, 452 deletions
diff --git a/miasm2/core/asmbloc.py b/miasm2/core/asmbloc.py index cb8423f6..4770b597 100644 --- a/miasm2/core/asmbloc.py +++ b/miasm2/core/asmbloc.py @@ -70,7 +70,7 @@ class asm_label: def __eq__(self, a): if isinstance(a, asm_label): - return self._hash == a._hash + return self._hash == hash(a) else: return False @@ -154,7 +154,7 @@ class asm_bloc: self.lines.append(l) def addto(self, c): - assert(type(self.bto) is set) + assert type(self.bto) is set self.bto.add(c) def split(self, offset, l): @@ -274,21 +274,21 @@ class asm_symbol_pool: """ if isinstance(obj, asm_label): if obj.name in self.s: - del(self.s[obj.name]) + del self.s[obj.name] if obj.offset is not None and obj.offset in self.s_offset: - del(self.s_offset[obj.offset]) + del self.s_offset[obj.offset] else: offset = int(obj) if offset in self.s_offset: obj = self.s_offset[offset] - del(self.s_offset[offset]) + del self.s_offset[offset] if obj.name in self.s: - del(self.s[obj.name]) + del self.s[obj.name] def del_offset(self, l=None): if l is not None: if l.offset in self.s_offset: - del(self.s_offset[l.offset]) + del self.s_offset[l.offset] l.offset = None else: self.s_offset = {} @@ -317,7 +317,7 @@ class asm_symbol_pool: if not s.name in self.s: log_asmbloc.warn('unk symb') return - del(self.s[s.name]) + del self.s[s.name] s.name = newname self.s[s.name] = s @@ -327,7 +327,7 @@ class asm_symbol_pool: if not label.name in self.s: raise ValueError('label %s not in symbol pool' % label) if not isinstance(label.offset, list) and label.offset in self.s_offset: - del(self.s_offset[label.offset]) + del self.s_offset[label.offset] label.offset = offset if not isinstance(label.offset, list): self.s_offset[label.offset] = label @@ -440,7 +440,8 @@ def dis_bloc(mnemo, pool_bin, cur_bloc, offset, job_done, symbol_pool, dst = instr.getdstflow(symbol_pool) dstn = [] for d in dst: - if isinstance(d, m2_expr.ExprId) and isinstance(d.name, asm_label): + if isinstance(d, m2_expr.ExprId) and \ + isinstance(d.name, asm_label): dstn.append(d.name) dst = dstn if (not instr.is_subcall()) or follow_call: @@ -699,7 +700,7 @@ def group_blocs(blocs): continue if c.label in groups_bloc: b += groups_bloc[c.label] - del(groups_bloc[c.label]) + del groups_bloc[c.label] groups_bloc[b[0].label] = b found_in_group = True break @@ -784,7 +785,8 @@ def gen_non_free_mapping(group_bloc, dont_erase=[]): return non_free_mapping -def resolve_symbol(group_bloc, symbol_pool, dont_erase=[], max_offset=0xFFFFFFFF): +def resolve_symbol(group_bloc, symbol_pool, dont_erase=[], + max_offset=0xFFFFFFFF): """ place all asmblocs """ @@ -824,7 +826,7 @@ def resolve_symbol(group_bloc, symbol_pool, dont_erase=[], max_offset=0xFFFFFFFF log_asmbloc.debug( "consumed %d rest: %d" % (g.total_max_l, int(tmp))) free_interval[g] = tmp - del(free_interval[x]) + del free_interval[x] symbol_pool.set_offset( g, [group_bloc[x][-1].label, group_bloc[x][-1], 1]) g.fixedblocs = True @@ -853,7 +855,7 @@ def resolve_symbol(group_bloc, symbol_pool, dont_erase=[], max_offset=0xFFFFFFFF log_asmbloc.debug( "consumed %d rest: %d" % (g.total_max_l, int(tmp))) free_interval[g] = tmp - del(free_interval[k]) + del free_interval[k] g.fixedblocs = True break @@ -910,8 +912,6 @@ def calc_symbol_offset(symbol_pool): for label in symbol_pool.items(): if label.offset is None: - # raise ValueError("symbol missing?", label) - #print "symbol missing?? %s" % label label.offset_g = None continue if not is_int(label.offset): @@ -935,7 +935,8 @@ def calc_symbol_offset(symbol_pool): s_to_use.add(l) -def asmbloc_final(mnemo, blocs, symbol_pool, symb_reloc_off=None, conservative = False): +def asmbloc_final(mnemo, blocs, symbol_pool, symb_reloc_off=None, + conservative=False): log_asmbloc.info("asmbloc_final") if symb_reloc_off is None: symb_reloc_off = {} @@ -954,7 +955,6 @@ def asmbloc_final(mnemo, blocs, symbol_pool, symb_reloc_off=None, conservative = symbols = asm_symbol_pool() for s, v in symbol_pool.s.items(): symbols.add_label(s, v.offset_g) - # print symbols # test if bad encoded relative for bloc in blocs: @@ -986,7 +986,6 @@ def asmbloc_final(mnemo, blocs, symbol_pool, symb_reloc_off=None, conservative = c, candidates = conservative_asm( mnemo, instr, symbol_reloc_off, conservative) - # print candidates for i, e in enumerate(sav_a): instr.args[i] = e @@ -1016,12 +1015,10 @@ def asmbloc_final(mnemo, blocs, symbol_pool, symb_reloc_off=None, conservative = if my_s is not None: my_symb_reloc_off[bloc.label].append(offset_i + my_s) offset_i += instr.l - assert(len(instr.data) == instr.l) + assert len(instr.data) == instr.l # we have fixed all relative values # recompute good offsets for label in symbol_pool.items(): - # if label.offset_g is None: - # fdfd symbol_pool.set_offset(label, label.offset_g) for a, b in my_symb_reloc_off.items(): @@ -1044,7 +1041,7 @@ def asm_resolve_final(mnemo, blocs, symbol_pool, dont_erase=[], for bloc in resolved_b: offset = bloc.label.offset for line in bloc.lines: - assert(line.data is not None) + assert line.data is not None patches[offset] = line.data for cur_pos in xrange(line.l): if offset + cur_pos in written_bytes: @@ -1232,10 +1229,9 @@ def bloc_merge(blocs, dont_merge=[]): # and parent has only one son if len(bp.bto) != 1: continue - """ - and will not create next loop composed of constraint_next from son to - parent - """ + # and will not create next loop composed of constraint_next from son to + # parent + path = bloc_find_path_next(blocs, blocby_label, b, bp) if path: continue @@ -1266,7 +1262,7 @@ def bloc_merge(blocs, dont_merge=[]): bp.lines += b.lines bp.bto = b.bto - del(blocs[i]) + del blocs[i] i = -1 diff --git a/miasm2/core/bin_stream.py b/miasm2/core/bin_stream.py index 19614661..6e158061 100644 --- a/miasm2/core/bin_stream.py +++ b/miasm2/core/bin_stream.py @@ -96,9 +96,9 @@ class bin_stream_str(bin_stream): class bin_stream_file(bin_stream): - def __init__(self, bin, offset=0L, shift=0): + def __init__(self, binary, offset=0L, shift=0): bin_stream.__init__(self) - self.bin = bin + self.bin = binary self.bin.seek(0, 2) self.shift = shift self.l = self.bin.tell() diff --git a/miasm2/core/cpu.py b/miasm2/core/cpu.py index ce6cf288..f8fdb4ff 100644 --- a/miasm2/core/cpu.py +++ b/miasm2/core/cpu.py @@ -4,10 +4,12 @@ import re import struct import logging -from pyparsing import * -from miasm2.expression.expression import * -from miasm2.core import asmbloc from collections import defaultdict + +import pyparsing + +import miasm2.expression.expression as m2_expr +from miasm2.core import asmbloc from miasm2.core.bin_stream import bin_stream, bin_stream_str from miasm2.core.utils import Disasm_Exception from miasm2.expression.simplifications import expr_simp @@ -18,8 +20,6 @@ console_handler.setFormatter(logging.Formatter("%(levelname)-5s: %(message)s")) log.addHandler(console_handler) log.setLevel(logging.WARN) -# size2int = {8:ExprInt8, 16:ExprInt16, 32:ExprInt32,64:ExprInt64} - class bitobj: @@ -81,9 +81,9 @@ def literal_list(l): l = l[:] l.sort() l = l[::-1] - o = Literal(l[0]) + o = pyparsing.Literal(l[0]) for x in l[1:]: - o |= Literal(x) + o |= pyparsing.Literal(x) return o @@ -118,7 +118,7 @@ def gen_reg(rname, env, sz=32): """ rnamel = rname.lower() - r = ExprId(rname, sz) + r = m2_expr.ExprId(rname, sz) reg_str = [rname] reg_expr = [r] regi = reg_info(reg_str, reg_expr) @@ -137,8 +137,8 @@ def gen_regs(rnames, env, sz=32): regs_expr = [] regs_init = [] for rname in rnames: - r = ExprId(rname, sz) - r_init = ExprId(rname+'_init', sz) + r = m2_expr.ExprId(rname, sz) + r_init = m2_expr.ExprId(rname+'_init', sz) regs_str.append(rname) regs_expr.append(r) regs_init.append(r_init) @@ -148,26 +148,23 @@ def gen_regs(rnames, env, sz=32): return regs_expr, regs_init, reginfo -LPARENTHESIS = Literal("(") -RPARENTHESIS = Literal(")") - - -# +LPARENTHESIS = pyparsing.Literal("(") +RPARENTHESIS = pyparsing.Literal(")") def int2expr(t): v = t[0] - return (ExprInt, v) + return (m2_expr.ExprInt, v) def parse_op(t): v = t[0] - return (ExprOp, v) + return (m2_expr.ExprOp, v) def parse_id(t): v = t[0] - return (ExprId, v) + return (m2_expr.ExprId, v) def ast_parse_op(t): @@ -175,14 +172,14 @@ def ast_parse_op(t): return t[0] if len(t) == 2: if t[0] in ['-', '+', '!']: - return ExprOp(t[0], t[1]) + return m2_expr.ExprOp(t[0], t[1]) if len(t) == 3: args = [t[0], t[2]] if t[1] == '-': # a - b => a + (-b) t[1] = '+' t[2] = - t[2] - return ExprOp(t[1], t[0], t[2]) + return m2_expr.ExprOp(t[1], t[0], t[2]) t = t[::-1] while len(t) >= 3: o1, op, o2 = t.pop(), t.pop(), t.pop() @@ -190,7 +187,7 @@ def ast_parse_op(t): # a - b => a + (-b) op = '+' o2 = - o2 - e = ExprOp(op, o1, o2) + e = m2_expr.ExprOp(op, o1, o2) t.append(e) if len(t) != 1: raise NotImplementedError('strange op') @@ -198,20 +195,20 @@ def ast_parse_op(t): def ast_id2expr(a): - return ExprId(a, 32) + return m2_expr.ExprId(a, 32) def ast_int2expr(a): - return ExprInt32(a) + return m2_expr.ExprInt32(a) def ast_raw2expr(a, my_id2expr, my_int2expr): assert(isinstance(a, tuple)) - if a[0] is ExprId: + if a[0] is m2_expr.ExprId: e = my_id2expr(a[1]) - elif a[0] is ExprInt: + elif a[0] is m2_expr.ExprInt: e = my_int2expr(a[1]) - elif a[0] is ExprOp: + elif a[0] is m2_expr.ExprOp: out = [] for x in a[1]: if isinstance(x, tuple): @@ -225,11 +222,11 @@ def ast_raw2expr(a, my_id2expr, my_int2expr): def ast_get_ids(a): assert(isinstance(a, tuple)) - if a[0] is ExprId: + if a[0] is m2_expr.ExprId: return set([a[1]]) - elif a[0] is ExprInt: + elif a[0] is m2_expr.ExprInt: return set() - elif a[0] is ExprOp: + elif a[0] is m2_expr.ExprOp: out = set() for x in a[1]: if isinstance(x, tuple): @@ -240,9 +237,9 @@ def ast_get_ids(a): def _extract_ast_core(a): assert(isinstance(a, tuple)) - if a[0] in [ExprInt, ExprId]: + if a[0] in [m2_expr.ExprInt, m2_expr.ExprId]: return a - elif a[0] is ExprOp: + elif a[0] is m2_expr.ExprOp: out = [] for x in a[1]: if isinstance(x, tuple): @@ -256,16 +253,14 @@ def _extract_ast_core(a): def extract_ast_core(v, my_id2expr, my_int2expr): ast_tokens = _extract_ast_core(v) ids = ast_get_ids(ast_tokens) - # print 'IDS', ids ids_expr = [my_id2expr(x) for x in ids] - # print 'IDS_expr', ids_expr sizes = set([i.size for i in ids_expr]) - # print "SIZE", sizes + if len(sizes) == 0: pass elif len(sizes) == 1: size = sizes.pop() - my_int2expr = lambda x: ExprInt_fromsize(size, x) + my_int2expr = lambda x: m2_expr.ExprInt_fromsize(size, x) else: raise ValueError('multiple sizes in ids') e = ast_raw2expr(ast_tokens, my_id2expr, my_int2expr) @@ -281,7 +276,7 @@ class parse_ast: def __call__(self, v): v = v[0] - if isinstance(v, Expr): + if isinstance(v, m2_expr.Expr): return v return self.extract_ast_core(v, self.id2expr, self.int2expr) @@ -291,34 +286,42 @@ def neg_int(t): return x -integer = Word(nums).setParseAction(lambda s, l, t: int(t[0])) -hex_int = Combine(Literal('0x') + Word(hexnums)).setParseAction( - lambda s, l, t: int(t[0], 16)) +integer = pyparsing.Word(pyparsing.nums).setParseAction(lambda _a, _b, t: + int(t[0])) +hex_word = pyparsing.Literal('0x') + pyparsing.Word(pyparsing.hexnums) +hex_int = pyparsing.Combine(hex_word).setParseAction(lambda _a, _b, t: + int(t[0], 16)) # str_int = (Optional('-') + (hex_int | integer)) str_int_pos = (hex_int | integer) -str_int_neg = (Suppress('-') + (hex_int | integer)).setParseAction(neg_int) +str_int_neg = (pyparsing.Suppress('-') + \ + (hex_int | integer)).setParseAction(neg_int) str_int = str_int_pos | str_int_neg str_int.setParseAction(int2expr) -logicop = oneOf('& | ^ >> << <<< >>>') -signop = oneOf('+ -') -multop = oneOf('* / %') -plusop = oneOf('+ -') +logicop = pyparsing.oneOf('& | ^ >> << <<< >>>') +signop = pyparsing.oneOf('+ -') +multop = pyparsing.oneOf('* / %') +plusop = pyparsing.oneOf('+ -') def gen_base_expr(): - variable = Word(alphas + "_$.", alphanums + "_") + variable = pyparsing.Word(pyparsing.alphas + "_$.", + pyparsing.alphanums + "_") variable.setParseAction(parse_id) operand = str_int | variable - base_expr = operatorPrecedence(operand, - [("!", 1, opAssoc.RIGHT, parse_op), - (logicop, 2, opAssoc.RIGHT, parse_op), - (signop, 1, opAssoc.RIGHT, parse_op), - (multop, 2, opAssoc.LEFT, parse_op), - (plusop, 2, opAssoc.LEFT, parse_op), ] - ) + base_expr = pyparsing.operatorPrecedence(operand, + [("!", 1, pyparsing.opAssoc.RIGHT, parse_op), + (logicop, 2, pyparsing.opAssoc.RIGHT, + parse_op), + (signop, 1, pyparsing.opAssoc.RIGHT, + parse_op), + (multop, 2, pyparsing.opAssoc.LEFT, + parse_op), + (plusop, 2, pyparsing.opAssoc.LEFT, + parse_op), + ]) return variable, operand, base_expr @@ -327,9 +330,6 @@ variable, operand, base_expr = gen_base_expr() my_var_parser = parse_ast(ast_id2expr, ast_int2expr) base_expr.setParseAction(my_var_parser) -# - - default_prio = 0x1337 @@ -357,11 +357,7 @@ class bs(object): def __init__(self, strbits=None, l=None, cls=None, fname=None, order=0, flen=None, **kargs): if fname is None: - # fname = hex(id((strbits, l, cls, fname, order, flen, kargs))) - # fname = hex(id((strbits, l, fname, order, flen))) - # print str((strbits, l, cls, fname, order, flen, kargs)) fname = hex(id(str((strbits, l, cls, fname, order, flen, kargs)))) - # print fname if strbits is None: strbits = "" # "X"*l elif l is None: @@ -388,8 +384,6 @@ class bs(object): fmask |= 1 lmask = (1 << l) - 1 # gen conditional field - # if flen is None: - # flen = lambda mode, v:l if cls: for b in cls: if 'flen' in b.__dict__: @@ -429,7 +423,6 @@ class bs(object): # bsi added at end of list # used to use first function of added class bases += [bsi] - # new_c = type(c_name, tuple(bases), {}) k = c_name, tuple(bases) if k in self.all_new_c: new_c = self.all_new_c[k] @@ -485,7 +478,6 @@ class bsi(object): return True def encode(self): - # self.value = v&self.lmask return True def clone(self): @@ -507,7 +499,7 @@ class bsi(object): l = [self.strbits, self.l, self.cls, self.fname, self.order, self.lmask, self.fbits, self.fmask, self.value] # + kargs - # l = [self.value] + return hash(tuple(l)) @@ -567,9 +559,7 @@ class bs_mod_name(bs_divert): f = bs(**args) nfields[i] = f ndct = dict(dct) - # new_name = ndct['name'] + new_name ndct['name'] = self.modname(ndct['name'], value) - # ndct['name'] = new_name out.append((cls, new_name, bases, ndct, nfields)) return out @@ -584,7 +574,6 @@ class bs_cond(bsi): class bs_swapargs(bs_divert): def divert(self, i, candidates): - # print candidates out = [] for cls, name, bases, dct, fields in candidates: # args not permuted @@ -602,7 +591,6 @@ class bs_swapargs(bs_divert): a = ap.pop(0) b = ap.pop(0) ndct['args_permut'] = [b, a] + ap - # print ndct['args_permut'] # gen fix field f = gen_bsint(1, self.args['l'], self.args) nfields[i] = f @@ -728,7 +716,6 @@ def factor_one_bit(tree): if len(tree) == 1: return tree for k, v in tree.items(): - # print k, v if k == "mn": new_keys[k] = v continue @@ -742,7 +729,6 @@ def factor_one_bit(tree): nfbits = fbits & ((1 << (l - 1)) - 1) ck = 1, cfmask, cfbits, None, flen nk = l - 1, nfmask, nfbits, fname, flen - # print ck if nk in new_keys[ck]: raise NotImplementedError('not fully functional') new_keys[ck][nk] = v @@ -824,8 +810,6 @@ def graph_tree(tree): digraph G { """ for a, b in nodes: - # print a, id(a) - # print b, id(b) if b == 'mn': continue out += "%s -> %s;\n" % (id(a), id(b)) @@ -838,13 +822,7 @@ def add_candidate_to_tree(tree, c): for f in c.fields: if f.l == 0: continue - # print len(bits), f.l - # if f.flen: - # pass - # print f node = f.l, f.fmask, f.fbits, f.fname, f.flen - # node = f.strbits, f.l, f.cls, f.fname, f.order, f.lmask, f.fbits, - # f.fmask, f.value#, tuple(f.kargs.items()) if not node in branch: branch[node] = {} @@ -878,10 +856,8 @@ class metamn(type): if name == "cls_mn" or name.startswith('mn_'): return type.__new__(mcs, name, bases, dct) alias = dct.get('alias', False) - # fields = [bm_cond]+dct['fields'] + fields = bases[0].mod_fields(dct['fields']) - # print 'f1', dct['fields'] - # print 'f2', fields if not 'name' in dct: dct["name"] = bases[0].getmn(name) if 'args' in dct: @@ -901,9 +877,7 @@ class metamn(type): f_ordered.sort(key=lambda x: (x[1].prio, x[0])) candidates = bases[0].gen_modes(mcs, name, bases, dct, fields) for i, fc in f_ordered: - # print fc, isinstance(fc, bs_divert) if isinstance(fc, bs_divert): - # print 'iiii', fc candidates = fc.divert(i, candidates) for cls, name, bases, dct, fields in candidates: ndct = dict(dct) @@ -917,10 +891,6 @@ class metamn(type): bases[0].num += 1 bases[0].all_mn.append(c) mode = dct['mode'] - # print 'add mnemo', c.name, c.mode, len(bases[0].all_mn_mode[mode]) - # print fields - # if 'args_permut' in dct: - # print dct['args_permut'] bases[0].all_mn_mode[mode].append(c) bases[0].all_mn_name[c.name].append(c) i = c() @@ -935,10 +905,7 @@ class metamn(type): raise ValueError('f is not bsi') if f.l == 0: continue - # if f.fmask: o += f.strbits - # print o, len(o) - # fd return c @@ -957,10 +924,8 @@ class instruction(object): def __str__(self): o = "%-10s " % self.name args = [] - #args_str = self.args_str - #for arg, arg_str in zip(self.args, args_str): for i, arg in enumerate(self.args): - if not isinstance(arg, Expr): + if not isinstance(arg, m2_expr.Expr): raise ValueError('zarb arg type') x = self.arg2str(arg, pos = i) args.append(x) @@ -968,7 +933,7 @@ class instruction(object): return o def get_asm_offset(self, x): - return ExprInt_from(x, self.offset) + return m2_expr.ExprInt_from(x, self.offset) def resolve_args_with_symbols(self, symbols=None): if symbols is None: @@ -977,7 +942,7 @@ class instruction(object): for a in self.args: e = a # try to resolve symbols using symbols (0 for default value) - ids = get_expr_ids(e) + ids = m2_expr.get_expr_ids(e) fixed_ids = {} for x in ids: if isinstance(x.name, asmbloc.asm_label): @@ -994,20 +959,18 @@ class instruction(object): continue if symbols[name].offset is None: default_size = self.get_symbol_size(x, symbols) - value = ExprInt_fromsize(default_size, 0) # default value + # default value + value = m2_expr.ExprInt_fromsize(default_size, 0) else: size = x.size if size is None: default_size = self.get_symbol_size(x, symbols) size = default_size - value = ExprInt_fromsize(size, symbols[name].offset) + value = m2_expr.ExprInt_fromsize(size, symbols[name].offset) fixed_ids[x] = value e = e.replace_expr(fixed_ids) - # print 'replaced e', e, fixed_ids e = expr_simp(e) - # print 'replaced e simp', e, fixed_ids args_out.append(e) - # print "args out", [str(x) for x in args_out] return args_out def get_info(self, c): @@ -1033,39 +996,30 @@ class cls_mn(object): bs_l = bs.getlen() else: bs_l = len(bs) - # print fname_values for fname_values, branch, offset_b in todo: (l, fmask, fbits, fname, flen), vals = branch cpt += 1 - # print bvalo, 'len', l, fmask, fbits, fname, flen, 'TTT', bs_l * 8, offset_b, l + if flen is not None: - # print 'flen' l = flen(attrib, fname_values) - # print 'len', fname, l if l is not None: - # print fname, hex(bs_l), l - # print hex(offset_b) try: v = cls.getbits(bs, attrib, offset_b, l) except IOError: # Raised if offset is out of bound continue - # print 'TEST', bval, fname, offset_b, cpt, (l, fmask, fbits), - # hex(v), hex(v & fmask), hex(fbits), v & fmask == fbits offset_b += l if v & fmask != fbits: continue if fname is not None and not fname in fname_values: - # print "YY", fname_values, fname, bval fname_values[fname] = v - # print vals for nb, v in vals.items(): if 'mn' in nb: candidates.update(v) else: todo.append((dict(fname_values), (nb, v), offset_b)) - candidates = [c for c in candidates] # if c.attrib == attrib] + candidates = [c for c in candidates] if not candidates: raise Disasm_Exception('cannot disasm (guess) at %X' % offset) @@ -1074,17 +1028,12 @@ class cls_mn(object): def reset_class(self): for f in self.fields_order: if f.strbits and isbin(f.strbits): - # print 'a', f.value = int(f.strbits, 2) elif 'default_val' in f.kargs: - # print 'b', f.value = int(f.kargs['default_val'], 2) else: - # print 'c', f.value = None - # print "reset", f.fname, f.value if f.fname: - # print 'SET asm', f.fname setattr(self, f.fname, f) def init_class(self): @@ -1101,11 +1050,8 @@ class cls_mn(object): if isinstance(f, m_arg): args.append(f) - # print f, fc.fname if f.fname: - # print 'SET asm', f.fname setattr(self, f.fname, f) - # print args if hasattr(self, 'args_permut'): args = [args[self.args_permut[i]] for i in xrange(len(self.args_permut))] @@ -1145,18 +1091,13 @@ class cls_mn(object): def dis(cls, bs_o, mode_o = None, offset=0): if not isinstance(bs_o, bin_stream): bs_o = bin_stream_str(bs_o) - loggg = False - # bs_o == 'fg\x11\x90\x00\x00'#False#'\x48\x15\x44\x33\x22\x11'==bs_o - # print 'disfunc', repr(bs_o) + offset_o = offset - # print 'DIS', hex(offset), mode_o#repr(bs_o.bin) pre_dis_info, bs, mode, offset, prefix_len = cls.pre_dis( bs_o, mode_o, offset) candidates = cls.guess_mnemo(bs, mode, pre_dis_info, offset) - # print 'guess', repr(v), mode, prefix.rex_w out = [] out_c = [] - # print 'DIS CAND', len(candidates), mode if hasattr(bs, 'getlen'): bs_l = bs.getlen() else: @@ -1164,54 +1105,36 @@ class cls_mn(object): alias = False for c in candidates: - # print 'RRR' - if loggg: - print "*" * 40, mode, c.mode - print c.fields - # c.mode_o = mode_o - # off = c.parse_prefix(mode_o, v) - # bits = bin_stream(v)#[:c.mn_len/8]) - - # c = c() - # c.init_class() + log.debug("*" * 40, mode, c.mode) + log.debug(c.fields) + c = cls.all_mn_inst[c][0] - # c.init_class() + c.reset_class() c.mode = mode - # for f in c.fields_order: print f.is_present - if not c.add_pre_dis_info(pre_dis_info): # = prefix#cls.mnprefix() - continue - # print "zz", c.rex_w.value - """ - if prefix.opmode != c.mp[1]: + if not c.add_pre_dis_info(pre_dis_info): continue - if prefix.admode != c.mp[2]: - continue - """ args = [] todo = {} getok = True fname_values = dict(pre_dis_info) offset_b = offset * 8 - # print pre_dis_info + total_l = 0 for i, f in enumerate(c.fields_order): - # print 'XX', i, f, id(f) - # print 'ZZ', c.rex_x.value if f.flen is not None: l = f.flen(mode, fname_values) else: l = f.l - # print 'len', l - # print "zz", c.rex_w, c.rex_w.value if l is not None: total_l += l f.l = l f.is_present = True - if loggg: - print "FIELD", f.__class__, f.fname, offset_b, l + log.debug("FIELD %s %s %s %s" % (f.__class__, + f.fname, + offset_b, l)) if bs_l * 8 - offset_b < l: getok = False break @@ -1224,19 +1147,12 @@ class cls_mn(object): f.is_present = False todo[i] = None - # print "decode", id(f), f.fname, - # print "l", l, "off", offset_b, "v", todo[i] - # print "zzz", c.rex_w, c.rex_w.value - if not getok: continue - # print 'PRIOdec', [(x[0], x[1].order) for x in c.to_decode] for i in c.to_decode: f = c.fields_order[i] if f.is_present: - # print "zz", f.fname, f.is_present, c.rex_w.value, - # c.rex_b.value, c.rex_x.value ret = f.decode(todo[i]) if not ret: log.debug("cannot decode %r" % (f)) @@ -1246,7 +1162,7 @@ class cls_mn(object): continue for a in c.args: a.expr = expr_simp(a.expr) - # print offset, offset_o, total_l + c.l = prefix_len + total_l / 8 c.b = cls.getbytes(bs, offset, total_l / 8) c.offset = offset_o @@ -1260,7 +1176,6 @@ class cls_mn(object): instr.b = cls.getbytes(bs, offset, total_l / 8) instr.offset = offset_o instr.get_info(c) - # instr = c.post_dis() if c.alias: alias = True out.append(instr) @@ -1276,10 +1191,6 @@ class cls_mn(object): if o.alias: return out[i] raise NotImplementedError('not fully functional') - # for xx in out: - # print xx - # if xx.name == "ADC": - # pass return out[0] @classmethod @@ -1289,25 +1200,15 @@ class cls_mn(object): if not name: raise ValueError('cannot find name', s) name = name[0] - # print "mnemo_name", name + if not name in cls.all_mn_name: raise ValueError('unknown name', name) - clist = [x for x in cls.all_mn_name[name]] # if x.mode == mode] + clist = [x for x in cls.all_mn_name[name]] out = [] out_args = [] parsers = defaultdict(dict) - # print 'ASM CAND', len(clist), name for cc in clist: - #""" - # c = cc() - # c.init_class() - #""" - """ - c = cls.all_mn_inst[cc][0] - c.reset_class() - c.mode = mode - """ for c in cls.get_cls_instance(cc, mode): args_expr = [] args_str = s[len(name):].strip(' ') @@ -1318,7 +1219,6 @@ class cls_mn(object): for i, f in enumerate(c.args): start_i = len_o - len(args_str) - # print i, "will parse", repr(args_str) if type(f.parser) == tuple: parser = f.parser else: @@ -1328,9 +1228,7 @@ class cls_mn(object): continue try: total_scans += 1 - # print type(p) v, start, stop = p.scanString(args_str).next() - # print "pp", args_str, v, start, stop except StopIteration: v, start, stop = [None], None, None if start != 0: @@ -1338,16 +1236,12 @@ class cls_mn(object): parsers[(i, start_i)][p] = v[0], start, stop start, stop = f.fromstring(args_str, parsers[(i, start_i)]) - # print args_str, start, stop#, f.expr - # if start is not None: print f.expr if start != 0: log.debug("cannot fromstring %r" % (args_str)) cannot_parse = True - # print "cannot_parse1" break if f.expr is None: raise NotImplementedError('not fully functional') - # print "f expr", repr(f.expr) f.expr = expr_simp(f.expr) args_expr.append(f.expr) a = args_str[start:stop] @@ -1356,21 +1250,10 @@ class cls_mn(object): args_str = args_str[1:] args_str = args_str.strip(' ') if args_str: - # print "cannot_parse", repr(args_str) - cannot_parse = True - if cannot_parse: - continue - # print [x for x in c.args] - # print [str(x) for x in c.args] - """ - try: - c.value() - except Exception, e: - log.debug("cannot encode %r\n%s"%(e, traceback.format_exc())) cannot_parse = True if cannot_parse: continue - """ + out.append(c) out_args.append(args_expr) break @@ -1384,21 +1267,6 @@ class cls_mn(object): instr = cls.instruction(c.name, mode, c_args, additional_info=c.additional_info()) - # instruction(name, attrib, args, args_str, additional_info): - # c = c() - # c.init_class() - # re parse instruction - """ - args_str = s[len(name):].strip(' ') - for i, f in enumerate(c.args): - if isinstance(f, m_arg): - start, stop = f.fromstring(args_str) - args_str = args_str[stop:].strip(' ') - if args_str.startswith(','): - args_str = args_str[1:] - args_str = args_str.strip(' ') - """ - return instr def dup_info(self, infos): @@ -1417,71 +1285,29 @@ class cls_mn(object): @classmethod def asm(cls, instr, symbols=None): - # t = time.time() """ Re asm instruction by searching mnemo using name and args. We then can modify args and get the hex of a modified instruction """ clist = cls.all_mn_name[instr.name] - clist = [x for x in clist] # if x.mode == instr.mode] - # print 'ASM CAN', len(clist) + clist = [x for x in clist] vals = [] candidates = [] - # print "resolve" args = instr.resolve_args_with_symbols(symbols) - # print "ok", [str(x) for x in args] - """ - args = [] - for i, f in enumerate(cls.args): - e = f.expr - # try to resolve symbols using symbols (0 for default value) - if symbols: - #print 'origine', e - ids = get_expr_ids(e) - fixed_ids = {} - for x in ids: - if not x.name in symbols: - #print 'not IN', x - continue - if symbols[x.name].offset is None: - value = ExprInt32(0) # default value - else: - value = ExprInt_fromsize(x.size, symbols[x.name].offset) - fixed_ids[x] = value - e = e.replace_expr(fixed_ids) - #print 'replaced e', e, fixed_ids - e = expr_simp(e) - #print 'replaced e simp', e, fixed_ids - args.append(e) - """ + for cc in clist: - # if cc.mode != cls.mode: - # continue - """ - c = c() - c.init_class() - """ + for c in cls.get_cls_instance( cc, instr.mode, instr.additional_info): - # c = cls.all_mn_inst[cc][0] - # c = cc() - # c.init_class() - cannot_parse = False if len(c.args) != len(instr.args): continue - # print c.mode, c.mp, c.fields[6:] - # print "eee", c.fields - # print [str(x.expr) for x in cls.args] + # only fix args expr for i in xrange(len(c.args)): c.args[i].expr = args[i] - # print 'ARGS', [str(x) for x in args] - # for a in c.args: - # print a.expr, - # print - # print instr.mode + v = c.value(instr.mode) if not v: log.debug("cannot encode %r" % (c)) @@ -1495,18 +1321,8 @@ class cls_mn(object): (instr.name, [str(x) for x in instr.args])) if len(vals) != 1: log.debug('asm multiple args ret default') - # raise ValueError("cannot parse %r (%d cand)"%(s, len(out))) - """ - for x in out: - print repr(x.value()) - print [str(a.expr) for a in x.args] - """ - vals = cls.filter_asm_candidates(instr, candidates) - # vals = list(set(vals)) - # vals.sort(key=lambda x:len(x)) - # dt = time.time() - t - # print 'TIME', dt, str(cls) + vals = cls.filter_asm_candidates(instr, candidates) return vals @classmethod @@ -1518,36 +1334,25 @@ class cls_mn(object): return o def value(self, mode): - # print 'PRIOenc', [(x, self.fields_order[x].order) for x in - # self.to_decode[::-1]] todo = [(0, [(x, self.fields_order[x]) for x in self.to_decode[::-1]])] - # print todo + result = [] done = [] cpt = 0 - # print 'VALUE'#, self.fields[6:] while todo: index, to_decode = todo.pop() # TEST XXX for i, f in to_decode: setattr(self, f.fname, f) - # print 'todo:', len(todo), index, to_decode - # print "OOOOOOO" - # if (index, hash(tuple(to_decode))) in done: if (index, [x[1].value for x in to_decode]) in done: - # print 'skip', to_decode continue done.append((index, [x[1].value for x in to_decode])) - # done.append((index, to_decode)) cpt += 1 can_encode = True for i, f in to_decode[index:]: - # print 'before', f.value, repr(f) ret = f.encode() - # print 'encode', len(todo), index, f.fname, f.value, f.l, ret - # print 'ret', ret if not ret: log.debug('cannot encode %r' % f) can_encode = False @@ -1556,7 +1361,6 @@ class cls_mn(object): if ret is True: continue - # print ret, index gcpt = 0 for i in ret: gcpt += 1 @@ -1570,13 +1374,12 @@ class cls_mn(object): o.append((p, fnew)) todo.append((index, o)) can_encode = False - # print 'gcpt', gcpt + break if not can_encode: continue result.append(to_decode) - # print 'CPT', cpt - # print "HEX", len(result), result + return self.decoded2bytes(result) def encodefields(self, decoded): @@ -1587,8 +1390,7 @@ class cls_mn(object): if f.value is None: continue bits.putbits(f.value, f.l) - # if f.l: - # print f.l, hex(f.value), len(bits.bits), bits.bits + xx = bits.tostring() return bits.tostring() @@ -1599,7 +1401,7 @@ class cls_mn(object): out = [] for decoded in result: decoded.sort() - # print [f.value for p, f in decoded] + o = self.encodefields(decoded) if o is None: continue @@ -1615,7 +1417,8 @@ class cls_mn(object): args = [] for arg in self.args: # XXX todo test - if not (isinstance(arg, Expr) or isinstance(arg.expr, Expr)): + if not (isinstance(arg, m2_expr.Expr) or + isinstance(arg.expr, m2_expr.Expr)): raise ValueError('zarb arg type') x = str(arg) args.append(x) @@ -1626,7 +1429,8 @@ class cls_mn(object): args = [] for arg in self.args: # XXX todo test - if not (isinstance(arg, Expr) or isinstance(arg.expr, Expr)): + if not (isinstance(arg, m2_expr.Expr) or + isinstance(arg.expr, m2_expr.Expr)): raise ValueError('zarb arg type') x = str(arg) args.append(x) @@ -1641,10 +1445,10 @@ class cls_mn(object): dst = self.getdstflow(symbol_pool) args = [] for d in dst: - if isinstance(d, ExprInt): + if isinstance(d, m2_expr.ExprInt): l = symbol_pool.getby_offset_create(int(d.arg)) - # print l - a = ExprId(l.name, d.size) + + a = m2_expr.ExprId(l.name, d.size) else: a = d args.append(a) @@ -1655,21 +1459,18 @@ class cls_mn(object): class imm_noarg(object): - # parser = str_int intsize = 32 intmask = (1 << intsize) - 1 - # expr2int = lambda self,x:int(self.expr.arg&self.lmask) def int2expr(self, v): if (v & ~self.intmask) != 0: return None - return ExprInt_fromsize(self.intsize, v) + return m2_expr.ExprInt_fromsize(self.intsize, v) def expr2int(self, e): - if not isinstance(e, ExprInt): + if not isinstance(e, m2_expr.ExprInt): return None v = int(e.arg) - # print "testimm2", hex(v), hex(self.intmask) if v & ~self.intmask != 0: return None return v @@ -1684,11 +1485,11 @@ class imm_noarg(object): return None, None if e is None: return None, None - # print 'fromstring', hex(e), self.int2expr - assert(isinstance(e, Expr)) + + assert(isinstance(e, m2_expr.Expr)) if isinstance(e, tuple): self.expr = self.int2expr(e[1]) - elif isinstance(e, Expr): + elif isinstance(e, m2_expr.Expr): self.expr = e else: raise TypeError('zarb expr') @@ -1726,19 +1527,19 @@ class imm_noarg(object): class imm08_noarg(object): - int2expr = lambda self, x: ExprInt08(x) + int2expr = lambda self, x: m2_expr.ExprInt08(x) class imm16_noarg(object): - int2expr = lambda self, x: ExprInt16(x) + int2expr = lambda self, x: m2_expr.ExprInt16(x) class imm32_noarg(object): - int2expr = lambda self, x: ExprInt32(x) + int2expr = lambda self, x: m2_expr.ExprInt32(x) class imm64_noarg(object): - int2expr = lambda self, x: ExprInt64(x) + int2expr = lambda self, x: m2_expr.ExprInt64(x) class int32_noarg(imm_noarg): @@ -1752,7 +1553,7 @@ class int32_noarg(imm_noarg): return True def encode(self): - if not isinstance(self.expr, ExprInt): + if not isinstance(self.expr, m2_expr.ExprInt): return False v = int(self.expr.arg) if sign_ext(v & self.lmask, self.l, self.intsize) != v: diff --git a/miasm2/core/interval.py b/miasm2/core/interval.py index cd2a793e..d76cbd15 100644 --- a/miasm2/core/interval.py +++ b/miasm2/core/interval.py @@ -1,59 +1,62 @@ -INT_EQ = 0 -INT_B_IN_A = 1 -INT_A_IN_B = -1 -INT_DISJOIN = 2 -INT_JOIN = 3 -INT_JOIN_AB = 4 -INT_JOIN_BA = 5 - -# 0 => eq -# 1 => b in a -# -1 => a in b -# 2 => disjoin -# 3 => join -# 4 => join a,b touch -# 5 => join b,a touch - - -def cmp_interval(a, b): - if a == b: +INT_EQ = 0 # Equivalent +INT_B_IN_A = 1 # B in A +INT_A_IN_B = -1 # A in B +INT_DISJOIN = 2 # Disjoint +INT_JOIN = 3 # Overlap +INT_JOIN_AB = 4 # B starts at the end of A +INT_JOIN_BA = 5 # A starts at the end of B + + +def cmp_interval(inter1, inter2): + """Compare @inter1 and @inter2 and returns the associated INT_* case + @inter1, @inter2: interval instance + """ + if inter1 == inter2: return INT_EQ - a1, a2 = a - b1, b2 = b - if a1 <= b1 and a2 >= b2: - return INT_B_IN_A - if b1 <= a1 and b2 >= a2: - return INT_A_IN_B - if a2 + 1 == b1: - return INT_JOIN_AB - if b2 + 1 == a1: - return INT_JOIN_BA - if a1 > b2 + 1 or b1 > a2 + 1: - return INT_DISJOIN - return INT_JOIN - -# interval is: [a, b] - - -class interval: - - def __init__(self, a=None): - if a is None: - a = [] - if isinstance(a, interval): - a = a.intervals + + inter1_start, inter1_stop = inter1 + inter2_start, inter2_stop = inter2 + result = INT_JOIN + if inter1_start <= inter2_start and inter1_stop >= inter2_stop: + result = INT_B_IN_A + if inter2_start <= inter1_start and inter2_stop >= inter1_stop: + result = INT_A_IN_B + if inter1_stop + 1 == inter2_start: + result = INT_JOIN_AB + if inter2_stop + 1 == inter1_start: + result = INT_JOIN_BA + if inter1_start > inter2_stop + 1 or inter2_start > inter1_stop + 1: + result = INT_DISJOIN + return result + + +class interval(object): + """Stands for intervals with integer bounds + + Offers common methods to work with interval""" + + def __init__(self, bounds=None): + """Instance an interval object + @bounds: (optional) list of (int, int) and/or interval instance + """ + if bounds is None: + bounds = [] + elif isinstance(bounds, interval): + bounds = bounds.intervals self.is_cannon = False - self.intervals = a + self.intervals = bounds self.cannon() def __iter__(self): - for x in self.intervals: - yield x + """Iterate on intervals""" + for inter in self.intervals: + yield inter - @classmethod - def cannon_list(cls, tmp): + @staticmethod + def cannon_list(tmp): """ Return a cannonizes list of intervals + @tmp: list of (int, int) """ tmp = sorted([x for x in tmp if x[0] <= x[1]]) out = [] @@ -63,7 +66,7 @@ class interval: while tmp: x = tmp.pop() rez = cmp_interval(out[-1], x) - # print out[-1], x, rez + if rez == INT_EQ: continue elif rez == INT_DISJOIN: @@ -83,6 +86,7 @@ class interval: return out[::-1] def cannon(self): + "Apply .cannon_list() on self contained intervals" if self.is_cannon is True: return self.intervals = interval.cannon_list(self.intervals) @@ -130,12 +134,12 @@ class interval: i += 1 x = to_test[i] if x[0] > x[1]: - del(to_test[i]) + del to_test[i] i -= 1 continue while to_del and to_del[0][1] < x[0]: - del(to_del[0]) + del to_del[0] for y in to_del: if y[0] > x[1]: @@ -144,15 +148,15 @@ class interval: if rez == INT_DISJOIN: continue elif rez == INT_EQ: - del(to_test[i]) + del to_test[i] i -= 1 break elif rez == INT_A_IN_B: - del(to_test[i]) + del to_test[i] i -= 1 break elif rez == INT_B_IN_A: - del(to_test[i]) + del to_test[i] i1 = (x[0], y[0] - 1) i2 = (y[1] + 1, x[1]) to_test[i:i] = [i1, i2] @@ -161,7 +165,7 @@ class interval: elif rez in [INT_JOIN_AB, INT_JOIN_BA]: continue elif rez == INT_JOIN: - del(to_test[i]) + del to_test[i] if x[0] < y[0]: to_test[i:i] = [(x[0], y[0] - 1)] else: @@ -175,13 +179,11 @@ class interval: def __and__(self, v): out = [] for x in self.intervals: - # print "x", x if x[0] > x[1]: continue for y in v.intervals: - # print 'y', y rez = cmp_interval(x, y) - # print x, y, rez + if rez == INT_DISJOIN: continue elif rez == INT_EQ: @@ -208,13 +210,14 @@ class interval: return interval(out) def hull(self): + "Return the first and the last bounds of intervals" if not self.intervals: return None, None return self.intervals[0][0], self.intervals[-1][1] def show(self, img_x=1350, img_y=20, dry_run=False): """ - show image representing the itnerval + show image representing the interval """ try: import Image @@ -229,8 +232,7 @@ class interval: print hex(i_min), hex(i_max) - def addr2x(addr): - return (addr - i_min) * img_x / (i_max - i_min) + addr2x = lambda addr: (addr - i_min) * img_x / (i_max - i_min) for a, b in self.intervals: draw.rectangle((addr2x(a), 0, addr2x(b), img_y), (200, 0, 0)) diff --git a/miasm2/core/parse_asm.py b/miasm2/core/parse_asm.py index dba097fa..09003ed9 100644 --- a/miasm2/core/parse_asm.py +++ b/miasm2/core/parse_asm.py @@ -1,11 +1,11 @@ #!/usr/bin/env python #-*- coding:utf-8 -*- - import re + import miasm2.expression.expression as m2_expr -from miasm2.core.asmbloc import * -from miasm2.core.utils import pck +import miasm2.core.asmbloc as asmbloc from miasm2.core.cpu import gen_base_expr, parse_ast + declarator = {'byte': 8, 'word': 16, 'dword': 32, @@ -33,12 +33,15 @@ def guess_next_new_label(symbol_pool, gen_label_index=0): def parse_txt(mnemo, attrib, txt, symbol_pool=None, gen_label_index=0): if symbol_pool is None: - symbol_pool = asm_symbol_pool() + symbol_pool = asmbloc.asm_symbol_pool() lines_text = [] lines_data = [] lines_bss = [] + C_NEXT = asmbloc.asm_constraint.c_next + C_TO = asmbloc.asm_constraint.c_to + lines = lines_text # parse each line for line in txt.split('\n'): @@ -79,36 +82,36 @@ def parse_txt(mnemo, attrib, txt, symbol_pool=None, gen_label_index=0): raw = raw.decode('string_escape') if directive == 'string': raw += "\x00" - lines.append(asm_raw(raw)) + lines.append(asmbloc.asm_raw(raw)) continue if directive == 'ustring': # XXX HACK line = line.replace(r'\n', '\n').replace(r'\r', '\r') raw = line[line.find(r'"') + 1:line.rfind(r"'")] + "\x00" raw = raw.decode('string_escape') - raw = "".join(map(lambda x: x + '\x00', raw)) - lines.append(asm_raw(raw)) + raw = "".join([string + '\x00' for string in raw]) + lines.append(asmbloc.asm_raw(raw)) continue if directive in declarator: data_raw = line[r.end():].split(' ', 1)[1] data_raw = data_raw.split(',') size = declarator[directive] data_int = [] - has_symb = False # parser - variable, operand, base_expr = gen_base_expr() - my_var_parser = parse_ast(lambda x:m2_expr.ExprId(x, size), - lambda x:m2_expr.ExprInt_fromsize(size, x)) + base_expr = gen_base_expr()[2] + my_var_parser = parse_ast(lambda x: m2_expr.ExprId(x, size), + lambda x: + m2_expr.ExprInt_fromsize(size, x)) base_expr.setParseAction(my_var_parser) for b in data_raw: b = b.strip() x = base_expr.parseString(b)[0] data_int.append(x.canonize()) - p = size2pck[size] + raw = data_int - x = asm_raw(raw) + x = asmbloc.asm_raw(raw) x.element_size = size lines.append(x) continue @@ -116,12 +119,12 @@ def parse_txt(mnemo, attrib, txt, symbol_pool=None, gen_label_index=0): # TODO continue if directive == 'split': # custom command - x = asm_raw() + x = asmbloc.asm_raw() x.split = True lines.append(x) continue if directive == 'dontsplit': # custom command - lines.append(asm_raw(line.strip())) + lines.append(asmbloc.asm_raw(line.strip())) continue if directive in ['file', 'intel_syntax', 'globl', 'local', 'type', 'size', 'align', 'ident', 'section']: @@ -148,12 +151,12 @@ def parse_txt(mnemo, attrib, txt, symbol_pool=None, gen_label_index=0): instr.dstflow2label(symbol_pool) lines.append(instr) - log_asmbloc.info("___pre asm oki___") + asmbloc.log_asmbloc.info("___pre asm oki___") # make blocs - # gen_label_index = 0 blocs_sections = [] bloc_num = 0 + b = None for lines in [lines_text, lines_data, lines_bss]: state = 0 i = 0 @@ -162,81 +165,58 @@ def parse_txt(mnemo, attrib, txt, symbol_pool=None, gen_label_index=0): bloc_to_nlink = None block_may_link = False while i < len(lines): - # print 'DEAL', lines[i], state # no current bloc if state == 0: - if not isinstance(lines[i], asm_label): + if not isinstance(lines[i], asmbloc.asm_label): l = guess_next_new_label(symbol_pool) lines[i:i] = [l] else: l = lines[i] - b = asm_bloc(l) + b = asmbloc.asm_bloc(l) b.bloc_num = bloc_num bloc_num += 1 blocs.append(b) state = 1 i += 1 if bloc_to_nlink: - # print 'nlink!' - bloc_to_nlink.addto( - asm_constraint(b.label, asm_constraint.c_next)) + bloc_to_nlink.addto(asmbloc.asm_constraint(b.label, + C_NEXT)) bloc_to_nlink = None # in bloc elif state == 1: - # asm_raw - if isinstance(lines[i], asm_raw): + if isinstance(lines[i], asmbloc.asm_raw): if hasattr(lines[i], 'split'): state = 0 block_may_link = False i += 1 - else: #if lines[i].raw.startswith('.dontsplit'): - # raw asm are link by default - # print 'dontsplit' + else: state = 1 block_may_link = True b.addline(lines[i]) i += 1 - """ - else: - b.addline(lines[i]) - i += 1 - """ - # asm_label - elif isinstance(lines[i], asm_label): + # asmbloc.asm_label + elif isinstance(lines[i], asmbloc.asm_label): if block_may_link: - # print 'nlink!' b.addto( - asm_constraint(lines[i], asm_constraint.c_next)) + asmbloc.asm_constraint(lines[i], C_NEXT)) block_may_link = False state = 0 # instruction else: b.addline(lines[i]) if lines[i].dstflow(): - ''' - mydst = lines[i].args - if len(mydst)==1 and mnemo.get_symbols(mydst[0]): - arg = dict(mydst[0]) - symbs = mnemo.get_symbols(arg) - """ - TODO XXX redo this (as many miasm parts) - """ - l = symbs[0][0] - lines[i].setdstflow([l]) - b.addto(asm_constraint(l, asm_constraint.c_to)) - ''' for x in lines[i].getdstflow(symbol_pool): if not isinstance(x, m2_expr.ExprId): continue if x in mnemo.regs.all_regs_ids: continue - b.addto(asm_constraint(x, asm_constraint.c_to)) + b.addto(asmbloc.asm_constraint(x, C_TO)) # TODO XXX redo this really if not lines[i].breakflow() and i + 1 < len(lines): - if isinstance(lines[i + 1], asm_label): + if isinstance(lines[i + 1], asmbloc.asm_label): l = lines[i + 1] else: l = guess_next_new_label(symbol_pool) @@ -253,7 +233,7 @@ def parse_txt(mnemo, attrib, txt, symbol_pool=None, gen_label_index=0): i += 1 - for b in blocs_sections[0]: - log_asmbloc.info(b) + for block in blocs_sections[0]: + asmbloc.log_asmbloc.info(block) return blocs_sections, symbol_pool diff --git a/miasm2/core/utils.py b/miasm2/core/utils.py index 360deb8d..b2ddff2b 100644 --- a/miasm2/core/utils.py +++ b/miasm2/core/utils.py @@ -27,10 +27,10 @@ def hexdump(src, length=16): lines = [] for c in xrange(0, len(src), length): chars = src[c:c + length] - hex = ' '.join(["%02x" % ord(x) for x in chars]) + hexa = ' '.join(["%02x" % ord(x) for x in chars]) printable = ''.join( ["%s" % ((ord(x) <= 127 and FILTER[ord(x)]) or '.') for x in chars]) - lines.append("%04x %-*s %s\n" % (c, length * 3, hex, printable)) + lines.append("%04x %-*s %s\n" % (c, length * 3, hexa, printable)) print ''.join(lines) # stackoverflow.com/questions/2912231 |