diff options
| -rw-r--r-- | miasm/arch/aarch64/arch.py | 28 | ||||
| -rw-r--r-- | miasm/arch/aarch64/sem.py | 12 | ||||
| -rw-r--r-- | miasm/arch/arm/arch.py | 16 | ||||
| -rw-r--r-- | miasm/arch/msp430/arch.py | 2 | ||||
| -rw-r--r-- | miasm/arch/ppc/arch.py | 22 | ||||
| -rw-r--r-- | miasm/arch/x86/arch.py | 2 | ||||
| -rw-r--r-- | miasm/arch/x86/sem.py | 6 | ||||
| -rw-r--r-- | miasm/core/asmblock.py | 6 | ||||
| -rw-r--r-- | miasm/core/cpu.py | 12 | ||||
| -rw-r--r-- | miasm/core/objc.py | 5 | ||||
| -rw-r--r-- | miasm/core/parse_asm.py | 4 | ||||
| -rw-r--r-- | miasm/expression/expression.py | 26 | ||||
| -rw-r--r-- | miasm/expression/simplifications_common.py | 55 | ||||
| -rw-r--r-- | miasm/ir/ir.py | 24 | ||||
| -rw-r--r-- | miasm/ir/translators/C.py | 7 | ||||
| -rw-r--r-- | miasm/jitter/codegen.py | 8 | ||||
| -rw-r--r-- | miasm/jitter/emulatedsymbexec.py | 8 | ||||
| -rwxr-xr-x | test/arch/msp430/sem.py | 6 | ||||
| -rwxr-xr-x | test/arch/x86/sem.py | 6 |
19 files changed, 152 insertions, 103 deletions
diff --git a/miasm/arch/aarch64/arch.py b/miasm/arch/aarch64/arch.py index 10e94517..464d7eff 100644 --- a/miasm/arch/aarch64/arch.py +++ b/miasm/arch/aarch64/arch.py @@ -330,19 +330,19 @@ class instruction_aarch64(instruction): op_str = expr.op return "%s %s %s" % (expr.args[0], op_str, expr.args[1]) elif isinstance(expr, m2_expr.ExprOp) and expr.op == "postinc": - if expr.args[1].arg != 0: + if int(expr.args[1]) != 0: return "[%s], %s" % (expr.args[0], expr.args[1]) else: return "[%s]" % (expr.args[0]) elif isinstance(expr, m2_expr.ExprOp) and expr.op == "preinc_wb": - if expr.args[1].arg != 0: + if int(expr.args[1]) != 0: return "[%s, %s]!" % (expr.args[0], expr.args[1]) else: return "[%s]" % (expr.args[0]) elif isinstance(expr, m2_expr.ExprOp) and expr.op == "preinc": if len(expr.args) == 1: return "[%s]" % (expr.args[0]) - elif not isinstance(expr.args[1], m2_expr.ExprInt) or expr.args[1].arg != 0: + elif not isinstance(expr.args[1], m2_expr.ExprInt) or int(expr.args[1]) != 0: return "[%s, %s]" % (expr.args[0], expr.args[1]) else: return "[%s]" % (expr.args[0]) @@ -350,7 +350,7 @@ class instruction_aarch64(instruction): arg = expr.args[1] if isinstance(arg, m2_expr.ExprId): arg = str(arg) - elif arg.op == 'LSL' and arg.args[1].arg == 0: + elif arg.op == 'LSL' and int(arg.args[1]) == 0: arg = str(arg.args[0]) else: arg = "%s %s %s" % (arg.args[0], arg.op, arg.args[1]) @@ -375,7 +375,7 @@ class instruction_aarch64(instruction): expr = self.args[index] if not expr.is_int(): return - addr = expr.arg + self.offset + addr = (int(expr) + self.offset) & 0xFFFFFFFFFFFFFFFF loc_key = loc_db.get_or_create_offset_location(addr) self.args[index] = m2_expr.ExprLoc(loc_key, expr.size) @@ -403,7 +403,7 @@ class instruction_aarch64(instruction): if not isinstance(e, m2_expr.ExprInt): log.debug('dyn dst %r', e) return - off = e.arg - self.offset + off = (int(e) + 0x10000000000000000 - self.offset) & 0xFFFFFFFFFFFFFFFF if int(off % 4): raise ValueError('strange offset! %r' % off) self.args[index] = m2_expr.ExprInt(int(off), 64) @@ -643,7 +643,7 @@ class aarch64_gpreg0(bsi, aarch64_arg): def encode(self): if isinstance(self.expr, m2_expr.ExprInt): - if self.expr.arg == 0: + if int(self.expr) == 0: self.value = 0x1F return True return False @@ -793,7 +793,7 @@ def set_imm_to_size(size, expr): if size > expr.size: expr = m2_expr.ExprInt(int(expr), size) else: - if expr.arg > (1 << size) - 1: + if int(expr) > (1 << size) - 1: return None expr = m2_expr.ExprInt(int(expr), size) return expr @@ -954,11 +954,11 @@ class aarch64_gpreg_ext2(reg_noarg, aarch64_arg): if arg1.op not in EXT2_OP_INV: return False self.parent.option.value = EXT2_OP_INV[arg1.op] - if arg1.args[1].arg == 0: + if int(arg1.args[1]) == 0: self.parent.shift.value = 0 return True - if arg1.args[1].arg != self.get_size(): + if int(arg1.args[1]) != self.get_size(): return False self.parent.shift.value = 1 @@ -1273,7 +1273,7 @@ class aarch64_imm_nsr(aarch64_imm_sf, aarch64_arg): return False if not test_set_sf(self.parent, self.expr.size): return False - value = self.expr.arg + value = int(self.expr) if value == 0: return False @@ -1376,7 +1376,7 @@ class aarch64_imm_hw_sc(aarch64_arg): def encode(self): if isinstance(self.expr, m2_expr.ExprInt): - if self.expr.arg > 0xFFFF: + if int(self.expr) > 0xFFFF: return False self.value = int(self.expr) self.parent.hw.value = 0 @@ -1498,7 +1498,7 @@ class aarch64_deref(aarch64_arg): def decode(self, v): reg = gpregs64_info.expr[v] - off = self.parent.imm.expr.arg + off = int(self.parent.imm.expr) op = self.get_postpre(self.parent) off = self.decode_w_size(off) self.expr = m2_expr.ExprOp(op, reg, m2_expr.ExprInt(off, 64)) @@ -1568,7 +1568,7 @@ class aarch64_deref_nooff(aarch64_deref): reg, off = expr.args if not isinstance(off, m2_expr.ExprInt): return False - if off.arg != 0: + if int(off) != 0: return False else: return False diff --git a/miasm/arch/aarch64/sem.py b/miasm/arch/aarch64/sem.py index e9088bde..2761aed4 100644 --- a/miasm/arch/aarch64/sem.py +++ b/miasm/arch/aarch64/sem.py @@ -401,7 +401,7 @@ def movk(ir, instr, arg1, arg2): assert(arg2.op == 'slice_at' and isinstance(arg2.args[0], ExprInt) and isinstance(arg2.args[1], ExprInt)) - value, shift = int(arg2.args[0].arg), int(arg2.args[1]) + value, shift = int(arg2.args[0]), int(arg2.args[1]) e.append( ExprAssign(arg1[shift:shift + 16], ExprInt(value, 16))) else: @@ -434,7 +434,7 @@ def csel(arg1, arg2, arg3, arg4): def ccmp(ir, instr, arg1, arg2, arg3, arg4): e = [] if(arg2.is_int()): - arg2=ExprInt(arg2.arg.arg,arg1.size) + arg2=ExprInt(int(arg2),arg1.size) default_nf = arg3[0:1] default_zf = arg3[1:2] default_cf = arg3[2:3] @@ -697,7 +697,7 @@ def ldp(ir, instr, arg1, arg2, arg3): def sbfm(ir, instr, arg1, arg2, arg3, arg4): e = [] - rim, sim = int(arg3.arg), int(arg4) + 1 + rim, sim = int(arg3), int(arg4) + 1 if sim > rim: res = arg2[rim:sim].signExtend(arg1.size) else: @@ -709,7 +709,7 @@ def sbfm(ir, instr, arg1, arg2, arg3, arg4): def ubfm(ir, instr, arg1, arg2, arg3, arg4): e = [] - rim, sim = int(arg3.arg), int(arg4) + 1 + rim, sim = int(arg3), int(arg4) + 1 if sim != arg1.size - 1 and rim == sim: # Simple case: lsl value = int(rim) @@ -733,7 +733,7 @@ def ubfm(ir, instr, arg1, arg2, arg3, arg4): def bfm(ir, instr, arg1, arg2, arg3, arg4): e = [] - rim, sim = int(arg3.arg), int(arg4) + 1 + rim, sim = int(arg3), int(arg4) + 1 if sim > rim: res = arg2[rim:sim] e.append(ExprAssign(arg1[:sim-rim], res)) @@ -1038,7 +1038,7 @@ def rev16(ir, instr, arg1, arg2): @sbuild.parse def extr(arg1, arg2, arg3, arg4): compose = ExprCompose(arg2, arg3) - arg1 = compose[int(arg4.arg):int(arg4)+arg1.size] + arg1 = compose[int(arg4):int(arg4)+arg1.size] @sbuild.parse diff --git a/miasm/arch/arm/arch.py b/miasm/arch/arm/arch.py index fc6a0527..4aac13c6 100644 --- a/miasm/arch/arm/arch.py +++ b/miasm/arch/arm/arch.py @@ -437,9 +437,9 @@ class instruction_arm(instruction): if not isinstance(expr, ExprInt): return if self.name == 'BLX': - addr = expr.arg + self.offset + addr = (expr.arg + self.offset) & 0xFFFFFFFF else: - addr = expr.arg + self.offset + addr = (expr.arg + self.offset) & 0xFFFFFFFF loc_key = loc_db.get_or_create_offset_location(addr) self.args[0] = ExprLoc(loc_key, expr.size) @@ -481,7 +481,7 @@ class instruction_arm(instruction): if not isinstance(e, ExprInt): log.debug('dyn dst %r', e) return - off = e.arg - self.offset + off = (e.arg + 0x100000000 - self.offset) & 0xFFFFFFFF if int(off % 4): raise ValueError('strange offset! %r' % off) self.args[0] = ExprInt(off, 32) @@ -516,13 +516,13 @@ class instruction_armt(instruction_arm): if self.name == 'BLX': addr = expr.arg + (self.offset & 0xfffffffc) elif self.name == 'BL': - addr = expr.arg + self.offset + addr = (expr.arg + self.offset) & 0xFFFFFFFF elif self.name.startswith('BP'): - addr = expr.arg + self.offset + addr = (expr.arg + self.offset) & 0xFFFFFFFF elif self.name.startswith('CB'): - addr = expr.arg + self.offset + self.l + 2 + addr = (expr.arg + self.offset + self.l + 2) & 0xFFFFFFFF else: - addr = expr.arg + self.offset + addr = (expr.arg + self.offset) & 0xFFFFFFFF loc_key = loc_db.get_or_create_offset_location(addr) dst = ExprLoc(loc_key, expr.size) @@ -564,7 +564,7 @@ class instruction_armt(instruction_arm): # The first +2 is to compensate instruction len, but strangely, 32 bits # thumb2 instructions len is 2... For the second +2, didn't find it in # the doc. - off = e.arg - self.offset + off = (e.arg + 0x100000000 - self.offset) & 0xFFFFFFFF if int(off % 2): raise ValueError('strange offset! %r' % off) self.args[0] = ExprInt(off, 32) diff --git a/miasm/arch/msp430/arch.py b/miasm/arch/msp430/arch.py index a700b04a..93854153 100644 --- a/miasm/arch/msp430/arch.py +++ b/miasm/arch/msp430/arch.py @@ -64,7 +64,7 @@ class msp430_arg(m_arg): def asm_ast_to_expr(self, value, loc_db): if isinstance(value, AstId): name = value.name - if isinstance(name, Expr): + if is_expr(name): return name assert isinstance(name, str) if name in gpregs.str: diff --git a/miasm/arch/ppc/arch.py b/miasm/arch/ppc/arch.py index 29550931..8cd0181c 100644 --- a/miasm/arch/ppc/arch.py +++ b/miasm/arch/ppc/arch.py @@ -129,9 +129,9 @@ class instruction_ppc(instruction): if not isinstance(e, ExprInt): return if name[-1] != 'A': - ad = e.arg + self.offset + ad = (int(e) + self.offset) & 0xFFFFFFFF else: - ad = e.arg + ad = int(e) loc_key = loc_db.get_or_create_offset_location(ad) s = ExprLoc(loc_key, e.size) self.args[address_index] = s @@ -175,11 +175,11 @@ class instruction_ppc(instruction): if self.name[-1] != 'A': if self.offset is None: raise ValueError('symbol not resolved %s' % self.l) - off = e.arg - (self.offset + self.l) + off = (int(e) + 0x100000000 - (self.offset + self.l)) & 0xFFFFFFFF if int(off % 4): raise ValueError('Offset %r must be a multiple of four' % off) else: - off = e.arg + off = int(e) self.args[0] = ExprInt(off, 32) def get_args_expr(self): @@ -343,7 +343,7 @@ class ppc_s14imm_branch(ppc_imm): def encode(self): if not isinstance(self.expr, ExprInt): return False - v = self.expr.arg.arg + v = int(self.expr) if v & 0x3: return False v = v >> 2 @@ -362,7 +362,7 @@ class ppc_s24imm_branch(ppc_imm): def encode(self): if not isinstance(self.expr, ExprInt): return False - v = self.expr.arg.arg + v = int(self.expr) if v & 0x3: return False v = v >> 2 @@ -381,7 +381,7 @@ class ppc_s16imm(ppc_imm): def encode(self): if not isinstance(self.expr, ExprInt): return False - v = self.expr.arg.arg + v = int(self.expr) if sign_ext(v & self.lmask, 16, 32) != v: return False self.value = v & self.lmask @@ -398,7 +398,7 @@ class ppc_u16imm(ppc_imm): def encode(self): if not isinstance(self.expr, ExprInt): return False - v = self.expr.arg.arg + v = int(self.expr) if v & self.lmask != v: return False self.value = v & self.lmask @@ -416,7 +416,7 @@ class ppc_spr(ppc_imm): def encode(self, e): if not isinstance(e, ExprInt): return False - self.value = ppc_swap_10(e.arg) + self.value = ppc_swap_10(int(e)) return True class ppc_tbr(ppc_imm): @@ -428,7 +428,7 @@ class ppc_tbr(ppc_imm): def encode(self, e): if not isinstance(e, ExprInt): return False - self.value = ppc_swap_10(e.arg) + self.value = ppc_swap_10(int(e)) return True class ppc_u08imm(ppc_u16imm): @@ -520,7 +520,7 @@ class ppc_deref32(ppc_arg): if len(addr.args) != 2: return False reg, disp = addr.args[0], addr.args[1] - v = int(disp.arg) + v = int(disp) if sign_ext(v & 0xFFFF, 16, 32) != v: return False v &= 0xFFFF diff --git a/miasm/arch/x86/arch.py b/miasm/arch/x86/arch.py index 33b41236..52ea1663 100644 --- a/miasm/arch/x86/arch.py +++ b/miasm/arch/x86/arch.py @@ -278,7 +278,7 @@ class x86_arg(m_arg): if value.name in ["FAR"]: return None - loc_key = loc_db.get_or_create_name_location(value.name.encode()) + loc_key = loc_db.get_or_create_name_location(value.name) return ExprLoc(loc_key, size_hint) if isinstance(value, AstOp): # First pass to retrieve fixed_size diff --git a/miasm/arch/x86/sem.py b/miasm/arch/x86/sem.py index fdb4efd6..b0fcd054 100644 --- a/miasm/arch/x86/sem.py +++ b/miasm/arch/x86/sem.py @@ -3387,9 +3387,11 @@ def icebp(_, instr): def l_int(_, instr, src): e = [] # XXX - if src.arg == 1: + assert src.is_int() + value = int(src) + if value == 1: except_int = EXCEPT_INT_1 - elif src.arg == 3: + elif value == 3: except_int = EXCEPT_SOFT_BP else: except_int = EXCEPT_INT_XX diff --git a/miasm/core/asmblock.py b/miasm/core/asmblock.py index 8f47947f..abd2b2c6 100644 --- a/miasm/core/asmblock.py +++ b/miasm/core/asmblock.py @@ -960,7 +960,9 @@ def fix_loc_offset(loc_db, loc_key, offset, modified): loc_offset = loc_db.get_location_offset(loc_key) if loc_offset == offset: return - loc_db.set_location_offset(loc_key, offset, force=True) + if loc_offset is not None: + loc_db.unset_location_offset(loc_key) + loc_db.set_location_offset(loc_key, offset) modified.add(loc_key) @@ -1209,7 +1211,7 @@ def assemble_block(mnemo, block, loc_db, conservative=False): data = b"" for expr in instr.raw: expr_int = fix_expr_val(expr, loc_db) - data += pck[expr_int.size](expr_int.arg) + data += pck[expr_int.size](int(expr_int)) instr.data = data instr.offset = offset_i diff --git a/miasm/core/cpu.py b/miasm/core/cpu.py index 3dc7bd68..ec8d95bc 100644 --- a/miasm/core/cpu.py +++ b/miasm/core/cpu.py @@ -1587,16 +1587,8 @@ class imm_noarg(object): if e == [None]: return None, None - assert(isinstance(e, m2_expr.Expr)) - if isinstance(e, tuple): - self.expr = self.int2expr(e[1]) - elif isinstance(e, m2_expr.Expr): - self.expr = e - else: - raise TypeError('zarb expr') - if self.expr is None: - log.debug('cannot fromstring int %r', text) - return None, None + assert(m2_expr.is_expr(e)) + self.expr = e return start, stop def decodeval(self, v): diff --git a/miasm/core/objc.py b/miasm/core/objc.py index 123d339a..117e3b7d 100644 --- a/miasm/core/objc.py +++ b/miasm/core/objc.py @@ -14,7 +14,8 @@ from functools import total_ordering from miasm.core.utils import cmp_elts from miasm.expression.expression_reduce import ExprReducer -from miasm.expression.expression import ExprInt, ExprId, ExprOp, ExprMem +from miasm.expression.expression import ExprInt, ExprId, ExprOp, ExprMem, \ + is_op_segm from miasm.core.ctypesmngr import CTypeUnion, CTypeStruct, CTypeId, CTypePtr,\ CTypeArray, CTypeOp, CTypeSizeof, CTypeEnum, CTypeFunc, CTypeEllipsis @@ -1045,7 +1046,7 @@ class ExprToAccessC(ExprReducer): def reduce_op(self, node, lvl=0, **kwargs): """Generate access for ExprOp""" - if not (node.expr.is_op("+") or node.expr.is_op_segm()) \ + if not (node.expr.is_op("+") or is_op_segm(node.expr)) \ or len(node.args) != 2: return None type_arg1 = self.get_solo_type(node.args[1]) diff --git a/miasm/core/parse_asm.py b/miasm/core/parse_asm.py index 2b4f1195..b742a2d2 100644 --- a/miasm/core/parse_asm.py +++ b/miasm/core/parse_asm.py @@ -65,7 +65,7 @@ def guess_next_new_label(loc_db): """Generate a new label @loc_db: the LocationDB instance""" i = 0 - gen_name = b"loc_%.8X" + gen_name = "loc_%.8X" while True: name = gen_name % i label = loc_db.get_name_location(name) @@ -121,7 +121,7 @@ def parse_txt(mnemo, attrib, txt, loc_db=None): # label beginning with .L match_re = LABEL_RE.match(line) if match_re: - label_name = match_re.group(1).encode() + label_name = match_re.group(1) label = loc_db.get_or_create_name_location(label_name) lines.append(label) continue diff --git a/miasm/expression/expression.py b/miasm/expression/expression.py index 9ac631fa..d6813cec 100644 --- a/miasm/expression/expression.py +++ b/miasm/expression/expression.py @@ -140,6 +140,32 @@ class DiGraphExpr(DiGraph): return "" +def is_expr(expr): + return isinstance( + expr, + ( + ExprInt, ExprId, ExprMem, + ExprSlice, ExprCompose, ExprCond, + ExprLoc, ExprOp + ) + ) + +def is_associative(expr): + "Return True iff current operation is associative" + return (expr.op in ['+', '*', '^', '&', '|']) + +def is_commutative(expr): + "Return True iff current operation is commutative" + return (expr.op in ['+', '*', '^', '&', '|']) + +def is_op_segm(expr): + """Returns True if is ExprOp and op == 'segm'""" + return expr.is_op('segm') + +def is_mem_segm(expr): + """Returns True if is ExprMem and ptr is_op_segm""" + return expr.is_mem() and is_op_segm(expr.ptr) + @total_ordering class LocKey(object): diff --git a/miasm/expression/simplifications_common.py b/miasm/expression/simplifications_common.py index 38859f3a..2b69ed0e 100644 --- a/miasm/expression/simplifications_common.py +++ b/miasm/expression/simplifications_common.py @@ -32,29 +32,29 @@ def simp_cst_propagation(e_s, expr): int2 = args.pop() int1 = args.pop() if op_name == '+': - out = int1.arg + int2.arg + out = mod_size2uint[int1.size](int(int1) + int(int2)) elif op_name == '*': - out = int1.arg * int2.arg + out = mod_size2uint[int1.size](int(int1) * int(int2)) elif op_name == '**': - out =int1.arg ** int2.arg + out = mod_size2uint[int1.size](int(int1) ** int(int2)) elif op_name == '^': - out = int1.arg ^ int2.arg + out = mod_size2uint[int1.size](int(int1) ^ int(int2)) elif op_name == '&': - out = int1.arg & int2.arg + out = mod_size2uint[int1.size](int(int1) & int(int2)) elif op_name == '|': - out = int1.arg | int2.arg + out = mod_size2uint[int1.size](int(int1) | int(int2)) elif op_name == '>>': if int(int2) > int1.size: out = 0 else: - out = int1.arg >> int2.arg + out = mod_size2uint[int1.size](int(int1) >> int(int2)) elif op_name == '<<': if int(int2) > int1.size: out = 0 else: - out = int1.arg << int2.arg + out = mod_size2uint[int1.size](int(int1) << int(int2)) elif op_name == 'a>>': - tmp1 = mod_size2int[int1.arg.size](int1.arg) + tmp1 = mod_size2int[int1.size](int1.arg) tmp2 = mod_size2uint[int2.arg.size](int2.arg) if tmp2 > int1.size: is_signed = int(int1) & (1 << (int1.size - 1)) @@ -63,7 +63,7 @@ def simp_cst_propagation(e_s, expr): else: out = 0 else: - out = mod_size2uint[int1.arg.size](tmp1 >> tmp2) + out = mod_size2uint[int1.size](tmp1 >> tmp2) elif op_name == '>>>': shifter = int2.arg % int2.size out = (int1.arg >> shifter) | (int1.arg << (int2.size - shifter)) @@ -76,28 +76,28 @@ def simp_cst_propagation(e_s, expr): out = int1.arg % int2.arg elif op_name == 'sdiv': assert int2.arg.arg - tmp1 = mod_size2int[int1.arg.size](int1.arg) + tmp1 = mod_size2int[int1.size](int1.arg) tmp2 = mod_size2int[int2.arg.size](int2.arg) - out = mod_size2uint[int1.arg.size](tmp1 // tmp2) + out = mod_size2uint[int1.size](tmp1 // tmp2) elif op_name == 'smod': assert int2.arg.arg - tmp1 = mod_size2int[int1.arg.size](int1.arg) + tmp1 = mod_size2int[int1.size](int1.arg) tmp2 = mod_size2int[int2.arg.size](int2.arg) - out = mod_size2uint[int1.arg.size](tmp1 % tmp2) + out = mod_size2uint[int1.size](tmp1 % tmp2) elif op_name == 'umod': assert int2.arg.arg - tmp1 = mod_size2uint[int1.arg.size](int1.arg) + tmp1 = mod_size2uint[int1.size](int1.arg) tmp2 = mod_size2uint[int2.arg.size](int2.arg) - out = mod_size2uint[int1.arg.size](tmp1 % tmp2) + out = mod_size2uint[int1.size](tmp1 % tmp2) elif op_name == 'udiv': assert int2.arg.arg - tmp1 = mod_size2uint[int1.arg.size](int1.arg) + tmp1 = mod_size2uint[int1.size](int1.arg) tmp2 = mod_size2uint[int2.arg.size](int2.arg) - out = mod_size2uint[int1.arg.size](tmp1 // tmp2) + out = mod_size2uint[int1.size](tmp1 // tmp2) - args.append(ExprInt(out, int1.size)) + args.append(ExprInt(int(out), int1.size)) # cnttrailzeros(int) => int if op_name == "cnttrailzeros" and args[0].is_int(): @@ -120,6 +120,7 @@ def simp_cst_propagation(e_s, expr): len(args[0].args) == 1): return args[0].args[0] + # -(int) => -int if op_name == '-' and len(args) == 1 and args[0].is_int(): return ExprInt(-int(args[0]), expr.size) @@ -207,13 +208,13 @@ def simp_cst_propagation(e_s, expr): j += 1 i += 1 - if op_name in ['|', '&', '%', '/', '**'] and len(args) == 1: + if op_name in ['+', '^', '|', '&', '%', '/', '**'] and len(args) == 1: return args[0] # A <<< A.size => A if (op_name in ['<<<', '>>>'] and args[1].is_int() and - args[1].arg == args[0].size): + int(args[1]) == args[0].size): return args[0] # (A <<< X) <<< Y => A <<< (X+Y) (or <<< >>>) if X + Y does not overflow @@ -277,7 +278,10 @@ def simp_cst_propagation(e_s, expr): # ((A & A.mask) if op_name == "&" and args[-1] == expr.mask: - return ExprOp('&', *args[:-1]) + args = args[:-1] + if len(args) == 1: + return args[0] + return ExprOp('&', *args) # ((A | A.mask) if op_name == "|" and args[-1] == expr.mask: @@ -289,7 +293,7 @@ def simp_cst_propagation(e_s, expr): # ((A & mask) >> shift) with mask < 2**shift => 0 if op_name == ">>" and args[1].is_int() and args[0].is_op("&"): if (args[0].args[1].is_int() and - 2 ** args[1].arg > args[0].args[1].arg): + 2 ** int(args[1]) > int(args[0].args[1])): return ExprInt(0, args[0].size) # parity(int) => int @@ -315,7 +319,6 @@ def simp_cst_propagation(e_s, expr): args = args[0].args return ExprOp('*', *(list(args[:-1]) + [ExprInt(-int(args[-1]), expr.size)])) - # A << int with A ExprCompose => move index if (op_name == "<<" and args[0].is_compose() and args[1].is_int() and int(args[1]) != 0): @@ -471,7 +474,7 @@ def simp_slice(e_s, expr): if expr.arg.is_int(): total_bit = expr.stop - expr.start mask = (1 << (expr.stop - expr.start)) - 1 - return ExprInt(int((expr.arg.arg >> expr.start) & mask), total_bit) + return ExprInt(int((int(expr.arg) >> expr.start) & mask), total_bit) # Slice(Slice(A, x), y) => Slice(A, z) if expr.arg.is_slice(): if expr.stop - expr.start > expr.arg.stop - expr.arg.start: @@ -626,7 +629,7 @@ def simp_cond(_, expr): expr = expr.src1 # int ? A:B => A or B elif expr.cond.is_int(): - if expr.cond.arg == 0: + if int(expr.cond) == 0: expr = expr.src2 else: expr = expr.src1 diff --git a/miasm/ir/ir.py b/miasm/ir/ir.py index 613a4bce..9b2e4ba0 100644 --- a/miasm/ir/ir.py +++ b/miasm/ir/ir.py @@ -44,6 +44,26 @@ def _expr_loc_to_symb(expr, loc_db): name = sorted(names)[0] return m2_expr.ExprId(name, expr.size) +def slice_rest(expr): + "Return the completion of the current slice" + size = expr.arg.size + if expr.start >= size or expr.stop > size: + raise ValueError('bad slice rest %s %s %s' % + (size, expr.start, expr.stop)) + + if expr.start == expr.stop: + return [(0, size)] + + rest = [] + if expr.start != 0: + rest.append((0, expr.start)) + if expr.stop < size: + rest.append((expr.stop, size)) + + return rest + + + class AssignBlock(object): """Represent parallel IR assignment, such as: EAX = EBX @@ -99,7 +119,7 @@ class AssignBlock(object): # Complete the source with missing slice parts new_dst = dst.arg rest = [(m2_expr.ExprSlice(dst.arg, r[0], r[1]), r[0], r[1]) - for r in dst.slice_rest()] + for r in slice_rest(dst)] all_a = [(src, dst.start, dst.stop)] + rest all_a.sort(key=lambda x: x[1]) args = [expr for (expr, _, _) in all_a] @@ -752,7 +772,7 @@ class IntermediateRepresentation(object): if loc_key is None: offset = getattr(instr, "offset", None) - loc_key = self.loc_db.add_location(offset=offset) + loc_key = self.loc_db.get_or_create_offset_location(offset) block = AsmBlock(loc_key) block.lines = [instr] self.add_asmblock_to_ircfg(block, ircfg, gen_pc_updt) diff --git a/miasm/ir/translators/C.py b/miasm/ir/translators/C.py index 6be5d961..7778abf7 100644 --- a/miasm/ir/translators/C.py +++ b/miasm/ir/translators/C.py @@ -3,7 +3,8 @@ from miasm.expression.modint import size2mask from miasm.expression.expression import ExprInt, ExprCond, ExprCompose, \ TOK_EQUAL, \ TOK_INF_SIGNED, TOK_INF_UNSIGNED, \ - TOK_INF_EQUAL_SIGNED, TOK_INF_EQUAL_UNSIGNED + TOK_INF_EQUAL_SIGNED, TOK_INF_EQUAL_UNSIGNED, \ + is_associative def int_size_to_bn(value, size): if size < 32: @@ -288,7 +289,7 @@ class TranslatorC(Translator): out = "bignum_mask(%s, %d)"% (out, expr.size) return out - elif expr.is_associative(): + elif is_associative(expr): args = [self.from_expr(arg) for arg in expr.args] if expr.size <= self.NATIVE_INT_MAX_SIZE: @@ -466,7 +467,7 @@ class TranslatorC(Translator): else: raise NotImplementedError('Unknown op: %r' % expr.op) - elif len(expr.args) >= 3 and expr.is_associative(): # ????? + elif len(expr.args) >= 3 and is_associative(expr): # ????? oper = ['(%s&%s)' % ( self.from_expr(arg), self._size2mask(arg.size), diff --git a/miasm/jitter/codegen.py b/miasm/jitter/codegen.py index abbf65d2..0b5b7961 100644 --- a/miasm/jitter/codegen.py +++ b/miasm/jitter/codegen.py @@ -6,8 +6,8 @@ from builtins import zip from future.utils import viewitems, viewvalues -from miasm.expression.expression import Expr, ExprId, ExprLoc, ExprInt, \ - ExprMem, ExprCond, LocKey +from miasm.expression.expression import ExprId, ExprLoc, ExprInt, \ + ExprMem, ExprCond, LocKey, is_expr from miasm.ir.ir import IRBlock, AssignBlock from miasm.ir.translators.C import TranslatorC @@ -123,7 +123,7 @@ class CGen(object): def dst_to_c(self, src): """Translate Expr @src into C code""" - if not isinstance(src, Expr): + if not is_expr(src): src = ExprInt(src, self.PC.size) return self.id_to_c(src) @@ -413,7 +413,7 @@ class CGen(object): @dst: potential instruction destination""" out = [] - if isinstance(dst, Expr): + if is_expr(dst): out += self.gen_post_code(attrib, "DST_value") out.append('BlockDst->address = DST_value;') out += self.gen_post_instr_checks(attrib) diff --git a/miasm/jitter/emulatedsymbexec.py b/miasm/jitter/emulatedsymbexec.py index aacfba9f..844e7d5f 100644 --- a/miasm/jitter/emulatedsymbexec.py +++ b/miasm/jitter/emulatedsymbexec.py @@ -94,10 +94,10 @@ class EmulatedSymbExec(SymbolicExecutionEngine): data = self.expr_simp(data) if not isinstance(data, m2_expr.ExprInt): raise RuntimeError("A simplification is missing: %s" % data) - to_write = data.arg.arg + to_write = int(data) # Format information - addr = dest.ptr.arg.arg + addr = int(dest.ptr) size = data.size // 8 content = hex(to_write).replace("0x", "").replace("L", "") content = "0" * (size * 2 - len(content)) + content @@ -120,7 +120,7 @@ class EmulatedSymbExec(SymbolicExecutionEngine): if not isinstance(value, m2_expr.ExprInt): raise ValueError("A simplification is missing: %s" % value) - setattr(self.cpu, symbol.name, value.arg.arg) + setattr(self.cpu, symbol.name, int(value)) else: raise NotImplementedError("Type not handled: %s" % symbol) @@ -140,7 +140,7 @@ class EmulatedSymbExec(SymbolicExecutionEngine): # CPU specific simplifications def _simp_handle_segm(self, e_s, expr): """Handle 'segm' operation""" - if not expr.is_op_segm(): + if not m2_expr.is_op_segm(expr): return expr if not expr.args[0].is_int(): return expr diff --git a/test/arch/msp430/sem.py b/test/arch/msp430/sem.py index 2aca66ed..cb101937 100755 --- a/test/arch/msp430/sem.py +++ b/test/arch/msp430/sem.py @@ -39,10 +39,12 @@ def compute(asm, inputstate={}, debug=False): for k, v in viewitems(symexec.symbols): if regs_init.get(k, None) != v: print(k, v) - return { - k: v.arg.arg for k, v in viewitems(symexec.symbols) + + result = { + k: int(v) for k, v in viewitems(symexec.symbols) if k not in EXCLUDE_REGS and regs_init.get(k, None) != v } + return result class TestMSP430Semantic(unittest.TestCase): diff --git a/test/arch/x86/sem.py b/test/arch/x86/sem.py index 5109d2b4..10980b05 100755 --- a/test/arch/x86/sem.py +++ b/test/arch/x86/sem.py @@ -104,7 +104,7 @@ class TestX86Semantic(unittest.TestCase): sem = compute(ir_32, m32, '%s XMM0, XMM1' % name, {XMM0: arg1, XMM1: arg2}, False) - ref = ExprInt(int_vec_op(op, elt_size, reg_size, arg1.arg, arg2.arg), XMM0.size) + ref = ExprInt(int_vec_op(op, elt_size, reg_size, int(arg1), int(arg2)), XMM0.size) self.assertEqual(sem, {XMM0: ref, XMM1: arg2}) def symb_sse_ops(self, names, a, b, ref): @@ -121,7 +121,7 @@ class TestX86Semantic(unittest.TestCase): sem = compute(ir_32, m32, '%s MM0, MM1' % name, {mm0: arg1, mm1: arg2}, False) - ref = ExprInt(op(arg1.arg, arg2.arg), mm0.size) + ref = ExprInt(op(int(arg1), int(arg2)), mm0.size) self.assertEqual(sem, {mm0: ref, mm1: arg2}) def sse_logical_op(self, name, op, arg1, arg2): @@ -130,7 +130,7 @@ class TestX86Semantic(unittest.TestCase): sem = compute(ir_32, m32, '%s XMM0, XMM1' % name, {XMM0: arg1, XMM1: arg2}, False) - ref = ExprInt(op(arg1.arg, arg2.arg), XMM0.size) + ref = ExprInt(op(int(arg1), int(arg2)), XMM0.size) self.assertEqual(sem, {XMM0: ref, XMM1: arg2}) def test_SSE_ADD(self): |