From 8e8a60b5d55db6209d05577d038ed3b4dc961b60 Mon Sep 17 00:00:00 2001 From: serpilliere Date: Sat, 21 Feb 2015 20:51:31 +0100 Subject: Expression: Use singleton pattern for Expression Start the transformation of Expression into immutable. Multiple problems were present in Expression class. One of them was comparison done through hash, which could generate collisions. The attributes is_simp/is_canon where linked to the instance, and could not survive to expression simplification. --- miasm2/core/sembuilder.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'miasm2/core/sembuilder.py') diff --git a/miasm2/core/sembuilder.py b/miasm2/core/sembuilder.py index ce327ce1..7f80b64e 100644 --- a/miasm2/core/sembuilder.py +++ b/miasm2/core/sembuilder.py @@ -16,7 +16,7 @@ class MiasmTransformer(ast.NodeTransformer): X if Y else Z -> ExprCond(Y, X, Z) 'X'(Y) -> ExprOp('X', Y) ('X' % Y)(Z) -> ExprOp('X' % Y, Z) - {a, b} -> ExprCompose([a, 0, a.size], [b, a.size, a.size + b.size]) + {a, b} -> ExprCompose([(a, 0, a.size), (b, a.size, a.size + b.size)]) """ # Parsers @@ -95,7 +95,7 @@ class MiasmTransformer(ast.NodeTransformer): return call def visit_Set(self, node): - "{a, b} -> ExprCompose([a, 0, a.size], [b, a.size, a.size + b.size])" + "{a, b} -> ExprCompose([(a, 0, a.size)], (b, a.size, a.size + b.size)])" if len(node.elts) == 0: return node @@ -109,7 +109,7 @@ class MiasmTransformer(ast.NodeTransformer): right=ast.Attribute(value=elt, attr='size', ctx=ast.Load())) - new_elts.append(ast.List(elts=[elt, index, new_index], + new_elts.append(ast.Tuple(elts=[elt, index, new_index], ctx=ast.Load())) index = new_index return ast.Call(func=ast.Name(id='ExprCompose', -- cgit 1.4.1 From 3771288cffdd53c1ff87857374bd13c550b355dc Mon Sep 17 00:00:00 2001 From: Fabrice Desclaux Date: Fri, 21 Oct 2016 16:19:09 +0200 Subject: ExprCompose: add new api The ExprComposes uses directly its arguments sizes to guess the slices locations. Old api: ExprCompose([(a, 0, 32), (b, 32, 64)]) becomes: ExprCompose(a, b) --- example/expression/basic_simplification.py | 3 +- example/expression/expr_grapher.py | 2 +- example/expression/simplification_tools.py | 8 +- miasm2/arch/aarch64/sem.py | 3 +- miasm2/arch/arm/sem.py | 20 ++- miasm2/arch/mips32/sem.py | 7 +- miasm2/arch/msp430/sem.py | 22 +-- miasm2/arch/x86/sem.py | 213 ++++++++++------------------- miasm2/core/sembuilder.py | 2 +- miasm2/expression/expression.py | 47 ++++--- miasm2/ir/translators/miasm.py | 6 +- test/arch/arm/sem.py | 2 +- test/expression/expression.py | 8 +- test/expression/expression_helper.py | 5 +- test/expression/simplifications.py | 178 ++++++++++++------------ test/ir/symbexec.py | 6 +- test/ir/translators/z3_ir.py | 2 +- 17 files changed, 224 insertions(+), 310 deletions(-) (limited to 'miasm2/core/sembuilder.py') diff --git a/example/expression/basic_simplification.py b/example/expression/basic_simplification.py index 27c86096..17b1a35b 100644 --- a/example/expression/basic_simplification.py +++ b/example/expression/basic_simplification.py @@ -11,8 +11,7 @@ b = ExprId('ebx') exprs = [a + b - a, ExprInt32(0x12) + ExprInt32(0x30) - a, - ExprCompose([(a[:8], 0, 8), - (a[8:16], 8, 16)])] + ExprCompose(a[:8], a[8:16])] for e in exprs: print '*' * 40 diff --git a/example/expression/expr_grapher.py b/example/expression/expr_grapher.py index 22dff7cf..3137e6d2 100644 --- a/example/expression/expr_grapher.py +++ b/example/expression/expr_grapher.py @@ -8,7 +8,7 @@ c = ExprId("C") d = ExprId("D") m = ExprMem(a + b + c + a) -e1 = ExprCompose([(a + b - (c * a) / m | b, 0, 32), (a + m, 32, 64)]) +e1 = ExprCompose(a + b - (c * a) / m | b, a + m) e2 = ExprInt64(15) e = ExprCond(d, e1, e2)[0:32] diff --git a/example/expression/simplification_tools.py b/example/expression/simplification_tools.py index b2df58d3..9b8aeed5 100644 --- a/example/expression/simplification_tools.py +++ b/example/expression/simplification_tools.py @@ -25,11 +25,9 @@ i1 = ExprInt(uint32(0x1)) i2 = ExprInt(uint32(0x2)) cc = ExprCond(a, b, c) -o = ExprCompose([(a[:8], 8, 16), - (a[8:16], 0, 8)]) +o = ExprCompose(a[8:16], a[:8]) -o2 = ExprCompose([(a[8:16], 0, 8), - (a[:8], 8, 16)]) +o2 = ExprCompose(a[8:16], a[:8]) l = [a[:8], b[:8], c[:8], m[:8], s, i1[:8], i2[:8], o[:8]] l2 = l[::-1] @@ -56,7 +54,7 @@ print y == y.copy() print repr(y), repr(y.copy()) -z = ExprCompose([(a[5:5 + 8], 0, 8), (b[:16], 8, 24), (x[:8], 24, 32)]) +z = ExprCompose(a[5:5 + 8], b[:16], x[:8]) print z print z.copy() print z[:31].copy().visit(replace_expr) diff --git a/miasm2/arch/aarch64/sem.py b/miasm2/arch/aarch64/sem.py index aff2d8ca..0bceb8dc 100644 --- a/miasm2/arch/aarch64/sem.py +++ b/miasm2/arch/aarch64/sem.py @@ -672,8 +672,7 @@ def nop(): @sbuild.parse def extr(arg1, arg2, arg3, arg4): - compose = m2_expr.ExprCompose([(arg2, 0, arg2.size), - (arg3, arg2.size, arg2.size+arg3.size)]) + compose = m2_expr.ExprCompose(arg2, arg3) arg1 = compose[int(arg4.arg):int(arg4)+arg1.size] mnemo_func = sbuild.functions diff --git a/miasm2/arch/arm/sem.py b/miasm2/arch/arm/sem.py index 260531ac..c6f3dceb 100644 --- a/miasm2/arch/arm/sem.py +++ b/miasm2/arch/arm/sem.py @@ -481,7 +481,7 @@ def umull(ir, instr, a, b, c, d): def umlal(ir, instr, a, b, c, d): e = [] - r = c.zeroExtend(64) * d.zeroExtend(64) + ExprCompose([(a, 0, 32), (b, 32, 64)]) + r = c.zeroExtend(64) * d.zeroExtend(64) + ExprCompose(a, b) e.append(ExprAff(a, r[0:32])) e.append(ExprAff(b, r[32:64])) # r15/IRDst not allowed as output @@ -497,7 +497,7 @@ def smull(ir, instr, a, b, c, d): def smlal(ir, instr, a, b, c, d): e = [] - r = c.signExtend(64) * d.signExtend(64) + ExprCompose([(a, 0, 32), (b, 32, 64)]) + r = c.signExtend(64) * d.signExtend(64) + ExprCompose(a, b) e.append(ExprAff(a, r[0:32])) e.append(ExprAff(b, r[32:64])) # r15/IRDst not allowed as output @@ -910,14 +910,14 @@ def bfc(ir, instr, a, b, c): out = [] last = 0 if start: - out.append((a[:start], 0, start)) + out.append(a[:start]) last = start if stop - start: - out.append((ExprInt32(0)[last:stop], last, stop)) + out.append(ExprInt32(0)[last:stop]) last = stop if last < 32: - out.append((a[last:], last, 32)) - r = ExprCompose(out) + out.append(a[last:]) + r = ExprCompose(*out) e.append(ExprAff(a, r)) dst = None if PC in a.get_r(): @@ -927,10 +927,7 @@ def bfc(ir, instr, a, b, c): def rev(ir, instr, a, b): e = [] - c = ExprCompose([(b[:8], 24, 32), - (b[8:16], 16, 24), - (b[16:24], 8, 16), - (b[24:32], 0, 8)]) + c = ExprCompose(b[24:32], b[16:24], b[8:16], b[:8]) e.append(ExprAff(a, c)) return e @@ -1225,8 +1222,7 @@ class ir_arml(ir): # ir = get_mnemo_expr(self, self.name.lower(), *args) if len(args) and isinstance(args[-1], ExprOp): if args[-1].op == 'rrx': - args[-1] = ExprCompose( - [(args[-1].args[0][1:], 0, 31), (cf, 31, 32)]) + args[-1] = ExprCompose(args[-1].args[0][1:], cf) elif (args[-1].op in ['<<', '>>', '<>', '<<<', '>>>'] and isinstance(args[-1].args[-1], ExprId)): args[-1] = ExprOp(args[-1].op, diff --git a/miasm2/arch/mips32/sem.py b/miasm2/arch/mips32/sem.py index d03772ca..dea822b4 100644 --- a/miasm2/arch/mips32/sem.py +++ b/miasm2/arch/mips32/sem.py @@ -99,7 +99,7 @@ def bne(arg1, arg2, arg3): def lui(arg1, arg2): """The immediate value @arg2 is shifted left 16 bits and stored in the register @arg1. The lower 16 bits are zeroes.""" - arg1 = ExprCompose([(i16(0), 0, 16), (arg2[:16], 16, 32)]) + arg1 = ExprCompose(i16(0), arg2[:16]) @sbuild.parse def nop(): @@ -251,10 +251,7 @@ def bgtz(arg1, arg2): @sbuild.parse def wsbh(arg1, arg2): - arg1 = ExprCompose([(arg2[8:16], 0, 8), - (arg2[0:8] , 8, 16), - (arg2[24:32], 16, 24), - (arg2[16:24], 24, 32)]) + arg1 = ExprCompose(arg2[8:16], arg2[0:8], arg2[24:32], arg2[16:24]) @sbuild.parse def rotr(arg1, arg2, arg3): diff --git a/miasm2/arch/msp430/sem.py b/miasm2/arch/msp430/sem.py index 169a631f..a99e500c 100644 --- a/miasm2/arch/msp430/sem.py +++ b/miasm2/arch/msp430/sem.py @@ -250,8 +250,7 @@ def call(ir, instr, a): def swpb(ir, instr, a): e = [] x, y = a[:8], a[8:16] - e.append(ExprAff(a, ExprCompose([(y, 0, 8), - (x, 8, 16)]))) + e.append(ExprAff(a, ExprCompose(y, x))) return e, [] @@ -330,8 +329,7 @@ def jmp(ir, instr, a): def rrc_w(ir, instr, a): e = [] - c = ExprCompose([(a[1:16], 0, 15), - (cf, 15, 16)]) + c = ExprCompose(a[1:16], cf) e.append(ExprAff(a, c)) e.append(ExprAff(cf, a[:1])) # e += update_flag_zn_r(c) @@ -347,8 +345,7 @@ def rrc_w(ir, instr, a): def rra_w(ir, instr, a): e = [] - c = ExprCompose([(a[1:16], 0, 15), - (a[15:16], 15, 16)]) + c = ExprCompose(a[1:16], a[15:16]) e.append(ExprAff(a, c)) # TODO: error in disasm microcorruption? # e.append(ExprAff(cf, a[:1])) @@ -406,18 +403,7 @@ mnemo_func = { } -composed_sr = ExprCompose([ - (cf, 0, 1), - (zf, 1, 2), - (nf, 2, 3), - (gie, 3, 4), - (cpuoff, 4, 5), - (osc, 5, 6), - (scg0, 6, 7), - (scg1, 7, 8), - (of, 8, 9), - (res, 9, 16), -]) +composed_sr = ExprCompose(cf, zf, nf, gie, cpuoff, osc, scg0, scg1, of, res) def ComposeExprAff(dst, src): diff --git a/miasm2/arch/x86/sem.py b/miasm2/arch/x86/sem.py index 69c21ac8..5dc49efc 100644 --- a/miasm2/arch/x86/sem.py +++ b/miasm2/arch/x86/sem.py @@ -331,9 +331,7 @@ def xadd(ir, instr, a, b): def adc(ir, instr, a, b): e = [] - c = a + (b + m2_expr.ExprCompose([(m2_expr.ExprInt(0, a.size - 1), - 1, a.size), - (cf, 0, 1)])) + c = a + (b + m2_expr.ExprCompose(cf, m2_expr.ExprInt(0, a.size - 1))) e += update_flag_arith(c) e += update_flag_af(a, b, c) e += update_flag_add(a, b, c) @@ -355,9 +353,7 @@ def sub(ir, instr, a, b): def sbb(ir, instr, a, b): e = [] - c = a - (b + m2_expr.ExprCompose([(m2_expr.ExprInt(0, a.size - 1), - 1, a.size), - (cf, 0, 1)])) + c = a - (b + m2_expr.ExprCompose(cf, m2_expr.ExprInt(0, a.size - 1))) e += update_flag_arith(c) e += update_flag_af(a, b, c) e += update_flag_sub(a, b, c) @@ -898,25 +894,12 @@ def setalc(ir, instr): def bswap(ir, instr, a): e = [] if a.size == 16: - c = m2_expr.ExprCompose([(a[:8], 8, 16), - (a[8:16], 0, 8), - ]) + c = m2_expr.ExprCompose(a[8:16], a[:8]) elif a.size == 32: - c = m2_expr.ExprCompose([(a[:8], 24, 32), - (a[8:16], 16, 24), - (a[16:24], 8, 16), - (a[24:32], 0, 8), - ]) + c = m2_expr.ExprCompose(a[24:32], a[16:24], a[8:16], a[:8]) elif a.size == 64: - c = m2_expr.ExprCompose([(a[:8], 56, 64), - (a[8:16], 48, 56), - (a[16:24], 40, 48), - (a[24:32], 32, 40), - (a[32:40], 24, 32), - (a[40:48], 16, 24), - (a[48:56], 8, 16), - (a[56:64], 0, 8), - ]) + c = m2_expr.ExprCompose(a[56:64], a[48:56], a[40:48], a[32:40], + a[24:32], a[16:24], a[8:16], a[:8]) else: raise ValueError('the size DOES matter') e.append(m2_expr.ExprAff(a, c)) @@ -986,24 +969,18 @@ def scas(ir, instr, size): def compose_eflag(s=32): args = [] - regs = [cf, m2_expr.ExprInt1(1), pf, m2_expr.ExprInt1( - 0), af, m2_expr.ExprInt1(0), zf, nf, tf, i_f, df, of] - for i in xrange(len(regs)): - args.append((regs[i], i, i + 1)) - - args.append((iopl, 12, 14)) + args = [cf, m2_expr.ExprInt1(1), pf, m2_expr.ExprInt1(0), af, + m2_expr.ExprInt1(0), zf, nf, tf, i_f, df, of, iopl] if s == 32: - regs = [nt, m2_expr.ExprInt1(0), rf, vm, ac, vif, vip, i_d] + args += [nt, m2_expr.ExprInt1(0), rf, vm, ac, vif, vip, i_d] elif s == 16: - regs = [nt, m2_expr.ExprInt1(0)] + args += [nt, m2_expr.ExprInt1(0)] else: raise ValueError('unk size') - for i in xrange(len(regs)): - args.append((regs[i], i + 14, i + 15)) if s == 32: - args.append((m2_expr.ExprInt(0, 10), 22, 32)) - return m2_expr.ExprCompose(args) + args.append(m2_expr.ExprInt(0, 10)) + return m2_expr.ExprCompose(*args) def pushfd(ir, instr): @@ -1426,8 +1403,7 @@ def div(ir, instr, a): b = mRAX[instr.mode][:16] elif size in [16, 32, 64]: s1, s2 = mRDX[size], mRAX[size] - b = m2_expr.ExprCompose([(s2, 0, size), - (s1, size, size * 2)]) + b = m2_expr.ExprCompose(s2, s1) else: raise ValueError('div arg not impl', a) @@ -1436,8 +1412,7 @@ def div(ir, instr, a): # if 8 bit div, only ax is affected if size == 8: - e.append(m2_expr.ExprAff(b, m2_expr.ExprCompose([(c_d[:8], 0, 8), - (c_r[:8], 8, 16)]))) + e.append(m2_expr.ExprAff(b, m2_expr.ExprCompose(c_d[:8], c_r[:8]))) else: e.append(m2_expr.ExprAff(s1, c_r[:size])) e.append(m2_expr.ExprAff(s2, c_d[:size])) @@ -1454,8 +1429,7 @@ def idiv(ir, instr, a): b = mRAX[instr.mode][:16] elif size in [16, 32, 64]: s1, s2 = mRDX[size], mRAX[size] - b = m2_expr.ExprCompose([(s2, 0, size), - (s1, size, size * 2)]) + b = m2_expr.ExprCompose(s2, s1) else: raise ValueError('div arg not impl', a) @@ -1464,8 +1438,7 @@ def idiv(ir, instr, a): # if 8 bit div, only ax is affected if size == 8: - e.append(m2_expr.ExprAff(b, m2_expr.ExprCompose([(c_d[:8], 0, 8), - (c_r[:8], 8, 16)]))) + e.append(m2_expr.ExprAff(b, m2_expr.ExprCompose(c_d[:8], c_r[:8]))) else: e.append(m2_expr.ExprAff(s1, c_r[:size])) e.append(m2_expr.ExprAff(s2, c_d[:size])) @@ -2192,14 +2165,10 @@ def fyl2x(ir, instr): def fnstenv(ir, instr, a): e = [] # XXX TODO tag word, ... - status_word = m2_expr.ExprCompose([(m2_expr.ExprInt8(0), 0, 8), - (float_c0, 8, 9), - (float_c1, 9, 10), - (float_c2, 10, 11), - (float_stack_ptr, 11, 14), - (float_c3, 14, 15), - (m2_expr.ExprInt1(0), 15, 16), - ]) + status_word = m2_expr.ExprCompose(m2_expr.ExprInt8(0), + float_c0, float_c1, float_c2, + float_stack_ptr, float_c3, + m2_expr.ExprInt1(0)) s = instr.mode # The behaviour in 64bit is identical to 32 bit @@ -2497,15 +2466,15 @@ def fabs(ir, instr): def fnstsw(ir, instr, dst): args = [ # Exceptions -> 0 - (m2_expr.ExprInt8(0), 0, 8), - (float_c0, 8, 9), - (float_c1, 9, 10), - (float_c2, 10, 11), - (float_stack_ptr, 11, 14), - (float_c3, 14, 15), + m2_expr.ExprInt8(0), + float_c0, + float_c1, + float_c2, + float_stack_ptr, + float_c3, # B: FPU is not busy -> 0 - (m2_expr.ExprInt1(0), 15, 16)] - e = [m2_expr.ExprAff(dst, m2_expr.ExprCompose(args))] + m2_expr.ExprInt1(0)] + e = [m2_expr.ExprAff(dst, m2_expr.ExprCompose(*args))] return e, [] @@ -2656,11 +2625,9 @@ def das(ir, instr): def aam(ir, instr, a): e = [] tempAL = mRAX[instr.mode][0:8] - newEAX = m2_expr.ExprCompose([ - (tempAL % a, 0, 8), - (tempAL / a, 8, 16), - (mRAX[instr.mode][16:], 16, mRAX[instr.mode].size), - ]) + newEAX = m2_expr.ExprCompose(tempAL % a, + tempAL / a, + mRAX[instr.mode][16:]) e += [m2_expr.ExprAff(mRAX[instr.mode], newEAX)] e += update_flag_arith(newEAX) e.append(m2_expr.ExprAff(af, m2_expr.ExprInt1(0))) @@ -2671,12 +2638,9 @@ def aad(ir, instr, a): e = [] tempAL = mRAX[instr.mode][0:8] tempAH = mRAX[instr.mode][8:16] - newEAX = m2_expr.ExprCompose([ - ((tempAL + (tempAH * a)) & m2_expr.ExprInt8(0xFF), 0, 8), - (m2_expr.ExprInt8(0), 8, 16), - (mRAX[instr.mode][16:], - 16, mRAX[instr.mode].size), - ]) + newEAX = m2_expr.ExprCompose((tempAL + (tempAH * a)) & m2_expr.ExprInt8(0xFF), + m2_expr.ExprInt8(0), + mRAX[instr.mode][16:]) e += [m2_expr.ExprAff(mRAX[instr.mode], newEAX)] e += update_flag_arith(newEAX) e.append(m2_expr.ExprAff(af, m2_expr.ExprInt1(0))) @@ -2908,9 +2872,8 @@ def l_outs(ir, instr, size): def xlat(ir, instr): e = [] - a = m2_expr.ExprCompose([(m2_expr.ExprInt(0, 24), 8, 32), - (mRAX[instr.mode][0:8], 0, 8)]) - b = m2_expr.ExprMem(m2_expr.ExprOp('+', mRBX[instr.mode], a), 8) + a = mRAX[instr.mode][0:8].zeroExtend(mRBX[instr.mode].size) + b = m2_expr.ExprMem(mRBX[instr.mode] + a, 8) e.append(m2_expr.ExprAff(mRAX[instr.mode][0:8], b)) return e, [] @@ -3073,13 +3036,10 @@ def lgs(ir, instr, a, b): def lahf(ir, instr): e = [] - args = [] - regs = [cf, m2_expr.ExprInt1(1), pf, m2_expr.ExprInt1(0), af, + args = [cf, m2_expr.ExprInt1(1), pf, m2_expr.ExprInt1(0), af, m2_expr.ExprInt1(0), zf, nf] - for i in xrange(len(regs)): - args.append((regs[i], i, i + 1)) e.append( - m2_expr.ExprAff(mRAX[instr.mode][8:16], m2_expr.ExprCompose(args))) + m2_expr.ExprAff(mRAX[instr.mode][8:16], m2_expr.ExprCompose(*args))) return e, [] @@ -3128,11 +3088,9 @@ def l_str(ir, instr, a): def movd(ir, instr, a, b): e = [] if a in regs_mm_expr: - e.append(m2_expr.ExprAff(a, m2_expr.ExprCompose([(b, 0, 32), - (m2_expr.ExprInt32(0), 32, 64)]))) + e.append(m2_expr.ExprAff(a, m2_expr.ExprCompose(b, m2_expr.ExprInt32(0)))) elif a in regs_xmm_expr: - e.append(m2_expr.ExprAff(a, m2_expr.ExprCompose([(b, 0, 32), - (m2_expr.ExprInt(0, 96), 32, 128)]))) + e.append(m2_expr.ExprAff(a, m2_expr.ExprCompose(b, m2_expr.ExprInt(0, 96)))) else: e.append(m2_expr.ExprAff(a, b[:32])) return e, [] @@ -3187,8 +3145,7 @@ def wrmsr(ir, instr): msr_addr = m2_expr.ExprId('MSR') + m2_expr.ExprInt32( 8) * mRCX[instr.mode][:32] e = [] - src = m2_expr.ExprCompose([(mRAX[instr.mode][:32], 0, 32), - (mRDX[instr.mode][:32], 32, 64)]) + src = m2_expr.ExprCompose(mRAX[instr.mode][:32], mRDX[instr.mode][:32]) e.append(m2_expr.ExprAff(m2_expr.ExprMem(msr_addr, 64), src)) return e, [] @@ -3216,17 +3173,14 @@ def vec_vertical_sem(op, elt_size, reg_size, a, b): assert(reg_size % elt_size == 0) n = reg_size / elt_size if op == '-': - ops = [( + ops = [ (a[i * elt_size:(i + 1) * elt_size] - - b[i * elt_size:(i + 1) * elt_size]), - i * elt_size, (i + 1) * elt_size) for i in xrange(0, n)] + - b[i * elt_size:(i + 1) * elt_size]) for i in xrange(0, n)] else: - ops = [(m2_expr.ExprOp(op, a[i * elt_size:(i + 1) * elt_size], - b[i * elt_size:(i + 1) * elt_size]), - i * elt_size, - (i + 1) * elt_size) for i in xrange(0, n)] + ops = [m2_expr.ExprOp(op, a[i * elt_size:(i + 1) * elt_size], + b[i * elt_size:(i + 1) * elt_size]) for i in xrange(0, n)] - return m2_expr.ExprCompose(ops) + return m2_expr.ExprCompose(*ops) def float_vec_vertical_sem(op, elt_size, reg_size, a, b): @@ -3236,24 +3190,22 @@ def float_vec_vertical_sem(op, elt_size, reg_size, a, b): x_to_int, int_to_x = {32: ('float_to_int_%d', 'int_%d_to_float'), 64: ('double_to_int_%d', 'int_%d_to_double')}[elt_size] if op == '-': - ops = [(m2_expr.ExprOp(x_to_int % elt_size, - m2_expr.ExprOp(int_to_x % elt_size, a[i * elt_size:(i + 1) * elt_size]) - - m2_expr.ExprOp( - int_to_x % elt_size, b[i * elt_size:( - i + 1) * elt_size])), - i * elt_size, (i + 1) * elt_size) for i in xrange(0, n)] + ops = [m2_expr.ExprOp(x_to_int % elt_size, + m2_expr.ExprOp(int_to_x % elt_size, a[i * elt_size:(i + 1) * elt_size]) - + m2_expr.ExprOp( + int_to_x % elt_size, b[i * elt_size:( + i + 1) * elt_size])) for i in xrange(0, n)] else: - ops = [(m2_expr.ExprOp(x_to_int % elt_size, - m2_expr.ExprOp(op, - m2_expr.ExprOp( - int_to_x % elt_size, a[i * elt_size:( - i + 1) * elt_size]), - m2_expr.ExprOp( - int_to_x % elt_size, b[i * elt_size:( - i + 1) * elt_size]))), - i * elt_size, (i + 1) * elt_size) for i in xrange(0, n)] + ops = [m2_expr.ExprOp(x_to_int % elt_size, + m2_expr.ExprOp(op, + m2_expr.ExprOp( + int_to_x % elt_size, a[i * elt_size:( + i + 1) * elt_size]), + m2_expr.ExprOp( + int_to_x % elt_size, b[i * elt_size:( + i + 1) * elt_size]))) for i in xrange(0, n)] - return m2_expr.ExprCompose(ops) + return m2_expr.ExprCompose(*ops) def __vec_vertical_instr_gen(op, elt_size, sem): @@ -3558,8 +3510,7 @@ def movss(ir, instr, a, b): e.append(m2_expr.ExprAff(a, b[:32])) else: # Source Mem Destination XMM - e.append(m2_expr.ExprAff(a, m2_expr.ExprCompose([(b, 0, 32), - (m2_expr.ExprInt(0, 96), 32, 128)]))) + e.append(m2_expr.ExprAff(a, m2_expr.ExprCompose(b, m2_expr.ExprInt(0, 96)))) return e, [] @@ -3624,19 +3575,18 @@ def ps_rl_ll(ir, instr, a, b, op, size): slices = [] for i in xrange(0, a.size, size): - slices.append((m2_expr.ExprOp(op, a[i:i + size], count[:size]), - i, i + size)) + slices.append(m2_expr.ExprOp(op, a[i:i + size], count[:size])) if isinstance(test, m2_expr.ExprInt): if int(test) == 0: - return [m2_expr.ExprAff(a[0:a.size], m2_expr.ExprCompose(slices))], [] + return [m2_expr.ExprAff(a[0:a.size], m2_expr.ExprCompose(*slices))], [] else: return [m2_expr.ExprAff(a, m2_expr.ExprInt(0, a.size))], [] e_zero = [m2_expr.ExprAff(a, m2_expr.ExprInt(0, a.size)), m2_expr.ExprAff(ir.IRDst, lbl_next)] e_do = [] - e.append(m2_expr.ExprAff(a[0:a.size], m2_expr.ExprCompose(slices))) + e.append(m2_expr.ExprAff(a[0:a.size], m2_expr.ExprCompose(*slices))) e_do.append(m2_expr.ExprAff(ir.IRDst, lbl_next)) return e, [irbloc(lbl_do.name, [e_do]), irbloc(lbl_zero.name, [e_zero])] @@ -3759,11 +3709,9 @@ def punpck(ir, instr, a, b, size, off): e = [] slices = [] for i in xrange(a.size / (2 * size)): - src1 = a[size * i + off: size * i + off + size] - src2 = b[size * i + off: size * i + off + size] - slices.append((src1, size * 2 * i, size * 2 * i + size)) - slices.append((src2, size * (2 * i + 1), size * (2 * i + 1) + size)) - e.append(m2_expr.ExprAff(a, m2_expr.ExprCompose(slices))) + slices.append(a[size * i + off: size * i + off + size]) + slices.append(b[size * i + off: size * i + off + size]) + e.append(m2_expr.ExprAff(a, m2_expr.ExprCompose(*slices))) return e, [] @@ -3861,36 +3809,28 @@ def pextrq(ir, instr, a, b, c): def unpckhps(ir, instr, a, b): e = [] - src = m2_expr.ExprCompose([(a[64:96], 0, 32), - (b[64:96], 32, 64), - (a[96:128], 64, 96), - (b[96:128], 96, 128)]) + src = m2_expr.ExprCompose(a[64:96], b[64:96], a[96:128], b[96:128]) e.append(m2_expr.ExprAff(a, src)) return e, [] def unpckhpd(ir, instr, a, b): e = [] - src = m2_expr.ExprCompose([(a[64:128], 0, 64), - (b[64:128], 64, 128)]) + src = m2_expr.ExprCompose(a[64:128], b[64:128]) e.append(m2_expr.ExprAff(a, src)) return e, [] def unpcklps(ir, instr, a, b): e = [] - src = m2_expr.ExprCompose([(a[0:32], 0, 32), - (b[0:32], 32, 64), - (a[32:64], 64, 96), - (b[32:64], 96, 128)]) + src = m2_expr.ExprCompose(a[0:32], b[0:32], a[32:64], b[32:64]) e.append(m2_expr.ExprAff(a, src)) return e, [] def unpcklpd(ir, instr, a, b): e = [] - src = m2_expr.ExprCompose([(a[0:64], 0, 64), - (b[0:64], 64, 128)]) + src = m2_expr.ExprCompose(a[0:64], b[0:64]) e.append(m2_expr.ExprAff(a, src)) return e, [] @@ -3940,10 +3880,9 @@ def sqrt_gen(ir, instr, a, b, size): e = [] out = [] for i in b.size / size: - out.append((m2_expr.ExprOp('fsqrt' % size, - b[i * size: (i + 1) * size]), - i * size, (i + 1) * size)) - src = m2_expr.ExprCompose(out) + out.append(m2_expr.ExprOp('fsqrt' % size, + b[i * size: (i + 1) * size])) + src = m2_expr.ExprCompose(*out) e.append(m2_expr.ExprAff(a, src)) return e, [] @@ -3976,8 +3915,8 @@ def pmovmskb(ir, instr, a, b): e = [] out = [] for i in xrange(b.size / 8): - out.append((b[8 * i + 7:8 * (i + 1)], i, i + 1)) - src = m2_expr.ExprCompose(out) + out.append(b[8 * i + 7:8 * (i + 1)]) + src = m2_expr.ExprCompose(*out) e.append(m2_expr.ExprAff(a, src.zeroExtend(a.size))) return e, [] diff --git a/miasm2/core/sembuilder.py b/miasm2/core/sembuilder.py index 7f80b64e..27401049 100644 --- a/miasm2/core/sembuilder.py +++ b/miasm2/core/sembuilder.py @@ -16,7 +16,7 @@ class MiasmTransformer(ast.NodeTransformer): X if Y else Z -> ExprCond(Y, X, Z) 'X'(Y) -> ExprOp('X', Y) ('X' % Y)(Z) -> ExprOp('X' % Y, Z) - {a, b} -> ExprCompose([(a, 0, a.size), (b, a.size, a.size + b.size)]) + {a, b} -> ExprCompose(((a, 0, a.size), (b, a.size, a.size + b.size))) """ # Parsers diff --git a/miasm2/expression/expression.py b/miasm2/expression/expression.py index d51f0bdb..d18bc751 100644 --- a/miasm2/expression/expression.py +++ b/miasm2/expression/expression.py @@ -322,12 +322,10 @@ class Expr(object): if self.size == size: return self ad_size = size - self.size - c = ExprCompose([(self, 0, self.size), - (ExprCond(self.msb(), - ExprInt(size2mask(ad_size), ad_size), - ExprInt(0, ad_size)), - self.size, size) - ]) + c = ExprCompose(self, + ExprCond(self.msb(), + ExprInt(size2mask(ad_size), ad_size), + ExprInt(0, ad_size))) return c def graph_recursive(self, graph): @@ -1056,25 +1054,33 @@ class ExprSlice(Expr): class ExprCompose(Expr): """ - Compose is like a hambuger. - It's arguments are tuple of: (Expression, start, stop) - start and stop are intergers, determining Expression position in the compose. - - Burger Example: - ExprCompose([(salad, 0, 3), (cheese, 3, 10), (beacon, 10, 16)]) - In the example, salad.size == 3. + Compose is like a hambuger. It concatenate Expressions """ __slots__ = Expr.__slots__ + ["__args"] - def __init__(self, args): + def __init__(self, *args): """Create an ExprCompose The ExprCompose is contiguous and starts at 0 - @args: tuple(Expr, int, int) + @args: [Expr, Expr, ...] + DEPRECATED: + @args: [(Expr, int, int), (Expr, int, int), ...] """ super(ExprCompose, self).__init__() + is_new_style = args and isinstance(args[0], Expr) + if is_new_style: + new_args = [] + index = 0 + for arg in args: + new_args.append((arg, index, index + arg.size)) + index += arg.size + args = new_args + else: + assert len(args) == 1 + args = args[0] + last_stop = 0 args = sorted(args, key=itemgetter(1)) for e, start, stop in args: @@ -1106,12 +1112,15 @@ class ExprCompose(Expr): def __setstate__(self, state): self.__init__(state) - def __new__(cls, args): + def __new__(cls, *args): + is_new_style = args and isinstance(args[0], Expr) + if not is_new_style: + assert len(args) == 1 + args = args[0] return Expr.get_object(cls, tuple(args)) def __str__(self): - return '{' + ', '.join(['%s,%d,%d' % - (str(arg[0]), arg[1], arg[2]) for arg in self.__args]) + '}' + return '{' + ', '.join([str(arg[0]) for arg in self.__args]) + '}' def get_r(self, mem_read=False, cst_read=False): return reduce(lambda elements, arg: @@ -1127,7 +1136,7 @@ class ExprCompose(Expr): return hash(tuple(h_args)) def _exprrepr(self): - return "%s(%r)" % (self.__class__.__name__, self.__args) + return "%s([%r])" % (self.__class__.__name__, self.__args) def __contains__(self, e): if self == e: diff --git a/miasm2/ir/translators/miasm.py b/miasm2/ir/translators/miasm.py index ef91cfb1..515148ee 100644 --- a/miasm2/ir/translators/miasm.py +++ b/miasm2/ir/translators/miasm.py @@ -27,9 +27,9 @@ class TranslatorMiasm(Translator): ", ".join(map(self.from_expr, expr.args))) def from_ExprCompose(self, expr): - args = ["(%s, %d, %d)" % (self.from_expr(arg), start, stop) - for arg, start, stop in expr.args] - return "ExprCompose([%s])" % ", ".join(args) + args = ["%s" % self.from_expr(arg) + for arg, _, _ in expr.args] + return "ExprCompose(%s)" % ", ".join(args) def from_ExprAff(self, expr): return "ExprAff(%s, %s)" % (self.from_expr(expr.dst), diff --git a/test/arch/arm/sem.py b/test/arch/arm/sem.py index cefbe76a..8fc609fb 100644 --- a/test/arch/arm/sem.py +++ b/test/arch/arm/sem.py @@ -285,7 +285,7 @@ class TestARMSemantic(unittest.TestCase): self.assertEqual(compute('AND R4, R4, R5 LSR 2 ', {R4: 0xFFFFFFFF, R5: 0x80000041, }), {R4: 0x20000010, R5: 0x80000041, }) self.assertEqual(compute('AND R4, R4, R5 ASR 3 ', {R4: 0xF00000FF, R5: 0x80000081, }), {R4: 0xF0000010, R5: 0x80000081, }) self.assertEqual(compute('AND R4, R4, R5 ROR 4 ', {R4: 0xFFFFFFFF, R5: 0x000000FF, }), {R4: 0xF000000F, R5: 0x000000FF, }) - self.assertEqual(compute('AND R4, R4, R5 RRX ', {R4: 0xFFFFFFFF, R5: 0x00000101, }), {R4: ExprCompose([(ExprInt(0x80, 31),0,31), (cf_init,31,32)]), R5: 0x00000101, }) + self.assertEqual(compute('AND R4, R4, R5 RRX ', {R4: 0xFFFFFFFF, R5: 0x00000101, }), {R4: ExprCompose(ExprInt(0x80, 31), cf_init), R5: 0x00000101, }) # §A8.8.15: AND{S}{}{} {,} , , self.assertEqual(compute('AND R4, R6, R4 LSL R5', {R4: 0x00000001, R5: 0x00000004, R6: -1, }), {R4: 0x00000010, R5: 0x00000004, R6: 0xFFFFFFFF, }) diff --git a/test/expression/expression.py b/test/expression/expression.py index 90236744..847ba7eb 100644 --- a/test/expression/expression.py +++ b/test/expression/expression.py @@ -30,10 +30,10 @@ for expr in [ A + cst1, A + ExprCond(cond1, cst1, cst2), ExprCond(cond1, cst1, cst2) + ExprCond(cond2, cst3, cst4), - ExprCompose([(A, 0, 32), (cst1, 32, 64)]), - ExprCompose([(ExprCond(cond1, cst1, cst2), 0, 32), (A, 32, 64)]), - ExprCompose([(ExprCond(cond1, cst1, cst2), 0, 32), - (ExprCond(cond2, cst3, cst4), 32, 64)]), + ExprCompose(A, cst1), + ExprCompose(ExprCond(cond1, cst1, cst2), A), + ExprCompose(ExprCond(cond1, cst1, cst2), + ExprCond(cond2, cst3, cst4)), ExprCond(ExprCond(cond1, cst1, cst2), cst3, cst4), ]: print "*" * 80 diff --git a/test/expression/expression_helper.py b/test/expression/expression_helper.py index 514a9a51..a3a8fba4 100644 --- a/test/expression/expression_helper.py +++ b/test/expression/expression_helper.py @@ -16,11 +16,10 @@ class TestExpressionExpressionHelper(unittest.TestCase): ebx = m2_expr.ExprId("EBX") ax = eax[0:16] expr = eax + ebx - expr = m2_expr.ExprCompose([(ax, 0, 16), (expr[16:32], 16, 32)]) + expr = m2_expr.ExprCompose(ax, expr[16:32]) expr2 = m2_expr.ExprMem((eax + ebx) ^ (eax), size=16) expr2 = expr2 | ax | expr2 | cst - exprf = expr - expr + m2_expr.ExprCompose([(expr2, 0, 16), - (cst, 16, 32)]) + exprf = expr - expr + m2_expr.ExprCompose(expr2, cst) # Identify variables vi = Variables_Identifier(exprf) diff --git a/test/expression/simplifications.py b/test/expression/simplifications.py index 99cc7c35..bf658a30 100644 --- a/test/expression/simplifications.py +++ b/test/expression/simplifications.py @@ -24,11 +24,9 @@ i2 = ExprInt(uint32(0x2)) icustom = ExprInt(uint32(0x12345678)) cc = ExprCond(a, b, c) -o = ExprCompose([(a[:8], 8, 16), - (a[8:16], 0, 8)]) +o = ExprCompose(a[8:16], a[:8]) -o2 = ExprCompose([(a[8:16], 0, 8), - (a[:8], 8, 16)]) +o2 = ExprCompose(a[8:16], a[:8]) l = [a[:8], b[:8], c[:8], m[:8], s, i1[:8], i2[:8], o[:8]] l2 = l[::-1] @@ -93,11 +91,11 @@ to_test = [(ExprInt32(1) - ExprInt32(1), ExprInt32(0)), (a[8:16][:8], a[8:16]), (a[8:32][:8], a[8:16]), (a[:16][8:16], a[8:16]), - (ExprCompose([(a, 0, 32)]), a), - (ExprCompose([(a[:16], 0, 16)]), a[:16]), - (ExprCompose([(a[:16], 0, 16), (a[:16], 16, 32)]), - ExprCompose([(a[:16], 0, 16), (a[:16], 16, 32)]),), - (ExprCompose([(a[:16], 0, 16), (a[16:32], 16, 32)]), a), + (ExprCompose(a), a), + (ExprCompose(a[:16]), a[:16]), + (ExprCompose(a[:16], a[:16]), + ExprCompose(a[:16], a[:16]),), + (ExprCompose(a[:16], a[16:32]), a), (ExprMem(a)[:32], ExprMem(a)), (ExprMem(a)[:16], ExprMem(a, size=16)), @@ -106,14 +104,12 @@ to_test = [(ExprInt32(1) - ExprInt32(1), ExprInt32(0)), (ExprCond(ExprInt32(0), b, a), a), (ExprInt32(0x80000000)[31:32], ExprInt1(1)), - (ExprCompose([ - (ExprInt16(0x1337)[ - :8], 0, 8), (ExprInt16(0x1337)[8:16], 8, 16)]), + (ExprCompose(ExprInt16(0x1337)[:8], ExprInt16(0x1337)[8:16]), ExprInt16(0x1337)), - (ExprCompose([(ExprInt32(0x1337beef)[8:16], 8, 16), - (ExprInt32(0x1337beef)[:8], 0, 8), - (ExprInt32(0x1337beef)[16:32], 16, 32)]), + (ExprCompose(ExprInt32(0x1337beef)[:8], + ExprInt32(0x1337beef)[8:16], + ExprInt32(0x1337beef)[16:32]), ExprInt32(0x1337BEEF)), (ExprCond(a, ExprCond(a, @@ -122,9 +118,9 @@ to_test = [(ExprInt32(1) - ExprInt32(1), ExprInt32(0)), d), ExprCond(a, b, d)), ((a & b & ExprInt32(0x12))[31:32], ExprInt1(0)), - (ExprCompose([ - (ExprCond(a, ExprInt16(0x10), ExprInt16(0x20)), 0, 16), - (ExprInt16(0x1337), 16, 32)]), + (ExprCompose( + ExprCond(a, ExprInt16(0x10), ExprInt16(0x20)), + ExprInt16(0x1337)), ExprCond(a, ExprInt32(0x13370010), ExprInt32(0x13370020))), (ExprCond(ExprCond(a, ExprInt1(0), ExprInt1(1)), b, c), ExprCond(a, c, b)), @@ -167,103 +163,99 @@ to_test = [(ExprInt32(1) - ExprInt32(1), ExprInt32(0)), (ExprOp('-', ExprInt8(1), ExprInt8(0)), ExprInt8(1)), - (ExprCompose([(a, 0, 32), (ExprInt32(0), 32, 64)]) << ExprInt64(0x20), - ExprCompose([(ExprInt32(0), 0, 32), (a, 32, 64)])), - (ExprCompose([(a, 0, 32), (ExprInt32(0), 32, 64)]) << ExprInt64(0x10), - ExprCompose([(ExprInt16(0), 0, 16), (a, 16, 48), (ExprInt16(0), 48, 64)])), - (ExprCompose([(a, 0, 32), (ExprInt32(0), 32, 64)]) << ExprInt64(0x30), - ExprCompose([(ExprInt(0, 48), 0, 48), (a[:0x10], 48, 64)])), - (ExprCompose([(a, 0, 32), (ExprInt32(0), 32, 64)]) << ExprInt64(0x11), - ExprCompose([(ExprInt(0, 0x11), 0, 0x11), (a, 0x11, 0x31), (ExprInt(0, 0xF), 0x31, 0x40)])), - (ExprCompose([(a, 0, 32), (ExprInt32(0), 32, 64)]) << ExprInt64(0x40), + (ExprCompose(a, ExprInt32(0)) << ExprInt64(0x20), + ExprCompose(ExprInt32(0), a)), + (ExprCompose(a, ExprInt32(0)) << ExprInt64(0x10), + ExprCompose(ExprInt16(0), a, ExprInt16(0))), + (ExprCompose(a, ExprInt32(0)) << ExprInt64(0x30), + ExprCompose(ExprInt(0, 48), a[:0x10])), + (ExprCompose(a, ExprInt32(0)) << ExprInt64(0x11), + ExprCompose(ExprInt(0, 0x11), a, ExprInt(0, 0xF))), + (ExprCompose(a, ExprInt32(0)) << ExprInt64(0x40), ExprInt64(0)), - (ExprCompose([(a, 0, 32), (ExprInt32(0), 32, 64)]) << ExprInt64(0x50), + (ExprCompose(a, ExprInt32(0)) << ExprInt64(0x50), ExprInt64(0)), - (ExprCompose([(ExprInt32(0), 0, 32), (a, 32, 64)]) >> ExprInt64(0x20), - ExprCompose([(a, 0, 32), (ExprInt32(0), 32, 64)])), - (ExprCompose([(ExprInt32(0), 0, 32), (a, 32, 64)]) >> ExprInt64(0x10), - ExprCompose([(ExprInt16(0), 0, 16), (a, 16, 48), (ExprInt16(0), 48, 64)])), - (ExprCompose([(ExprInt32(0), 0, 32), (a, 32, 64)]) >> ExprInt64(0x30), - ExprCompose([(a[0x10:], 0, 16), (ExprInt(0, 48), 16, 64)])), - (ExprCompose([(ExprInt32(0), 0, 32), (a, 32, 64)]) >> ExprInt64(0x11), - ExprCompose([(ExprInt(0, 0xf), 0, 0xf), (a, 0xf, 0x2f), (ExprInt(0, 0x11), 0x2f, 0x40)])), - (ExprCompose([(ExprInt32(0), 0, 32), (a, 32, 64)]) >> ExprInt64(0x40), + (ExprCompose(ExprInt32(0), a) >> ExprInt64(0x20), + ExprCompose(a, ExprInt32(0))), + (ExprCompose(ExprInt32(0), a) >> ExprInt64(0x10), + ExprCompose(ExprInt16(0), a, ExprInt16(0))), + (ExprCompose(ExprInt32(0), a) >> ExprInt64(0x30), + ExprCompose(a[0x10:], ExprInt(0, 48))), + (ExprCompose(ExprInt32(0), a) >> ExprInt64(0x11), + ExprCompose(ExprInt(0, 0xf), a, ExprInt(0, 0x11))), + (ExprCompose(ExprInt32(0), a) >> ExprInt64(0x40), ExprInt64(0)), - (ExprCompose([(ExprInt32(0), 0, 32), (a, 32, 64)]) >> ExprInt64(0x50), + (ExprCompose(ExprInt32(0), a) >> ExprInt64(0x50), ExprInt64(0)), - (ExprCompose([(a, 0, 32), (b, 32, 64)]) << ExprInt64(0x20), - ExprCompose([(ExprInt32(0), 0, 32), (a, 32, 64)])), - (ExprCompose([(a, 0, 32), (b, 32, 64)]) << ExprInt64(0x10), - ExprCompose([(ExprInt16(0), 0, 16), (a, 16, 48), (b[:16], 48, 64)])), + (ExprCompose(a, b) << ExprInt64(0x20), + ExprCompose(ExprInt32(0), a)), + (ExprCompose(a, b) << ExprInt64(0x10), + ExprCompose(ExprInt16(0), a, b[:16])), - (ExprCompose([(a, 0, 32), (b, 32, 64)]) | ExprCompose([(c, 0, 32), (d, 32, 64)]), - ExprCompose([(a|c, 0, 32), (b|d, 32, 64)])), - (ExprCompose([(a, 0, 32), (ExprInt32(0), 32, 64)]) | ExprCompose([(ExprInt32(0), 0, 32), (d, 32, 64)]), - ExprCompose([(a, 0, 32), (d, 32, 64)])), - (ExprCompose([(f[:32], 0, 32), (ExprInt32(0), 32, 64)]) | ExprCompose([(ExprInt32(0), 0, 32), (f[32:], 32, 64)]), + (ExprCompose(a, b) | ExprCompose(c, d), + ExprCompose(a|c, b|d)), + (ExprCompose(a, ExprInt32(0)) | ExprCompose(ExprInt32(0), d), + ExprCompose(a, d)), + (ExprCompose(f[:32], ExprInt32(0)) | ExprCompose(ExprInt32(0), f[32:]), f), - ((ExprCompose([(a, 0, 32), (ExprInt32(0), 32, 64)]) * ExprInt64(0x123))[32:64], - (ExprCompose([(a, 0, 32), (ExprInt32(0), 32, 64)]) * ExprInt64(0x123))[32:64]), + ((ExprCompose(a, ExprInt32(0)) * ExprInt64(0x123))[32:64], + (ExprCompose(a, ExprInt32(0)) * ExprInt64(0x123))[32:64]), (ExprInt32(0x12), ExprInt32(0x12L)), - (ExprCompose(((a, 0, 32), (b, 32, 64), (c, 64, 96)))[:16], + (ExprCompose(a, b, c)[:16], a[:16]), - (ExprCompose(((a, 0, 32), (b, 32, 64), (c, 64, 96)))[16:32], + (ExprCompose(a, b, c)[16:32], a[16:]), - (ExprCompose(((a, 0, 32), (b, 32, 64), (c, 64, 96)))[32:48], + (ExprCompose(a, b, c)[32:48], b[:16]), - (ExprCompose(((a, 0, 32), (b, 32, 64), (c, 64, 96)))[48:64], + (ExprCompose(a, b, c)[48:64], b[16:]), - (ExprCompose(((a, 0, 32), (b, 32, 64), (c, 64, 96)))[64:80], + (ExprCompose(a, b, c)[64:80], c[:16]), - (ExprCompose(((a, 0, 32), (b, 32, 64), (c, 64, 96)))[80:], + (ExprCompose(a, b, c)[80:], c[16:]), - (ExprCompose(((a, 0, 32), (b, 32, 64), (c, 64, 96)))[80:82], + (ExprCompose(a, b, c)[80:82], c[16:18]), - (ExprCompose(((a, 0, 32), (b, 32, 64), (c, 64, 96)))[16:48], - ExprCompose(((a[16:], 0, 16), (b[:16], 16, 32)))), - (ExprCompose(((a, 0, 32), (b, 32, 64), (c, 64, 96)))[48:80], - ExprCompose(((b[16:], 0, 16), (c[:16], 16, 32)))), - - (ExprCompose(((a[0:8], 0, 8), - (b[8:16], 8, 16), - (ExprInt(uint48(0x0L)), 16, 64)))[12:32], - ExprCompose(((b[12:16], 0, 4), (ExprInt(uint16(0)), 4, 20))) + (ExprCompose(a, b, c)[16:48], + ExprCompose(a[16:], b[:16])), + (ExprCompose(a, b, c)[48:80], + ExprCompose(b[16:], c[:16])), + + (ExprCompose(a[0:8], b[8:16], ExprInt(uint48(0x0L)))[12:32], + ExprCompose(b[12:16], ExprInt(uint16(0))) ), - (ExprCompose(((ExprCompose(((a[:8], 0, 8), - (ExprInt(uint56(0x0L)), 8, 64)))[8:32] - & - ExprInt(uint24(0x1L)), 0, 24), - (ExprInt(uint40(0x0L)), 24, 64))), + (ExprCompose(ExprCompose(a[:8], ExprInt(uint56(0x0L)))[8:32] + & + ExprInt(uint24(0x1L)), + ExprInt(uint40(0x0L))), ExprInt64(0)), - (ExprCompose(((ExprCompose(((a[:8], 0, 8), - (ExprInt(uint56(0x0L)), 8, 64)))[:8] - & - ExprInt(uint8(0x1L)), 0, 8), - (ExprInt(uint56(0x0L)), 8, 64))), - ExprCompose(((a[:8]&ExprInt8(1), 0, 8), (ExprInt(uint56(0)), 8, 64)))), - - (ExprCompose(((ExprCompose(((a[:8], 0, 8), - (ExprInt(uint56(0x0L)), 8, 64)))[:32] - & - ExprInt(uint32(0x1L)), 0, 32), - (ExprInt(uint32(0x0L)), 32, 64))), - ExprCompose(((ExprCompose(((ExprSlice(a, 0, 8), 0, 8), - (ExprInt(uint24(0x0L)), 8, 32))) - & - ExprInt(uint32(0x1L)), 0, 32), - (ExprInt(uint32(0x0L)), 32, 64))) + (ExprCompose(ExprCompose(a[:8], ExprInt(uint56(0x0L)))[:8] + & + ExprInt(uint8(0x1L)), + (ExprInt(uint56(0x0L)))), + ExprCompose(a[:8]&ExprInt8(1), ExprInt(uint56(0)))), + + (ExprCompose(ExprCompose(a[:8], + ExprInt(uint56(0x0L)))[:32] + & + ExprInt(uint32(0x1L)), + ExprInt(uint32(0x0L))), + ExprCompose(ExprCompose(ExprSlice(a, 0, 8), + ExprInt(uint24(0x0L))) + & + ExprInt(uint32(0x1L)), + ExprInt(uint32(0x0L))) ), - (ExprCompose([(a[:16], 0, 16), (b[:16], 16, 32)])[8:32], - ExprCompose([(a[8:16], 0, 8), (b[:16], 8, 24)])), + (ExprCompose(a[:16], b[:16])[8:32], + ExprCompose(a[8:16], b[:16])), ((a >> ExprInt32(16))[:16], a[16:32]), ((a >> ExprInt32(16))[8:16], @@ -410,10 +402,10 @@ match_tests = [ (MatchExpr(ExprCond(x, y, z), ExprCond(a, b, c), [a, b, c]), {a: x, b: y, c: z}), - (MatchExpr(ExprCompose([(x[:8], 0, 8), (y[:8], 8, 16)]), a, [a]), - {a: ExprCompose([(x[:8], 0, 8), (y[:8], 8, 16)])}), - (MatchExpr(ExprCompose([(x[:8], 0, 8), (y[:8], 8, 16)]), - ExprCompose([(a[:8], 0, 8), (b[:8], 8, 16)]), [a, b]), + (MatchExpr(ExprCompose(x[:8], y[:8]), a, [a]), + {a: ExprCompose(x[:8], y[:8])}), + (MatchExpr(ExprCompose(x[:8], y[:8]), + ExprCompose(a[:8], b[:8]), [a, b]), {a: x, b: y}), (MatchExpr(e1, e2, [b]), {b: ExprInt32(0x10)}), (MatchExpr(e3, diff --git a/test/ir/symbexec.py b/test/ir/symbexec.py index 19cc47db..6df0bbc3 100644 --- a/test/ir/symbexec.py +++ b/test/ir/symbexec.py @@ -43,12 +43,12 @@ class TestSymbExec(unittest.TestCase): self.assertEqual(e.eval_expr(ExprMem(addr1 - addr1)), id_x) self.assertEqual(e.eval_expr(ExprMem(addr1, 8)), id_y) self.assertEqual(e.eval_expr(ExprMem(addr1 + addr1)), ExprCompose( - [(id_x[16:32], 0, 16), (ExprMem(ExprInt32(4), 16), 16, 32)])) + id_x[16:32], ExprMem(ExprInt32(4), 16))) self.assertEqual(e.eval_expr(mem8), ExprCompose( - [(id_x[0:24], 0, 24), (ExprMem(ExprInt32(11), 8), 24, 32)])) + id_x[0:24], ExprMem(ExprInt32(11), 8))) self.assertEqual(e.eval_expr(mem40v), id_x[:8]) self.assertEqual(e.eval_expr(mem50w), ExprCompose( - [(id_y, 0, 8), (ExprMem(ExprInt32(51), 8), 8, 16)])) + id_y, ExprMem(ExprInt32(51), 8))) self.assertEqual(e.eval_expr(mem20), mem20) e.func_read = lambda x: x self.assertEqual(e.eval_expr(mem20), mem20) diff --git a/test/ir/translators/z3_ir.py b/test/ir/translators/z3_ir.py index e080c7f5..5fcfe25e 100644 --- a/test/ir/translators/z3_ir.py +++ b/test/ir/translators/z3_ir.py @@ -114,7 +114,7 @@ check_interp(model[memb.get_mem_array(32)], [(0xdeadbeef, 0), (0xdeadbeef + 3, 2)]) # -------------------------------------------------------------------------- -e5 = ExprSlice(ExprCompose(((e, 0, 32), (four, 32, 64))), 0, 32) * five +e5 = ExprSlice(ExprCompose(e, four), 0, 32) * five ez3 = Translator.to_language('z3').from_expr(e5) z3_e5 = z3.Extract(31, 0, z3.Concat(z3_four, z3_e)) * z3_five -- cgit 1.4.1 From 05bdb3651796525100a5cbe160e2f8ad93c80316 Mon Sep 17 00:00:00 2001 From: Fabrice Desclaux Date: Fri, 21 Oct 2016 23:35:25 +0200 Subject: ExprCompose: update api --- miasm2/core/sembuilder.py | 15 ++---------- miasm2/expression/expression.py | 20 +++++++++------ miasm2/expression/expression_helper.py | 22 ++++++----------- miasm2/expression/simplifications_common.py | 38 +++++++++++++++++++++++------ miasm2/ir/ir.py | 10 ++++++-- miasm2/ir/symbexec.py | 11 ++++++--- 6 files changed, 69 insertions(+), 47 deletions(-) (limited to 'miasm2/core/sembuilder.py') diff --git a/miasm2/core/sembuilder.py b/miasm2/core/sembuilder.py index 27401049..6ff390bb 100644 --- a/miasm2/core/sembuilder.py +++ b/miasm2/core/sembuilder.py @@ -95,27 +95,16 @@ class MiasmTransformer(ast.NodeTransformer): return call def visit_Set(self, node): - "{a, b} -> ExprCompose([(a, 0, a.size)], (b, a.size, a.size + b.size)])" + "{a, b} -> ExprCompose(a, b)" if len(node.elts) == 0: return node # Recursive visit node = self.generic_visit(node) - new_elts = [] - index = ast.Num(n=0) - for elt in node.elts: - new_index = ast.BinOp(op=ast.Add(), left=index, - right=ast.Attribute(value=elt, - attr='size', - ctx=ast.Load())) - new_elts.append(ast.Tuple(elts=[elt, index, new_index], - ctx=ast.Load())) - index = new_index return ast.Call(func=ast.Name(id='ExprCompose', ctx=ast.Load()), - args=[ast.List(elts=new_elts, - ctx=ast.Load())], + args=node.elts, keywords=[], starargs=None, kwargs=None) diff --git a/miasm2/expression/expression.py b/miasm2/expression/expression.py index d18bc751..cb9f6114 100644 --- a/miasm2/expression/expression.py +++ b/miasm2/expression/expression.py @@ -289,7 +289,10 @@ class Expr(object): else: new_e = e elif isinstance(e, ExprCompose): - new_e = ExprCompose(canonize_expr_list_compose(e.args)) + starts = [start for (_, start, _) in e.args] + assert sorted(starts) == starts + assert len(set(starts)) == len(starts) + new_e = e else: new_e = e new_e.is_canon = True @@ -311,8 +314,7 @@ class Expr(object): return self ad_size = size - self.size n = ExprInt(0, ad_size) - return ExprCompose([(self, 0, self.size), - (n, self.size, size)]) + return ExprCompose(self, n) def signExtend(self, size): """Sign extend to size @@ -542,7 +544,8 @@ class ExprAff(Expr): for r in dst.slice_rest()] all_a = [(src, dst.start, dst.stop)] + rest all_a.sort(key=lambda x: x[1]) - self.__src = ExprCompose(all_a) + args = [expr for (expr, _, _) in all_a] + self.__src = ExprCompose(*args) else: self.__dst, self.__src = dst, src @@ -1078,6 +1081,8 @@ class ExprCompose(Expr): index += arg.size args = new_args else: + warnings.warn('DEPRECATION WARNING: use "ExprCompose(a, b) instead of'+ + 'ExprCemul_ir_block(self, addr, step=False)" instead of emul_ir_bloc') assert len(args) == 1 args = args[0] @@ -1153,12 +1158,13 @@ class ExprCompose(Expr): args = [(arg[0].visit(cb, tv), arg[1], arg[2]) for arg in self.__args] modified = any([arg[0] != arg[1] for arg in zip(self.__args, args)]) if modified: - return ExprCompose(args) + args = [expr for (expr, _, _) in args] + return ExprCompose(*args) return self def copy(self): - args = [(arg[0].copy(), arg[1], arg[2]) for arg in self.__args] - return ExprCompose(args) + args = [arg[0].copy() for arg in self.__args] + return ExprCompose(*args) def depth(self): depth = [arg[0].depth() for arg in self.__args] diff --git a/miasm2/expression/expression_helper.py b/miasm2/expression/expression_helper.py index 178ee25f..e9176658 100644 --- a/miasm2/expression/expression_helper.py +++ b/miasm2/expression/expression_helper.py @@ -449,21 +449,19 @@ class ExprRandom(object): """ # First layer upper_bound = random.randint(1, size) - args = [(cls._gen(size=upper_bound, depth=depth - 1), 0, upper_bound)] + args = [cls._gen(size=upper_bound, depth=depth - 1)] # Next layers while (upper_bound < size): if len(args) == (cls.compose_max_layer - 1): # We reach the maximum size - upper_bound = size + new_upper_bound = size else: - upper_bound = random.randint(args[-1][-1] + 1, size) + new_upper_bound = random.randint(upper_bound + 1, size) - args.append((cls._gen(size=upper_bound - args[-1][-1]), - args[-1][-1], - upper_bound)) - - return m2_expr.ExprCompose(args) + args.append(cls._gen(size=new_upper_bound - upper_bound)) + upper_bound = new_upper_bound + return m2_expr.ExprCompose(*args) @classmethod def memory(cls, size=32, depth=1): @@ -656,14 +654,10 @@ def possible_values(expr): args_constraint = itertools.chain(*[consval[0].constraints for consval in consvals_possibility]) # Gen the corresponding constraints / ExprCompose + args = [consval[0].value for consval in consvals_possibility] consvals.add( ConstrainedValue(frozenset(args_constraint), - m2_expr.ExprCompose( - [(consval[0].value, - consval[1], - consval[2]) - for consval in consvals_possibility] - ))) + m2_expr.ExprCompose(*args))) else: raise RuntimeError("Unsupported type for expr: %s" % type(expr)) diff --git a/miasm2/expression/simplifications_common.py b/miasm2/expression/simplifications_common.py index 49dfbcc0..4b88f8c2 100644 --- a/miasm2/expression/simplifications_common.py +++ b/miasm2/expression/simplifications_common.py @@ -286,7 +286,11 @@ def simp_cst_propagation(e_s, e): # create entry 0 expr = ExprInt(0, min_index) filter_args = [(expr, 0, min_index)] + filter_args - return ExprCompose(filter_args) + filter_args.sort(key=lambda x:x[1]) + starts = [start for (_, start, _) in filter_args] + assert len(set(starts)) == len(starts) + args = [expr for (expr, _, _) in filter_args] + return ExprCompose(*args) # A >> int with A ExprCompose => move index if op == ">>" and isinstance(args[0], ExprCompose) and isinstance(args[1], ExprInt): @@ -310,7 +314,11 @@ def simp_cst_propagation(e_s, e): # create entry 0 expr = ExprInt(0, final_size - max_index) filter_args += [(expr, max_index, final_size)] - return ExprCompose(filter_args) + filter_args.sort(key=lambda x:x[1]) + starts = [start for (_, start, _) in filter_args] + assert len(set(starts)) == len(starts) + args = [expr for (expr, _, _) in filter_args] + return ExprCompose(*args) # Compose(a) OP Compose(b) with a/b same bounds => Compose(a OP b) @@ -327,7 +335,13 @@ def simp_cst_propagation(e_s, e): new_args[i].append(expr) for i, arg in enumerate(new_args): new_args[i] = ExprOp(op, *arg), bound[i][0], bound[i][1] - return ExprCompose(new_args) + + new_args.sort(key=lambda x:x[1]) + starts = [start for (_, start, _) in new_args] + assert len(set(starts)) == len(starts) + args = [expr for (expr, _, _) in new_args] + + return ExprCompose(*args) # <<>>c_rez if op in [">>>c_rez", "<< ExprMem(x, a) # XXXX todo hum, is it safe? @@ -590,11 +610,15 @@ def simp_compose(e_s, e): else: src1.append(a) src2.append(a) - src1 = e_s.apply_simp(ExprCompose(src1)) - src2 = e_s.apply_simp(ExprCompose(src2)) + src1 = [expr for (expr, _, _) in src1] + src2 = [expr for (expr, _, _) in src2] + src1 = e_s.apply_simp(ExprCompose(*src1)) + src2 = e_s.apply_simp(ExprCompose(*src2)) if isinstance(src1, ExprInt) and isinstance(src2, ExprInt): return ExprCond(cond.cond, src1, src2) - return ExprCompose(args) + args.sort(key=lambda x:x[1]) + args = [expr for (expr, _, _) in args] + return ExprCompose(*args) def simp_cond(e_s, e): diff --git a/miasm2/ir/ir.py b/miasm2/ir/ir.py index 3a841fa5..2c6300a9 100644 --- a/miasm2/ir/ir.py +++ b/miasm2/ir/ir.py @@ -59,7 +59,8 @@ class AssignBlock(dict): for r in dst.slice_rest()] all_a = [(src, dst.start, dst.stop)] + rest all_a.sort(key=lambda x: x[1]) - new_src = m2_expr.ExprCompose(all_a) + args = [expr for (expr, _, _) in all_a] + new_src = m2_expr.ExprCompose(*args) else: new_dst, new_src = dst, src @@ -95,7 +96,12 @@ class AssignBlock(dict): for interval in missing_i) # Build the merging expression - new_src = m2_expr.ExprCompose(e_colision.union(remaining)) + args = list(e_colision.union(remaining)) + 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] + new_src = m2_expr.ExprCompose(*args) super(AssignBlock, self).__setitem__(new_dst, new_src) diff --git a/miasm2/ir/symbexec.py b/miasm2/ir/symbexec.py index 2a0b19ca..65515c64 100644 --- a/miasm2/ir/symbexec.py +++ b/miasm2/ir/symbexec.py @@ -148,7 +148,8 @@ class symbexec(object): mem = m2_expr.ExprMem(ptr, slice_stop - slice_start) out.append((mem, slice_start, slice_stop)) out.sort(key=lambda x: x[1]) - tmp = m2_expr.ExprSlice(m2_expr.ExprCompose(out), 0, size) + args = [expr for (expr, _, _) in out] + tmp = m2_expr.ExprSlice(m2_expr.ExprCompose(*args), 0, size) tmp = self.expr_simp(tmp) return tmp @@ -179,7 +180,9 @@ class symbexec(object): ptr_index += diff_size rest -= diff_size ptr = self.expr_simp(ptr + m2_expr.ExprInt(mem.size / 8, ptr.size)) - ret = self.expr_simp(m2_expr.ExprCompose(out)) + out.sort(key=lambda x: x[1]) + args = [expr for (expr, _, _) in out] + ret = self.expr_simp(m2_expr.ExprCompose(*args)) return ret # part lookup ret = self.expr_simp(self.symbols[ret][:size]) @@ -228,8 +231,8 @@ class symbexec(object): args = [] for (arg, start, stop) in expr.args: arg = self.apply_expr_on_state_visit_cache(arg, state, cache, level+1) - args.append((arg, start, stop)) - ret = m2_expr.ExprCompose(args) + args.append(arg) + ret = m2_expr.ExprCompose(*args) else: raise TypeError("Unknown expr type") #print '\t'*level, "Result", ret -- cgit 1.4.1