diff options
| author | serpilliere <devnull@localhost> | 2012-05-08 18:33:55 +0200 |
|---|---|---|
| committer | serpilliere <devnull@localhost> | 2012-05-08 18:33:55 +0200 |
| commit | 5dec442348a47a8b68fa13e53805f31786ce6127 (patch) | |
| tree | 018a50ce5c8b23d73e7c55c18ec519ee3050e2c1 | |
| parent | 0720dbf62ec5e001c10f80b2e19c521d976fdef5 (diff) | |
| download | focaccia-miasm-5dec442348a47a8b68fa13e53805f31786ce6127.tar.gz focaccia-miasm-5dec442348a47a8b68fa13e53805f31786ce6127.zip | |
remove useless ExprSliceTo
exprsliceto is only used in exprcompose, so it can be removed from IL representation, and exprcompose will deal start/stop fields WARNING: as IL is modified, it may break a lot of scripts
| -rw-r--r-- | doc/slides.tex | 1 | ||||
| -rw-r--r-- | example/expression/manip_expression3.py | 5 | ||||
| -rw-r--r-- | example/expression/manip_expression5.py | 12 | ||||
| -rw-r--r-- | example/find_rop.py | 118 | ||||
| -rw-r--r-- | miasm/arch/arm_sem.py | 12 | ||||
| -rw-r--r-- | miasm/arch/ia32_sem.py | 77 | ||||
| -rw-r--r-- | miasm/expression/expression.py | 194 | ||||
| -rw-r--r-- | miasm/expression/expression_eval_abstract.py | 28 | ||||
| -rw-r--r-- | miasm/expression/expression_helper.py | 111 | ||||
| -rw-r--r-- | miasm/tools/to_c_helper.py | 6 |
10 files changed, 290 insertions, 274 deletions
diff --git a/doc/slides.tex b/doc/slides.tex index cf7057e7..0c510099 100644 --- a/doc/slides.tex +++ b/doc/slides.tex @@ -788,7 +788,6 @@ esi = df?((+ esi 0x1),(- esi 0x1)) \item ExprOp: op(a, b, ...) \item ExprSlice: a[0:8] (bits) \item ExprCompose: slices composition - \item ExprSliceTo: position in a composition \end{itemize} \end{block} That's all. diff --git a/example/expression/manip_expression3.py b/example/expression/manip_expression3.py index 06b3f77a..ed3123bb 100644 --- a/example/expression/manip_expression3.py +++ b/example/expression/manip_expression3.py @@ -18,3 +18,8 @@ print e # ((0x12 + 0x30) - eax) print "=>", expr_simp(e) # (0x42 - eax) + +o = ExprCompose([(a[:8], 0, 8), + (a[8:16], 8, 16)]) +print o +print expr_simp(o) diff --git a/example/expression/manip_expression5.py b/example/expression/manip_expression5.py index cc54515d..165d9eef 100644 --- a/example/expression/manip_expression5.py +++ b/example/expression/manip_expression5.py @@ -61,15 +61,15 @@ print (i2+s).canonize() cc = ExprCond(a, b, c) -o = ExprCompose([ExprSliceTo(a[:8], 8, 16), - ExprSliceTo(a[8:16], 0, 8)]) +o = ExprCompose([(a[:8], 8, 16), + (a[8:16], 0, 8)]) print o print o.canonize() -o = ExprCompose([ExprSliceTo(a[8:16], 0, 8), - ExprSliceTo(a[:8], 8, 16)]) -print o -print o.canonize() +o2 = ExprCompose([(a[8:16], 0, 8), + (a[:8], 8, 16)]) +print o2 +print o2.canonize() print ExprMem(o).canonize() diff --git a/example/find_rop.py b/example/find_rop.py index 91806225..a071cf18 100644 --- a/example/find_rop.py +++ b/example/find_rop.py @@ -25,7 +25,92 @@ code_stop = e.rva2virt(s_code.addr+s_code.size) print "run on", hex(code_start), hex(code_stop) - + + +filename = os.environ.get('PYTHONSTARTUP') +if filename and os.path.isfile(filename): + execfile(filename) + + +def whoami(): + return inspect.stack()[1][3] + + + +def mem_read_wrap(evaluator, e): + return e + + +def mem_write_wrap(evaluator, dst, s, src, pool_out): + return ExprTop() + + + +min_addr = code_start +max_addr = code_stop + +print hex(min_addr), hex(max_addr) +arg1 = ExprId('ARG1', 32, True) +arg2 = ExprId('ARG2', 32, True) +ret1 = ExprId('RET1', 32, True) + +data1 = ExprId('DATA1', 32, True) +data2 = ExprId('DATA2', 32, True) +data3 = ExprId('DATA3', 32, True) +data4 = ExprId('DATA4', 32, True) +data5 = ExprId('DATA5', 32, True) +data6 = ExprId('DATA6', 32, True) +data7 = ExprId('DATA7', 32, True) +data8 = ExprId('DATA8', 32, True) +data9 = ExprId('DATA9', 32, True) +data10 = ExprId('DATA10', 32, True) + +machine = eval_abs({esp:init_esp, ebp:init_ebp, eax:init_eax, ebx:init_ebx, ecx:init_ecx, edx:init_edx, esi:init_esi, edi:init_edi, + cs:ExprInt(uint32(9)), + zf : ExprInt(uint32(0)), nf : ExprInt(uint32(0)), pf : ExprInt(uint32(0)), + of : ExprInt(uint32(0)), cf : ExprInt(uint32(0)), tf : ExprInt(uint32(0)), + i_f: ExprInt(uint32(1)), df : ExprInt(uint32(0)), af : ExprInt(uint32(0)), + iopl: ExprInt(uint32(0)), nt : ExprInt(uint32(0)), rf : ExprInt(uint32(0)), + vm : ExprInt(uint32(0)), ac : ExprInt(uint32(0)), vif: ExprInt(uint32(0)), + vip: ExprInt(uint32(0)), i_d: ExprInt(uint32(0)),tsc1: ExprInt(uint32(0)), + tsc2: ExprInt(uint32(0)), + dr7:ExprInt(uint32(0)), + cr0:init_cr0, + + }, + mem_read_wrap, + mem_write_wrap, + ) + + +# add some info for example +from elfesteem import * +from miasm.tools.pe_helper import * +import inspect +from miasm.core import asmbloc +from miasm.core import parse_asm +from elfesteem import pe +from miasm.tools.to_c_helper import * + + +if len(sys.argv) < 2: + print "%s dllfile"%sys.argv[0] + sys.exit(0) +fname = sys.argv[1] +e = pe_init.PE(open(fname, 'rb').read()) +in_str = bin_stream(e.virt) + +# find gadget only in first section +section_code_name = e.SHList.shlist[0].name.strip("\x00") +s_code = e.getsectionbyname(section_code_name) + + +code_start = e.rva2virt(s_code.addr) +code_stop = e.rva2virt(s_code.addr+s_code.size) + + +print "run on", hex(code_start), hex(code_stop) + filename = os.environ.get('PYTHONSTARTUP') if filename and os.path.isfile(filename): @@ -76,7 +161,7 @@ machine = eval_abs({esp:init_esp, ebp:init_ebp, eax:init_eax, ebx:init_ebx, ecx: tsc2: ExprInt(uint32(0)), dr7:ExprInt(uint32(0)), cr0:init_cr0, - + }, mem_read_wrap, mem_write_wrap, @@ -84,17 +169,17 @@ machine = eval_abs({esp:init_esp, ebp:init_ebp, eax:init_eax, ebx:init_ebx, ecx: # add some info for example -machine.eval_instr(push(arg2)) -machine.eval_instr(push(arg1)) -machine.eval_instr(push(ret1)) -machine.eval_instr(push(ebp)) -machine.eval_instr(mov(ebp, esp)) -machine.eval_instr(sub(esp, ExprInt(uint32(0x14)))) -machine.eval_instr(mov(eax, ExprMem(ebp + ExprInt(uint32(8))))) -machine.eval_instr(mov(edx, ExprMem(eax + ExprInt(uint32(12))))) -machine.eval_instr(mov(eax, ExprMem(ebp + ExprInt(uint32(12))))) -machine.eval_instr(mov(ExprMem(esp), eax)) -machine.eval_instr(push(ExprInt(uint32(0x1337beef)))) +machine.eval_instr(push(('u32', 'u32'), arg2)) +machine.eval_instr(push(('u32', 'u32'), arg1)) +machine.eval_instr(push(('u32', 'u32'), ret1)) +machine.eval_instr(push(('u32', 'u32'), ebp)) +machine.eval_instr(mov(('u32', 'u32'), ebp, esp)) +machine.eval_instr(sub(('u32', 'u32'), esp, ExprInt(uint32(0x14)))) +machine.eval_instr(mov(('u32', 'u32'), eax, ExprMem(ebp + ExprInt(uint32(8))))) +machine.eval_instr(mov(('u32', 'u32'), edx, ExprMem(eax + ExprInt(uint32(12))))) +machine.eval_instr(mov(('u32', 'u32'), eax, ExprMem(ebp + ExprInt(uint32(12))))) +machine.eval_instr(mov(('u32', 'u32'), ExprMem(esp), eax)) +machine.eval_instr(push(('u32', 'u32'), ExprInt(uint32(0x1337beef)))) for k in machine.pool: machine.pool[k] = expr_simp(machine.pool[k]) @@ -110,7 +195,7 @@ for f_ad in xrange(min_addr, max_addr): start_ad = f_ad my_eip = ExprInt(uint32(f_ad)) cycles = 0 - + while True: cycles += 1 # max 5 instructions chain @@ -127,12 +212,11 @@ for f_ad in xrange(min_addr, max_addr): if not (min_addr < ad< max_addr): break in_str.offset = ad - l = x86_mn.dis(in_str) # print hex(my_eip.arg), l if not l: break - + args = [] my_eip.arg+=uint32(l.l) try: @@ -143,7 +227,7 @@ for f_ad in xrange(min_addr, max_addr): my_eip, mem_dst = emul_full_expr(ex, l, my_eip, None, machine) except: break - + for k in machine.pool: machine.pool[k] = expr_simp(machine.pool[k]) diff --git a/miasm/arch/arm_sem.py b/miasm/arch/arm_sem.py index c60b9cd0..de39f577 100644 --- a/miasm/arch/arm_sem.py +++ b/miasm/arch/arm_sem.py @@ -313,13 +313,15 @@ def rsbs(x, a, b): def adc(x, a, b): e= [] - c = ExprOp('+', a, ExprOp('+', b, ExprCompose([ExprSliceTo(ExprInt(uint32(0)), 1, a.get_size()), ExprSliceTo(cf, 0, 1)]))) + c = ExprOp('+', a, ExprOp('+', b, ExprCompose([(ExprInt(uint32(0)), 1, a.get_size()), + (cf, 0, 1)]))) e.append(ExprAff(x, c)) return e def adcs(x, a, b): e= [] - c = ExprOp('+', a, ExprOp('+', b, ExprCompose([ExprSliceTo(ExprInt(uint32(0)), 1, a.get_size()), ExprSliceTo(cf, 0, 1)]))) + c = ExprOp('+', a, ExprOp('+', b, ExprCompose([(ExprInt(uint32(0)), 1, a.get_size()), + (cf, 0, 1)]))) e+=update_flag_arith(c) e+=update_flag_add(a, b, c) e.append(ExprAff(x, c)) @@ -328,7 +330,8 @@ def adcs(x, a, b): def sbc(x, a, b): e= [] c = ExprOp('-', - ExprOp('+', a, ExprCompose([ExprSliceTo(ExprInt(uint32(0)), 1, a.get_size()), ExprSliceTo(cf, 0, 1)])), + ExprOp('+', a, ExprCompose([(ExprInt(uint32(0)), 1, a.get_size()), + (cf, 0, 1)])), ExprOp('+', b, ExprInt(uint32(1))) ) e.append(ExprAff(x, c)) @@ -337,7 +340,8 @@ def sbc(x, a, b): def sbcs(x, a, b): e= [] c = ExprOp('-', - ExprOp('+', a, ExprCompose([ExprSliceTo(ExprInt(uint32(0)), 1, a.get_size()), ExprSliceTo(cf, 0, 1)])), + ExprOp('+', a, ExprCompose([(ExprInt(uint32(0)), 1, a.get_size()), + (cf, 0, 1)])), ExprOp('+', b, ExprInt(uint32(1))) ) e+=update_flag_arith(c) diff --git a/miasm/arch/ia32_sem.py b/miasm/arch/ia32_sem.py index ac3ce1cf..c5441808 100644 --- a/miasm/arch/ia32_sem.py +++ b/miasm/arch/ia32_sem.py @@ -493,15 +493,15 @@ def xchg(info, a, b): return e def movzx(info, a, b): - return [ExprAff(a, ExprCompose([ExprSliceTo(ExprInt(uint32(0)), b.get_size(), a.get_size()), ExprSliceTo(b, 0, b.get_size())]))] + return [ExprAff(a, ExprCompose([(ExprInt(uint32(0)), b.get_size(), a.get_size()), + (b, 0, b.get_size())]))] def movsx(info, a, b): - return [ExprAff(a, ExprCompose([ExprSliceTo(ExprCond(ExprOp('==', get_op_msb(b), ExprInt(uint32(1))), - ExprInt(uint32(0xffffffff)), - ExprInt(uint32(0))), - b.get_size(), a.get_size()), - ExprSliceTo(b, - 0, b.get_size())]))] + return [ExprAff(a, ExprCompose([(ExprCond(ExprOp('==', get_op_msb(b), ExprInt(uint32(1))), + ExprInt(uint32(0xffffffff)), + ExprInt(uint32(0))), + b.get_size(), a.get_size()), + (b, 0, b.get_size())]))] def lea(info, a, b): return [ExprAff(a, b.arg)] @@ -531,7 +531,8 @@ def adc(info, a, b): a, ExprOp('+', b, - ExprCompose([ExprSliceTo(ExprInt(uint32(0)), 1, a.get_size()), ExprSliceTo(cf, 0, 1)]))) + ExprCompose([(ExprInt(uint32(0)), 1, a.get_size()), + (cf, 0, 1)]))) e+=update_flag_arith(c) e+=update_flag_af(c) e+=update_flag_add(a, b, c) @@ -554,7 +555,8 @@ def sbb(info, a, b): a, ExprOp('+', b, - ExprCompose([ExprSliceTo(ExprInt(uint32(0)), 1, a.get_size()), ExprSliceTo(cf, 0, 1)]))) + ExprCompose([(ExprInt(uint32(0)), 1, a.get_size()), + (cf, 0, 1)]))) e+=update_flag_arith(c) e+=update_flag_af(c) e+=update_flag_sub(a, b, c) @@ -1042,10 +1044,10 @@ def seto(info, a): def bswap(info, a): e = [] - c = ExprCompose([ExprSliceTo(ExprOp('&', ExprInt(tab_uintsize[a.get_size()](0xFF)), a), 24, 32), - ExprSliceTo(ExprOp('>>', ExprOp('&', ExprInt(tab_uintsize[a.get_size()](0xFF00)), a), ExprInt(uint32(8))), 16, 24), - ExprSliceTo(ExprOp('>>', ExprOp('&', ExprInt(tab_uintsize[a.get_size()](0xFF0000)), a), ExprInt(uint32(16))), 8 , 16), - ExprSliceTo(ExprOp('>>', ExprOp('&', ExprInt(tab_uintsize[a.get_size()](0xFF000000)), a), ExprInt(uint32(24))),0 , 8 ), + c = ExprCompose([(ExprOp('&', ExprInt(tab_uintsize[a.get_size()](0xFF)), a), 24, 32), + (ExprOp('>>', ExprOp('&', ExprInt(tab_uintsize[a.get_size()](0xFF00)), a), ExprInt(uint32(8))), 16, 24), + (ExprOp('>>', ExprOp('&', ExprInt(tab_uintsize[a.get_size()](0xFF0000)), a), ExprInt(uint32(16))), 8 , 16), + (ExprOp('>>', ExprOp('&', ExprInt(tab_uintsize[a.get_size()](0xFF000000)), a), ExprInt(uint32(24))),0 , 8 ), ]) e.append(ExprAff(a, c)) return e @@ -1077,9 +1079,9 @@ def compose_eflag(s = 32): regs = [cf, ExprInt(uint32(1)), pf, ExprInt(uint32(0)), af, ExprInt(uint32(0)), zf, nf, tf, i_f, df, of] for i in xrange(len(regs)): - args.append(ExprSliceTo(regs[i],i, i+1)) + args.append((regs[i],i, i+1)) - args.append(ExprSliceTo(iopl,12, 14)) + args.append((iopl,12, 14)) if s == 32: regs = [nt, ExprInt(uint32(0)), rf, vm, ac, vif, vip, i_d] @@ -1088,9 +1090,9 @@ def compose_eflag(s = 32): else: raise ValueError('unk size') for i in xrange(len(regs)): - args.append(ExprSliceTo(regs[i],i+14, i+15)) + args.append((regs[i],i+14, i+15)) if s == 32: - args.append(ExprSliceTo(ExprInt(uint32(0)),22, 32)) + args.append((ExprInt(uint32(0)),22, 32)) return ExprCompose(args) def pushfd(info): @@ -1410,7 +1412,8 @@ def div(info, a): #if 8 bit div, only ax is affected if s == 8: - e.append(ExprAff(eax[0:16], ExprCompose([ExprSliceTo(c_d, 0, 8), ExprSliceTo(c_r, 8, 16)]))) + e.append(ExprAff(eax[0:16], ExprCompose([(c_d, 0, 8), + (c_r, 8, 16)]))) else: e.append(ExprAff(s1, c_r)) e.append(ExprAff(s2, c_d)) @@ -1715,13 +1718,13 @@ def fninit(info): def fnstenv(info, a): e = [] # XXX TODO tag word, ... - status_word = ExprCompose([ExprSliceTo(ExprInt(uint32(0)), 0, 8), - ExprSliceTo(float_c0, 8, 9), - ExprSliceTo(float_c1, 9, 10), - ExprSliceTo(float_c2, 10, 11), - ExprSliceTo(float_stack_ptr, 11, 14), - ExprSliceTo(float_c3, 14, 15), - ExprSliceTo(ExprInt(uint32(0)), 15, 16), + status_word = ExprCompose([(ExprInt(uint32(0)), 0, 8), + (float_c0, 8, 9), + (float_c1, 9, 10), + (float_c2, 10, 11), + (float_stack_ptr, 11, 14), + (float_c3, 14, 15), + (ExprInt(uint32(0)), 15, 16), ]) w_size = tab_mode_size[info.opmode] @@ -1864,14 +1867,14 @@ def fabs(info): def fnstsw(info): dst = eax - return [ExprAff(dst, ExprCompose([ExprSliceTo(ExprInt(uint32(0)), 0, 8), - ExprSliceTo(float_c0, 8, 9), - ExprSliceTo(float_c1, 9, 10), - ExprSliceTo(float_c2, 10, 11), - ExprSliceTo(float_stack_ptr, 11, 14), - ExprSliceTo(float_c3, 14, 15), - ExprSliceTo(ExprInt(uint32(0)), 15, 16), - ExprSliceTo(ExprSlice(dst, 16, dst.get_size()), 16, dst.get_size()) + return [ExprAff(dst, ExprCompose([(ExprInt(uint32(0)), 0, 8), + (float_c0, 8, 9), + (float_c1, 9, 10), + (float_c2, 10, 11), + (float_stack_ptr, 11, 14), + (float_c3, 14, 15), + (ExprInt(uint32(0)), 15, 16), + (ExprSlice(dst, 16, dst.get_size()), 16, dst.get_size()) ]))] def fnstcw(info, a): @@ -1918,7 +1921,8 @@ def cbw(info, a): mask = ExprCond(ExprOp('==', get_op_msb(src), ExprInt(uint32(0))), byte_h_0, byte_h_f) e = [] - e.append(ExprAff(a, ExprCompose([ExprSliceTo(a, 0, s/2), ExprSliceTo(mask, s/2, s)]))) + e.append(ExprAff(a, ExprCompose([(a, 0, s/2), + (mask, s/2, s)]))) return e # XXX TODO @@ -2011,7 +2015,8 @@ def l_outs(info): # XXX actually, xlat performs al = (ds:[e]bx + ZeroExtend(al)) def xlat(info): e= [] - a = ExprCompose([ExprSliceTo(ExprInt(uint32(0)), 8, 32), ExprSliceTo(eax[0:8], 0, 8)]) + a = ExprCompose([(ExprInt(uint32(0)), 8, 32), + (eax[0:8], 0, 8)]) b = ExprMem(ExprOp('+', ebx, a), 8) e.append(ExprAff(eax[0:8], b)) return e @@ -2120,7 +2125,7 @@ def lahf(info): args = [] regs = [cf, ExprInt(uint32(1)), pf, ExprInt(uint32(0)), af, ExprInt(uint32(0)), zf, nf] for i in xrange(len(regs)): - args.append(ExprSliceTo(regs[i],i, i+1)) + args.append((regs[i],i, i+1)) e.append(ExprAff(eax[8:16], ExprCompose(args))) return e diff --git a/miasm/expression/expression.py b/miasm/expression/expression.py index 10b5ff8e..235a79b8 100644 --- a/miasm/expression/expression.py +++ b/miasm/expression/expression.py @@ -150,13 +150,11 @@ class ExprInt(Expr): def get_size(self): return 8*self.arg.nbytes def reload_expr(self, g = {}): + if self in g: + return g[self] return ExprInt(self.arg) def __contains__(self, e): return self == e - def replace_expr(self, g = {}): - if self in g: - return g[self] - return self def __eq__(self, a): if not isinstance(a, ExprInt): return False @@ -187,15 +185,8 @@ class ExprId(Expr): return g[self] else: return ExprId(self.name, self.size) - if self in g: - return g[self] - return self def __contains__(self, e): return self == e - def replace_expr(self, g = {}): - if self in g: - return g[self] - return self def __eq__(self, a): if not isinstance(a, ExprId): return False @@ -220,10 +211,10 @@ class ExprAff(Expr): #if dst is slice=> replace with id make composed src if isinstance(dst, ExprSlice): self.dst = dst.arg - rest = [ExprSliceTo(ExprSlice(dst.arg, *r), *r) for r in slice_rest(dst.arg.size, dst.start, dst.stop)] - all_a = [(dst.start, ExprSliceTo(src, dst.start, dst.stop))]+ [(x.start, x) for x in rest] - all_a.sort() - self.src = ExprCompose([x[1] for x in all_a]) + rest = [(ExprSlice(dst.arg, r[0], r[1]), r[0], r[1]) for r in slice_rest(dst.arg.size, dst.start, dst.stop)] + all_a = [(src, dst.start, dst.stop)] + rest + all_a.sort(key=lambda x:x[1]) + self.src = ExprCompose(all_a) else: self.dst, self.src = dst,src def __str__(self): @@ -241,21 +232,11 @@ class ExprAff(Expr): def reload_expr(self, g = {}): if self in g: return g[self] - dst = self.dst - if isinstance(dst, Expr): - dst = self.dst.reload_expr(g) - src = self.src - if isinstance(src, Expr): - src = self.src.reload_expr(g) + dst = self.dst.reload_expr(g) + src = self.src.reload_expr(g) return ExprAff(dst, src ) def __contains__(self, e): return self == e or self.src.__contains__(e) or self.dst.__contains__(e) - def replace_expr(self, g = {}): - if self in g: - return g[self] - dst = self.dst.replace_expr(g) - src = self.src.replace_expr(g) - return ExprAff(dst, src) def __eq__(self, a): if not isinstance(a, ExprAff): return False @@ -271,7 +252,7 @@ class ExprAff(Expr): raise ValueError("get mod slice not on expraff slice", str(self)) modified_s = [] for x in self.src.args: - if not isinstance(x.arg, ExprSlice) or x.arg.arg != dst or x.start != x.arg.start or x.stop != x.arg.stop: + if not isinstance(x[0], ExprSlice) or x[0].arg != dst or x[1] != x[0].start or x[2] != x[0].stop: modified_s.append(x) return modified_s def canonize(self): @@ -293,23 +274,10 @@ class ExprCond(Expr): def reload_expr(self, g = {}): if self in g: return g[self] - src1 = self.src1 - if isinstance(src1, Expr): - src1 = self.src1.reload_expr(g) - src2 = self.src2 - if isinstance(src2, Expr): - src2 = self.src2.reload_expr(g) - cond = self.cond - if isinstance(cond, Expr): - cond = self.cond.reload_expr(g) - return ExprCond(cond, src1, src2 ) - def replace_expr(self, g = {}): - if self in g: - return g[self] - cond = self.cond.replace_expr(g) - src1 = self.src1.replace_expr(g) - src2 = self.src2.replace_expr(g) - return ExprCond(cond, src1, src2 ) + cond = self.cond.reload_expr(g) + src1 = self.src1.reload_expr(g) + src2 = self.src2.reload_expr(g) + return ExprCond(cond, src1, src2) def __contains__(self, e): return self == e or self.cond.__contains__(e) or self.src1.__contains__(e) or self.src2.__contains__(e) def __eq__(self, a): @@ -346,20 +314,13 @@ class ExprMem(Expr): def reload_expr(self, g = {}): if self in g: return g[self] - arg = self.arg + arg = self.arg.reload_expr(g) segm = self.segm - if isinstance(arg, Expr): - arg = self.arg.reload_expr(g) if isinstance(segm, Expr): segm = self.segm.reload_expr(g) - return ExprMem(arg, self.size, segm) + return ExprMem(arg, self.size, self.segm) def __contains__(self, e): return self == e or self.arg.__contains__(e) - def replace_expr(self, g = {}): - if self in g: - return g[self] - arg = self.arg.replace_expr(g) - return ExprMem(arg, self.size, self.segm) def __eq__(self, a): if not isinstance(a, ExprMem): return False @@ -400,10 +361,7 @@ class ExprOp(Expr): return g[self] args = [] for a in self.args: - if isinstance(a, Expr): - args.append(a.reload_expr(g)) - else: - args.append(a) + args.append(a.reload_expr(g)) return ExprOp(self.op, *args ) def __contains__(self, e): if self == e: @@ -412,13 +370,6 @@ class ExprOp(Expr): if a.__contains__(e): return True return False - def replace_expr(self, g = {}): - if self in g: - return g[self] - args = [] - for a in self.args: - args.append(a.replace_expr(g)) - return ExprOp(self.op, *args ) def __eq__(self, a): if not isinstance(a, ExprOp): return False @@ -580,6 +531,8 @@ class ExprSlice(Expr): def get_size(self): return self.stop-self.start def reload_expr(self, g = {}): + if self in g: + return g[self] arg = self.arg.reload_expr(g) return ExprSlice(arg, self.start, self.stop ) def __contains__(self, e): @@ -589,11 +542,6 @@ class ExprSlice(Expr): if a.__contains__(e): return True return False - def replace_expr(self, g = {}): - if self in g: - return g[self] - arg = self.arg.replace_expr(g) - return ExprSlice(arg, self.start, self.stop ) def __eq__(self, a): if not isinstance(a, ExprSlice): return False @@ -608,79 +556,34 @@ class ExprSlice(Expr): self.start, self.stop) -class ExprSliceTo(Expr): - def __init__(self, arg, start, stop): - self.arg, self.start, self.stop = arg, start, stop - def __str__(self): - return "%s_to[%d:%d]"%(str(self.arg), self.start, self.stop) - def get_r(self, mem_read=False): - return self.arg.get_r(mem_read) - def get_w(self): - return self.arg.get_w() - def get_size(self): - return self.stop-self.start - def reload_expr(self, g = {}): - if isinstance(self.arg, Expr): - arg = self.arg.reload_expr(g) - else: - arg = self.arg - return ExprSliceTo(arg, self.start, self.stop ) - def __contains__(self, e): - return self == e or self.arg.__contains__(e) - def replace_expr(self, g = {}): - if self in g: - return g[self] - arg = self.arg.replace_expr(g) - return ExprSliceTo(arg, self.start, self.stop) - def __eq__(self, a): - if not isinstance(a, ExprSliceTo): - return False - return self.arg == a.arg and self.start == a.start and self.stop == a.stop - def __hash__(self): - return hash(self.arg)^hash(self.start)^hash(self.stop) - def toC(self): - # XXX gen mask in python for 64 bit & 32 bit compat - return "((%s & (0xFFFFFFFF>>(32-%d))) << %d)"%(self.arg.toC(), self.stop-self.start, self.start) - def canonize(self): - return ExprSliceTo(self.arg.canonize(), - self.start, - self.stop) class ExprCompose(Expr): def __init__(self, args): self.args = args def __str__(self): - return '('+', '.join([str(x) for x in self.args])+')' + return '('+', '.join(['%s,%d,%d'%(str(x[0]), x[1], x[2]) for x in self.args])+')' def get_r(self, mem_read=False): - return reduce(lambda x,y:x.union(y.get_r(mem_read)), self.args, set()) + return reduce(lambda x,y:x.union(y[0].get_r(mem_read)), self.args, set()) def get_w(self): - return reduce(lambda x,y:x.union(y.get_r(mem_read)), self.args, set()) + return reduce(lambda x,y:x.union(y[0].get_r(mem_read)), self.args, set()) def get_size(self): - return max([x.stop for x in self.args]) - min([x.start for x in self.args]) + return max([x[2] for x in self.args]) - min([x[1] for x in self.args]) def reload_expr(self, g = {}): if self in g: return g[self] args = [] for a in self.args: - if isinstance(a, Expr): - args.append(a.reload_expr(g)) - else: - args.append(a) + args.append(a[0].reload_expr(g), a[1], a[2]) return ExprCompose(args ) def __contains__(self, e): if self == e: return True for a in self.args: - if a.__contains__(e): + if a == e: + return True + if a[0].__contains__(e): return True return False - def replace_expr(self, g = {}): - if self in g: - return g[self] - args = [] - for a in self.args: - args.append(a.replace_expr(g)) - return ExprCompose(args ) def __eq__(self, a): if not isinstance(a, ExprCompose): return False @@ -693,13 +596,22 @@ class ExprCompose(Expr): def __hash__(self): h = 0 for a in self.args: - h^=hash(a) + h^=hash(a[0])^hash(a[1])^hash(a[2]) return h def toC(self): - out = ' | '.join([x.toC() for x in self.args]) + out = [] + # XXX check mask for 64 bit & 32 bit compat + for x in self.args: + o.append("((%s & %X) << %d)"%(x[0].toC(), + (1<<(x[2]-x[1]))-1, + x[1])) + out = ' | '.join(out) return '('+out+')' def canonize(self): - return ExprCompose(canonize_expr_list([x.canonize() for x in self.args])) + o = [] + for x in self.args: + o.append((x[0].canonize(), x[1], x[2])) + return ExprCompose(canonize_expr_list_compose(o)) class set_expr: def __init__(self, l = []): @@ -751,14 +663,22 @@ expr_order_dict = {ExprId: 1, ExprMem: 3, ExprOp: 4, ExprSlice: 5, - ExprSliceTo: 6, ExprCompose: 7, ExprInt: 8, } -def compare_exprs_list(l1_e, l2_e): - for i in xrange(min(len(l1_e, l2_e))): - x = expr_compare(l1_e[i], l2_e[i]) +def compare_exprs_compose(e1, e2): + # sort by start bit address, then expr then stop but address + x = cmp(e1[1], e2[1]) + if x: return x + x = compare_exprs(e1[0], e2[0]) + if x: return x + x = cmp(e1[2], e2[2]) + return x + +def compare_expr_list_compose(l1_e, l2_e): + for i in xrange(min(len(l1_e), len(l2_e))): + x = compare_exprs_compose(l1_e, l2_e) if x: return x return cmp(len(l1_e), len(l2_e)) @@ -803,15 +723,8 @@ def compare_exprs(e1, e2): if x: return x x = cmp(e1.stop, e2.stop) return x - elif c1 == ExprSliceTo: - x = compare_exprs(e1.arg, e2.arg) - if x: return x - x = cmp(e1.start, e2.start) - if x: return x - x = cmp(e1.stop, e2.stop) - return x elif c1 == ExprCompose: - return compare_exprs_list(e1.arg, e2.arg) + return compare_expr_list_compose(e1.args, e2.args) raise ValueError("not imppl %r %r"%(e1, e2)) @@ -820,3 +733,8 @@ def canonize_expr_list(l): l = l[:] l.sort(cmp=compare_exprs) return l + +def canonize_expr_list_compose(l): + l = l[:] + l.sort(cmp=compare_exprs_compose) + return l diff --git a/miasm/expression/expression_eval_abstract.py b/miasm/expression/expression_eval_abstract.py index 809c72fd..5e2d397b 100644 --- a/miasm/expression/expression_eval_abstract.py +++ b/miasm/expression/expression_eval_abstract.py @@ -599,13 +599,13 @@ class eval_abs: m = min(a.get_size(), x.get_size()-off*8) ee = ExprSlice(self.pool[x], off*8, off*8 + m) ee = expr_simp(ee) - out.append(ExprSliceTo(ee, off_base, off_base+ee.get_size())) + out.append((ee, off_base, off_base+ee.get_size())) off_base += ee.get_size() else: m = min(a.get_size()+off*8, x.get_size()) ee = ExprSlice(self.pool[x], 0, m) ee = expr_simp(ee) - out.append(ExprSliceTo(ee, off_base, off_base+ee.get_size())) + out.append((ee, off_base, off_base+ee.get_size())) off_base += ee.get_size() if out: ee = ExprSlice(ExprCompose(out), 0, a.get_size()) @@ -636,7 +636,7 @@ class eval_abs: else: diff_size = rest val = self.pool[v][0:diff_size] - val = ExprSliceTo(val, ptr_index, ptr_index+diff_size) + val = (val, ptr_index, ptr_index+diff_size) out.append(val) ptr_index+=diff_size rest -= diff_size @@ -738,7 +738,7 @@ class eval_abs: if not is_int and is_int_cond!=1: - uu = ExprCompose([ExprSliceTo(a, e.args[i].start, e.args[i].stop) for i, a in enumerate(args)]) + uu = ExprCompose([(a, e.args[i][1], e.args[i][2]) for i, a in enumerate(args)]) return uu if not is_int: @@ -749,15 +749,15 @@ class eval_abs: if isinstance(args[i], ExprInt): a = args[i].arg - mask = (1<<(e.args[i].stop-e.args[i].start))-1 + mask = (1<<(e.args[i][2]-e.args[i][1]))-1 a&=mask - a<<=e.args[i].start - total_bit+=e.args[i].stop-e.args[i].start + a<<=e.args[i][1] + total_bit+=e.args[i][2]-e.args[i][1] rez|=a else: a = args[i] - mask = (1<<(e.args[i].stop-e.args[i].start))-1 - total_bit+=e.args[i].stop-e.args[i].start + mask = (1<<(e.args[i][2]-e.args[i][1]))-1 + total_bit+=e.args[i][2]-e.args[i][1] mycond, mysrc1, mysrc2 = a.cond, a.src1.arg&mask, a.src2.arg&mask cond_i = i @@ -767,7 +767,9 @@ class eval_abs: if total_bit in tab_uintsize: - return self.eval_expr(ExprCond(mycond, ExprInt(tab_uintsize[total_bit](mysrc1)), ExprInt(tab_uintsize[total_bit](mysrc2))), eval_cache) + return self.eval_expr(ExprCond(mycond, + ExprInt(tab_uintsize[total_bit](mysrc1)), + ExprInt(tab_uintsize[total_bit](mysrc2))), eval_cache) else: raise 'cannot return non rounb bytes rez! %X %X'%(total_bit, rez) @@ -777,10 +779,10 @@ class eval_abs: total_bit = 0 for i in xrange(len(e.args)): a = args[i].arg - mask = (1<<(e.args[i].stop-e.args[i].start))-1 + mask = (1<<(e.args[i][2]-e.args[i][1]))-1 a&=mask - a<<=e.args[i].start - total_bit+=e.args[i].stop-e.args[i].start + a<<=e.args[i][1] + total_bit+=e.args[i][2]-e.args[i][1] rez|=a if total_bit in tab_uintsize: return ExprInt(tab_uintsize[total_bit](rez)) diff --git a/miasm/expression/expression_helper.py b/miasm/expression/expression_helper.py index 324c1ca8..8cf422bb 100644 --- a/miasm/expression/expression_helper.py +++ b/miasm/expression/expression_helper.py @@ -39,56 +39,53 @@ def merge_sliceto_slice(args): non_slice = {} sources_int = {} for a in args: - if isinstance(a.arg, ExprInt): + if isinstance(a[0], ExprInt): #sources_int[a.start] = a # copy ExprInt because we will inplace modify arg just below # /!\ TODO XXX never ever modify inplace args... - sources_int[a.start] = ExprSliceTo(ExprInt(a.arg.arg.__class__(a.arg.arg)), a.start, a.stop) - elif isinstance(a.arg, ExprSlice): - if not a.arg.arg in sources: - sources[a.arg.arg] = [] - sources[a.arg.arg].append(a) + sources_int[a[1]] = (ExprInt(a[0].arg.__class__(a[0].arg)), + a[1], + a[2]) + elif isinstance(a[0], ExprSlice): + if not a[0].arg in sources: + sources[a[0].arg] = [] + sources[a[0].arg].append(a) else: - non_slice[a.start] = a + non_slice[a[1]] = a #find max stop to determine size max_size = None for a in args: - if max_size == None or max_size < a.stop: - max_size = a.stop - - + if max_size == None or max_size < a[2]: + max_size = a[2] #first simplify all num slices - final_sources = [] sorted_s = [] for x in sources_int.values(): #mask int - v = x.arg.arg & ((1<<(x.stop-x.start))-1) - x.arg.arg = v - sorted_s.append((x.start, x)) + v = x[0].arg & ((1<<(x[2]-x[1]))-1) + x[0].arg = v + sorted_s.append((x[1], x)) sorted_s.sort() - while sorted_s: + while sorted_s: start, v = sorted_s.pop() - out = expr_replace(v, {}) - - + out = e.reload_expr() while sorted_s: - if sorted_s[-1][1].stop != start: + if sorted_s[-1][1][2] != start: break - start = sorted_s[-1][1].start + start = sorted_s[-1][1][1] - a = uint64((int(out.arg.arg) << (out.start - start )) + sorted_s[-1][1].arg.arg) + a = uint64((int(out[0].arg) << (out[1] - start )) + sorted_s[-1][1][0].arg) out.arg = ExprInt(uint32(a)) sorted_s.pop() - out.start = start + out[1] = start out_type = tab_size_int[max_size] - out.arg.arg = out_type(out.arg.arg) + out[0].arg = out_type(out[0].arg) final_sources.append((start, out)) final_sources_int = final_sources @@ -100,21 +97,21 @@ def merge_sliceto_slice(args): final_sources = [] sorted_s = [] for x in args: - sorted_s.append((x.start, x)) + sorted_s.append((x[1], x)) sorted_s.sort() while sorted_s: start, v = sorted_s.pop() - out = expr_replace(v, {}) + out = v[0].reload_expr(), v[1], v[2] while sorted_s: - if sorted_s[-1][1].stop != start: + if sorted_s[-1][1][2] != start: break - if sorted_s[-1][1].arg.stop != out.arg.start: + if sorted_s[-1][1][0].stop != out[0].start: break - start = sorted_s[-1][1].start - out.arg.start = sorted_s[-1][1].arg.start + start = sorted_s[-1][1][1] + out[0].start = sorted_s[-1][1][0].start sorted_s.pop() - out.start = start + out = out[0], start, out[2] final_sources.append((start, out)) @@ -457,7 +454,7 @@ def expr_simp_w(e): #! (compose a b c) => (compose !a !b !c) if op == '!' and isinstance(args[0], ExprCompose): - args = [ExprSliceTo(ExprOp('!', x.arg), x.start, x.stop) for x in args[0].args] + args = [(ExprOp('!', x.arg), x[1], x[2]) for x in args[0].args] new_e = ExprCompose(args) return expr_simp(new_e) #!a[0:X] => (!a)[0:X] @@ -526,8 +523,8 @@ def expr_simp_w(e): return expr_simp(new_e) elif isinstance(arg, ExprCompose): for a in arg.args: - if a.start <= e.start and a.stop>=e.stop: - new_e = a.arg[e.start-a.start:e.stop-a.start] + if a[1] <= e.start and a[2]>=e.stop: + new_e = a[0][e.start-a[1]:e.stop-a[1]] new_e = expr_simp(new_e) return new_e elif isinstance(arg, ExprOp) and e.start == 0: @@ -538,7 +535,7 @@ def expr_simp_w(e): elif isinstance(arg, ExprMem) and e.start == 0 and arg.size == e.stop: e = expr_simp(arg) return e - #XXXX hum, is it safe? + #XXXX todo hum, is it safe? elif isinstance(arg, ExprMem) and e.start == 0 and arg.size > e.stop and e.stop %8 == 0: e = expr_simp(ExprMem(e.arg.arg, size = e.stop)) return e @@ -547,6 +544,8 @@ def expr_simp_w(e): return ExprSlice(arg, e.start, e.stop) + """ + XXX todo move to exprcompose elif isinstance(e, ExprSliceTo): if isinstance(e.arg, ExprTop): return ExprTop() @@ -563,9 +562,10 @@ def expr_simp_w(e): return ExprSliceTo(expr_simp(e.arg), e.start, e.stop) + """ elif isinstance(e, ExprCompose): #(.., a_to[x:y], a[:]_to[y:z], ..) => (.., a[x:z], ..) - e = ExprCompose([expr_simp(x) for x in e.args]) + e = ExprCompose([(expr_simp(x[0]), x[1], x[2]) for x in e.args]) args = [] i = -1 simp = False @@ -574,19 +574,21 @@ def expr_simp_w(e): if not args: args.append(e.args[i]) continue - if args[-1].stop != e.args[i].start: + if args[-1][2] != e.args[i][1]: continue - if not isinstance(e.args[i].arg, ExprSlice): + if not isinstance(e.args[i][0], ExprSlice): continue - if isinstance(args[-1].arg, ExprSlice): + if isinstance(args[-1][0], ExprSlice): a = args[-1] else: - a = ExprSliceTo(ExprSlice(args[-1].arg, 0, args[-1].arg.get_size()), args[-1].start, args[-1].stop) - if a.arg.arg != e.args[i].arg.arg: + a = (ExprSlice(args[-1][0], 0, args[-1][0].get_size()), + args[-1][1], + args[-1][2]) + if a[0].arg != e.args[i][0].arg: continue - if a.stop != e.args[i].start: + if a[2] != e.args[i][1]: continue - args[-1] = ExprSliceTo(e.args[i].arg.arg, a.start, e.args[i].stop) + args[-1] = (e.args[i][0].arg, a[1], e.args[i][2]) simp = True if simp: @@ -609,26 +611,24 @@ def expr_simp_w(e): args = merge_sliceto_slice(e.args) if len(args) == 1: a = args[0] - if isinstance(a.arg, ExprInt): - if a.arg.get_size() != a.stop: - print a, a.arg.get_size(), a.stop - raise ValueError("cast in compose!", e) - return a.arg - - uu = expr_simp(a.arg) + if isinstance(a[0], ExprInt): + if a[0].get_size() != a[2]: + print a, a[0].get_size(), a[2] + raise ValueError("todo cast in compose!", e) + return a[0] + uu = expr_simp(a[0][:e.get_size()]) return uu if len(args) != len(e.args): return expr_simp(ExprCompose(args)) else: return ExprCompose(args) - else: raise 'bad expr' def expr_cmp(e1, e2): return str(e1) == str(e2) - +""" #replace id by another in expr def expr_replace(e, repl): if isinstance(e, ExprInt): @@ -647,12 +647,11 @@ def expr_replace(e, repl): return ExprOp(e.op, *[expr_replace(x, repl) for x in e.args]) elif isinstance(e, ExprSlice): return ExprSlice(expr_replace(e.arg, repl), e.start, e.stop) - elif isinstance(e, ExprSliceTo): - return ExprSliceTo(expr_replace(e.arg, repl), e.start, e.stop) elif isinstance(e, ExprCompose): - return ExprCompose([expr_replace(x, repl) for x in e.args]) + return ExprCompose([(expr_replace(x[0], repl), x[1], x[2]) for x in e.args]) else: - raise 'bad expr' + raise ValueError('bad expr', e) +""" diff --git a/miasm/tools/to_c_helper.py b/miasm/tools/to_c_helper.py index b9437b15..b7b387df 100644 --- a/miasm/tools/to_c_helper.py +++ b/miasm/tools/to_c_helper.py @@ -308,11 +308,11 @@ def Exp2C(exprs, l = None, addr2label = None, gen_exception_code = False): #spotted multi affectation to same id e_colision = reduce(lambda x,y:x+y, [e.get_modified_slice() for e in exs]) #print [str(x) for x in e_colision] - known_intervals = [(x.start, x.stop) for x in e_colision] + known_intervals = [(x[1], x[2]) for x in e_colision] #print known_intervals missing_i = get_missing_interval(known_intervals) #print missing_i - rest = [ExprSliceTo(ExprSlice(dst, *r), *r) for r in missing_i] + rest = [(ExprSlice(dst, r[0], r[1]), r[0], r[1]) for r in missing_i] final_dst = ExprCompose(e_colision+ rest) new_expr.append(ExprAff(dst, final_dst)) out_mem = [] @@ -936,7 +936,7 @@ if __name__ == '__main__': print x print '#'*80 - new_e = [x.replace_expr({ExprMem(eax): ExprId('ioio')}) for x in e] + new_e = [x.reload_expr({ExprMem(eax): ExprId('ioio')}) for x in e] for x in new_e: print x print '-'*80 |