about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorserpilliere <devnull@localhost>2012-05-09 13:53:30 +0200
committerserpilliere <devnull@localhost>2012-05-09 13:53:30 +0200
commit6008b0fe75024316529e485500f063cd6c1f6720 (patch)
tree06a6ccf819f36512db541f1d2cf71fb2eca56908
parent7a4f30ca4eaba66b094d295ca47bf1b4e37a67c9 (diff)
parentfa759c1f8f527c3ca8e6cce4032aad1efded4618 (diff)
downloadmiasm-6008b0fe75024316529e485500f063cd6c1f6720.tar.gz
miasm-6008b0fe75024316529e485500f063cd6c1f6720.zip
merge
Diffstat (limited to '')
-rw-r--r--doc/slides.tex1
-rw-r--r--example/expression/manip_expression3.py5
-rw-r--r--example/expression/manip_expression5.py12
-rw-r--r--example/find_rop.py118
-rw-r--r--miasm/arch/arm_arch.py1
-rw-r--r--miasm/arch/arm_sem.py12
-rw-r--r--miasm/arch/ia32_arch.py21
-rw-r--r--miasm/arch/ia32_sem.py218
-rw-r--r--miasm/arch/ppc_arch.py169
-rw-r--r--miasm/core/asmbloc.py5
-rw-r--r--miasm/expression/expression.py194
-rw-r--r--miasm/expression/expression_eval_abstract.py28
-rw-r--r--miasm/expression/expression_helper.py111
-rwxr-xr-xmiasm/graph/graph_qt.py11
-rwxr-xr-xmiasm/tools/emul_helper.py22
-rw-r--r--miasm/tools/emul_lib/libcodenat.h9
-rw-r--r--miasm/tools/to_c_helper.py10
17 files changed, 562 insertions, 385 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_arch.py b/miasm/arch/arm_arch.py
index 258ad933..5cffb5d7 100644
--- a/miasm/arch/arm_arch.py
+++ b/miasm/arch/arm_arch.py
@@ -880,6 +880,7 @@ class arm_mn(object):
         self.l = 4
         self.m = None
         self.arg = []
+        self.cmt = ""
 
 
 
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_arch.py b/miasm/arch/ia32_arch.py
index 2d20d2d5..5509a7c6 100644
--- a/miasm/arch/ia32_arch.py
+++ b/miasm/arch/ia32_arch.py
@@ -161,7 +161,8 @@ unsanity_mnemo = ['nop', 'monitor', 'mwait', 'fadd', 'faddp', 'fiadd', 'fcmovb',
                   'fdiv', 'fdivr', 'fidivr', 'fdivrp', 'ficom', 'ficomp', 'fild', 'fist', 'fistp', 'fisttp',
                   'fld', 'fldcw', 'fld1', 'fldl2t', "fldl2e", "fldpi", "fldlg2", "fldln2", "fldz", 'fldenv', 'fmul', 'fimul', 'fmulp', 'fst', 'fstp', 'fnstcw', 'fnstenv', 'f2xm1',
                   'fnstsw', 'fsub', 'fsubr', 'fisubr', 'fsubrp', 'ftst', 'fucom', 'fucompp', 'fxam', 'fxtract', 'fyl2x', 'fyl2xp1', 'fsqrt', 'fsincos', 'fsin', 'fscale',
-                  'fcos', 'fdecstp', 'fnop', 'fpatan', 'fprem', 'fprem1', 'fptan', 'frndint', "shl", 'sal', 'sar', 'fabs']
+                  'fcos', 'fdecstp', 'fnop', 'fpatan', 'fprem', 'fprem1', 'fptan', 'frndint', "shl", 'sal', 'sar', 'fabs',
+                  "jmpff"]
 
 
 mask_drcrsg = {cr:0x100, dr:0x200, sg:0x400}
@@ -848,6 +849,7 @@ class x86allmncs:
         addop("jecxz", [0xE3],             noafs, [s08]         , {}                 ,{}                , {bkf:True,spf:True,dtf:True})
 
         addop("jmp",   [0xE9],             noafs, [ims]         , {w8:(0,1)}         ,{w8:False}        , {bkf:True,dtf:True}         )
+        addop("jmpf",   [0xEa],             noafs, [ims,u16]       ,{}                  ,{}        , {bkf:True,dtf:True}         )
         addop("jmp",   [0xFF],             d4   , no_rm         , {}                 ,{}                , {bkf:True,dtf:True}         )
         addop("jmpf",  [0xFF],             d5   , no_rm         , {}                 ,{}                , {bkf:True,dtf:True}         )
 
@@ -1348,6 +1350,7 @@ class x86_mn:
         self.admode = admode
         self.opmode = opmode
         self.mnemo_mode = self.opmode
+        self.cmt = ""
 
     @classmethod
     def prefix2hex(self, prefix):
@@ -1425,7 +1428,11 @@ class x86_mn:
                 args_str+="%s, "%dict_to_ad(a, self.m.modifs, self.opmode, self.admode)
             else:
                 raise ValueError("arg zarbi %s"%str(a))
-        return args_str[:-2]
+
+        o = args_str[:-2]
+        if self.cmt:
+            o = "%-50s%s"%(o, self.cmt)
+        return o
 
     def intsize(self, im, ext = False):
         if ext:
@@ -2268,6 +2275,16 @@ if __name__ == '__main__':
     test_out = []
     log.setLevel(logging.DEBUG)
 
+    instr = x86mnemo.dis('ea21060000'.replace(' ', '').decode('hex'),
+                         admode=x86_afs.u16,
+                         opmode=x86_afs.u16)
+    print instr
+    print instr.arg
+    print instr.l
+    print instr.opmode, instr.admode
+    fds
+
+
     instr = x86mnemo.dis('0fbe13'.replace(' ', '').decode('hex'),)
                          #admode=x86_afs.u16,
                          #opmode=x86_afs.u16)
diff --git a/miasm/arch/ia32_sem.py b/miasm/arch/ia32_sem.py
index 2299f02b..3800ffce 100644
--- a/miasm/arch/ia32_sem.py
+++ b/miasm/arch/ia32_sem.py
@@ -88,6 +88,10 @@ reg_float_c2 = 'float_c2'
 reg_float_c3 = 'float_c3'
 reg_float_stack_ptr = "float_stack_ptr"
 reg_float_control = 'reg_float_control'
+reg_float_eip = 'reg_float_eip'
+reg_float_cs = 'reg_float_cs'
+reg_float_address = 'reg_float_address'
+reg_float_ds = 'reg_float_ds'
 
 
 reg_float_st0 = 'float_st0'
@@ -237,6 +241,10 @@ float_c2 = ExprId(reg_float_c2)
 float_c3 = ExprId(reg_float_c3)
 float_stack_ptr = ExprId(reg_float_stack_ptr)
 float_control = ExprId(reg_float_control)
+float_eip = ExprId(reg_float_eip)
+float_cs = ExprId(reg_float_cs, size=16)
+float_address = ExprId(reg_float_address)
+float_ds = ExprId(reg_float_ds, size=16)
 
 float_st0 = ExprId(reg_float_st0, 64)
 float_st1 = ExprId(reg_float_st1, 64)
@@ -334,6 +342,10 @@ all_registers = [
     float_c3 ,
     float_stack_ptr ,
     float_control ,
+    float_eip ,
+    float_cs ,
+    float_address ,
+    float_ds ,
 
     float_st0 ,
     float_st1 ,
@@ -357,6 +369,14 @@ tab_uintsize ={8:uint8,
                64:uint64
                }
 
+tab_mode ={'u16':uint16,
+           'u32':uint32,
+           }
+
+tab_mode_size ={'u16':16,
+                'u32':32,
+                }
+
 tab_afs_int ={x86_afs.u08:uint8,
               x86_afs.u16:uint16,
               x86_afs.u32:uint32,
@@ -455,6 +475,13 @@ def update_flag_sub(x, y, z):
     e.append(update_flag_sub_of(cast_int, x, y, z))
     return e
 
+def set_float_cs_eip(info):
+    e = []
+    # XXX TODO check float updt
+    cast_int = tab_mode[info.opmode]
+    e.append(ExprAff(float_eip, ExprInt(cast_int(info.offset))))
+    e.append(ExprAff(float_cs, cs))
+    return e
 
 def mov(info, a, b):
     return [ExprAff(a, b)]
@@ -466,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)]
@@ -504,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)
@@ -527,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)
@@ -631,14 +660,14 @@ def rcr(info, a, b):
     ### hack (only valid if b=1)
     e.append(ExprAff(of, ExprOp("^", get_op_msb(a), get_op_msb(c))))
     e.append(ExprAff(a, c))
-    
+
     return e
 
 def sar(info, a, b):
     e= []
     cast_int = tab_uintsize[a.get_size()]
     cast_intb = tab_uintsize[b.get_size()]
-    
+
     shifter = ExprOp('&',b, ExprInt(cast_intb(0x1f)))
     c = ExprOp('a>>', a, shifter)
 
@@ -1021,10 +1050,10 @@ def setalc(info):
 
 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
@@ -1056,9 +1085,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]
@@ -1067,9 +1096,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):
@@ -1120,7 +1149,7 @@ def popfw(info):
 
 def pushad(info):
     e = []
-    opmode, admode = info
+    opmode, admode = info.opmode, info.admode
     if opmode == u16:
         s = 16
         myesp = esp[:16]
@@ -1139,7 +1168,7 @@ def pushad(info):
 
 def popad(info):
     e = []
-    opmode, admode = info
+    opmode, admode = info.opmode, info.admode
     if opmode == u16:
         s = 16
         myesp = esp[:16]
@@ -1165,7 +1194,7 @@ def popad(info):
 
 def call(info, a, b):
     e= []
-    opmode, admode = info
+    opmode, admode = info.opmode, info.admode
     if opmode == u16:
         s = 16
         myesp = esp[:16]
@@ -1182,7 +1211,7 @@ def call(info, a, b):
 
 def ret(info, a = ExprInt(uint32(0))):
     e = []
-    opmode, admode = info
+    opmode, admode = info.opmode, info.admode
     if opmode == u16:
         s = 16
         myesp = esp[:16]
@@ -1196,7 +1225,7 @@ def ret(info, a = ExprInt(uint32(0))):
 
 def retf(info, a = ExprInt(uint32(0))):
     e = []
-    opmode, admode = info
+    opmode, admode = info.opmode, info.admode
     if opmode == u16:
         s = 16
         myesp = esp[:16]
@@ -1213,7 +1242,7 @@ def retf(info, a = ExprInt(uint32(0))):
     return e
 
 def leave(info):
-    opmode, admode = info
+    opmode, admode = info.opmode, info.admode
     if opmode == u16:
         s = 16
         myesp = esp[:16]
@@ -1230,7 +1259,7 @@ def leave(info):
     return e
 
 def enter(info, a,b):
-    opmode, admode = info
+    opmode, admode = info.opmode, info.admode
     if opmode == u16:
         s = 16
         myesp = esp[:16]
@@ -1259,6 +1288,13 @@ def jmp(info, a):
     e.append(ExprAff(eip, a))
     return e
 
+def jmpf(info, a, seg):
+    e= []
+    e.append(ExprAff(eip, a))
+    e.append(ExprAff(cs, seg))
+    return e
+
+
 def jz(info, a, b):
     e= []
     e.append(ExprAff(eip, ExprCond(ExprOp('==', zf, ExprInt(uint32(1))), b, a)))
@@ -1382,7 +1418,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))
@@ -1482,7 +1519,7 @@ def imul(info, a, b = None, c = None):
 
 def cdq(info):
     # XXX to check
-    opmode, admode = info
+    opmode, admode = info.opmode, info.admode
     if opmode == u32:
         e = []
         e.append(ExprAff(edx,
@@ -1569,14 +1606,20 @@ def fcom(info, a):
     e.append(ExprAff(float_c1, ExprOp('fcom_c1', float_st0, src)))
     e.append(ExprAff(float_c2, ExprOp('fcom_c2', float_st0, src)))
     e.append(ExprAff(float_c3, ExprOp('fcom_c3', float_st0, src)))
+
+    e += set_float_cs_eip(info)
     return e
 
 def ficom(info, a):
-    return []
+    e = []
+    e += set_float_cs_eip(info)
+    return e
 
 def fcomp(info, a):
     e= fcom(a)
     e+=float_pop()
+
+    e += set_float_cs_eip(info)
     return e
 
 def fld(info, a):
@@ -1595,6 +1638,8 @@ def fld(info, a):
     e.append(ExprAff(float_st1, float_st0))
     e.append(ExprAff(float_st0, src))
     e.append(ExprAff(float_stack_ptr, ExprOp('+', float_stack_ptr, ExprInt(uint32(1)))))
+
+    e += set_float_cs_eip(info)
     return e
 
 def fst(info, a):
@@ -1604,6 +1649,8 @@ def fst(info, a):
     else:
         src = float_st0
     e.append(ExprAff(a, src))
+
+    e += set_float_cs_eip(info)
     return e
 
 def fstp(info, a):
@@ -1614,6 +1661,8 @@ def fstp(info, a):
 def fist(info, a):
     e = []
     e.append(ExprAff(a, ExprOp('double_to_int_32', float_st0)))
+
+    e += set_float_cs_eip(info)
     return e
 
 def fistp(info, a):
@@ -1624,6 +1673,8 @@ def fistp(info, a):
 def fild(info, a):
     #XXXXX
     src = ExprOp('int_%.2d_to_double'%a.get_size(), a)
+
+    e += set_float_cs_eip(info)
     return fld(info, src)
 
 def fldz(info):
@@ -1637,6 +1688,12 @@ def fldl2e(info):
     x = struct.unpack('Q', x)[0]
     return fld(info, ExprOp('mem_64_to_double', ExprInt(uint64(x))))
 
+def fldlg2(info):
+    x = struct.pack('d', math.log10(2))
+    x = struct.unpack('Q', x)[0]
+    return fld(info, ExprOp('mem_64_to_double', ExprInt(uint64(x))))
+
+
 def fadd(info, a, b = None):
     if b == None:
         b = a
@@ -1647,6 +1704,8 @@ def fadd(info, a, b = None):
     else:
         src = b
     e.append(ExprAff(a, ExprOp('fadd', a, src)))
+
+    e += set_float_cs_eip(info)
     return e
 
 def faddp(info, a, b = None):
@@ -1658,8 +1717,36 @@ def faddp(info, a, b = None):
     return e
 
 def fninit(info):
-    return []
+    e = []
+    e += set_float_cs_eip(info)
+    return e
 
+def fnstenv(info, a):
+    e = []
+    # XXX TODO tag word, ...
+    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]
+    ad = ExprMem(a.arg, size=16)
+    e.append(ExprAff(ad, float_control))
+    ad = ExprMem(a.arg+ExprInt(uint32(w_size/8*1)), size = 16)
+    e.append(ExprAff(ad, status_word))
+    ad = ExprMem(a.arg+ExprInt(uint32(w_size/8*3)), size = w_size)
+    e.append(ExprAff(ad, float_eip[:w_size]))
+    ad = ExprMem(a.arg+ExprInt(uint32(w_size/8*4)), size = 16)
+    e.append(ExprAff(ad, float_cs))
+    ad = ExprMem(a.arg+ExprInt(uint32(w_size/8*5)), size = w_size)
+    e.append(ExprAff(ad, float_address[:w_size]))
+    ad = ExprMem(a.arg+ExprInt(uint32(w_size/8*6)), size = 16)
+    e.append(ExprAff(ad, float_ds))
+    return e
 
 def fsub(info, a, b = None):
     if b == None:
@@ -1671,6 +1758,7 @@ def fsub(info, a, b = None):
     else:
         src = b
     e.append(ExprAff(a, ExprOp('fsub', a, src)))
+    e += set_float_cs_eip(info)
     return e
 
 def fmul(info, a, b = None):
@@ -1683,6 +1771,7 @@ def fmul(info, a, b = None):
     else:
         src = b
     e.append(ExprAff(a, ExprOp('fmul', a, src)))
+    e += set_float_cs_eip(info)
     return e
 
 def fdiv(info, a, b = None):
@@ -1695,6 +1784,7 @@ def fdiv(info, a, b = None):
     else:
         src = b
     e.append(ExprAff(a, ExprOp('fdiv', a, src)))
+    e += set_float_cs_eip(info)
     return e
 
 def ftan(info, a):
@@ -1704,6 +1794,7 @@ def ftan(info, a):
     else:
         src = a
     e.append(ExprAff(float_st0, ExprOp('ftan', src)))
+    e += set_float_cs_eip(info)
     return e
 
 def fxch(info, a):
@@ -1714,6 +1805,7 @@ def fxch(info, a):
         src = a
     e.append(ExprAff(float_st0, src))
     e.append(ExprAff(src, float_st0))
+    e += set_float_cs_eip(info)
     return e
 
 def fptan(info):
@@ -1739,49 +1831,56 @@ def fptan(info):
 def frndint(info):
     e = []
     e.append(ExprAff(float_st0, ExprOp('frndint', float_st0)))
+    e += set_float_cs_eip(info)
     return e
 
 def fsin(info):
     e = []
     e.append(ExprAff(float_st0, ExprOp('fsin', float_st0)))
+    e += set_float_cs_eip(info)
     return e
 
 def fcos(info):
     e = []
     e.append(ExprAff(float_st0, ExprOp('fcos', float_st0)))
+    e += set_float_cs_eip(info)
     return e
 
 def fscale(info):
     e = []
     e.append(ExprAff(float_st0, ExprOp('fscale', float_st0, float_st1)))
+    e += set_float_cs_eip(info)
     return e
 
 def f2xm1(info):
     e = []
     e.append(ExprAff(float_st0, ExprOp('f2xm1', float_st0)))
+    e += set_float_cs_eip(info)
     return e
 
 def fsqrt(info):
     e = []
     e.append(ExprAff(float_st0, ExprOp('fsqrt', float_st0)))
+    e += set_float_cs_eip(info)
     return e
 
 def fabs(info):
     e = []
     e.append(ExprAff(float_st0, ExprOp('fabs', float_st0)))
+    e += set_float_cs_eip(info)
     return e
 
 
 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):
@@ -1811,7 +1910,7 @@ def rdtsc(info):
     return e
 
 def cbw(info, a):
-    opmode, admode = info
+    opmode, admode = info.opmode, info.admode
     if opmode == u16:
         s = 16
         src = a[:8]
@@ -1828,7 +1927,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
@@ -1921,7 +2021,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
@@ -2025,6 +2126,24 @@ def lss(info, a, b):
                                  size=16)))
     return e
 
+def lahf(info):
+    e = []
+    args = []
+    regs = [cf, ExprInt(uint32(1)), pf, ExprInt(uint32(0)), af, ExprInt(uint32(0)), zf, nf]
+    for i in xrange(len(regs)):
+        args.append((regs[i],i, i+1))
+    e.append(ExprAff(eax[8:16], ExprCompose(args)))
+    return e
+
+def sahf(info):
+    tmp = eax[8:16]
+    e = []
+    e.append(ExprAff(cf, ExprSlice(tmp, 0, 1)))
+    e.append(ExprAff(pf, ExprSlice(tmp, 2, 3)))
+    e.append(ExprAff(af, ExprSlice(tmp, 4, 5)))
+    e.append(ExprAff(zf, ExprSlice(tmp, 6, 7)))
+    e.append(ExprAff(nf, ExprSlice(tmp, 7, 8)))
+    return e
 mnemo_func = {'mov': mov,
               'xchg': xchg,
               'movzx': movzx,
@@ -2098,6 +2217,7 @@ mnemo_func = {'mov': mov,
               'leave':leave,
               'enter':enter,
               'jmp':jmp,
+              'jmpf':jmpf,
               'jz':jz,
               'je':jz,
               'jnz':jnz,
@@ -2151,6 +2271,7 @@ mnemo_func = {'mov': mov,
               'fldz':fldz,
               'fld1':fld1,
               'fldl2e':fldl2e,
+              'fldlg2':fldlg2,
               'fild':fild,
               'fadd':fadd,
               'fninit':fninit,
@@ -2171,6 +2292,7 @@ mnemo_func = {'mov': mov,
               'fnstcw':fnstcw,
               'fldcw':fldcw,
               'fwait':fwait,
+              'fnstenv':fnstenv,
               'sidt':sidt,
               'arpl':arpl,
               'cmovz':cmovz,
@@ -2196,6 +2318,8 @@ mnemo_func = {'mov': mov,
               "lds": lds,
               "les": les,
               "lss": lss,
+              "lahf": lahf,
+              "sahf": sahf,
               }
 
 
@@ -2239,9 +2363,9 @@ class ia32_rexpr:
                       s32:'i',
                       u32:'I',
                       }
-                      
 
-    
+
+
     r_eax = eax
     r_ecx = ecx
     r_edx = edx
@@ -2250,7 +2374,7 @@ class ia32_rexpr:
     r_ebp = ebp
     r_esi = esi
     r_edi = edi
-    
+
     r_dr0 = dr0
     r_dr1 = dr1
     r_dr2 = dr2
@@ -2259,7 +2383,7 @@ class ia32_rexpr:
     r_dr5 = dr5
     r_dr6 = dr6
     r_dr7 = dr7
-    
+
     r_cr0 = cr0
     r_cr1 = cr1
     r_cr2 = cr2
@@ -2268,7 +2392,7 @@ class ia32_rexpr:
     r_cr5 = cr5
     r_cr6 = cr6
     r_cr7 = cr7
-    
+
     r_ax = r_eax[:16]
     r_cx = r_ecx[:16]
     r_dx = r_edx[:16]
@@ -2277,7 +2401,7 @@ class ia32_rexpr:
     r_bp = r_ebp[:16]
     r_si = r_esi[:16]
     r_di = r_edi[:16]
-         
+
     r_al = r_eax[:8]
     r_cl = r_ecx[:8]
     r_dl = r_edx[:8]
diff --git a/miasm/arch/ppc_arch.py b/miasm/arch/ppc_arch.py
index 8cb66b2d..94c564ad 100644
--- a/miasm/arch/ppc_arch.py
+++ b/miasm/arch/ppc_arch.py
@@ -42,7 +42,7 @@ def str2imm(i):
     except:
         return False
     return a
-    
+
 def imm2str(i):
     if type(i) in [int, long]:
         if i<0:
@@ -65,9 +65,9 @@ class bm_meta(type):
         if name.startswith('bm_'):
             pname = name[3:]
             dct["p_property"] = [pname]+dct["p_property"]
-        
+
         b = bases[0]
-        
+
         dct["check"] = b.check_no
         l = dct["l"]
         fbits = dct["fbits"]
@@ -95,14 +95,14 @@ class bm_meta(type):
                 dct["check"] = b.check_fbits_inv
             else:
                 dct["check"] = b.check_fbits
-                
+
         p_property = dct["p_property"]
-            
+
         for p in p_property:
             dct["get_"+p] = lambda self, p=p:getattr(self, p)
             dct["set_"+p] = lambda self, p=p:setattr(self, p)
         return type.__new__(cls, name, bases, dct)
-    
+
 
 class bm(object):
     __metaclass__ = bm_meta
@@ -121,15 +121,15 @@ class bm(object):
     def get_val(self, v):
         return (v>>self.off) & ((1<<self.l)-1)
     def set_val(self, v = None):
-        
+
         if v == None and len(self.p_property) >= 1:
             p = self.p_property[0]
             v = getattr(self, p)
-        return (v&((1<<self.l)-1))<<self.off 
+        return (v&((1<<self.l)-1))<<self.off
 
     def bin(self):
         return self.set_val()
-        
+
     def parse(self, v):
         if len(self.p_property) >= 1:
             p = self.p_property[0]
@@ -152,7 +152,7 @@ for i in xrange(0x40):
         if mask_str[0] !='0':
             break
         mask_str = mask_str[1:]
-    
+
 
 class bm_set_meta(type):
     def __new__(cls, name, bases, odct):
@@ -169,7 +169,7 @@ class bm_set(object):
         self.fmask = (1<<self.l)-1
     def check(self, v):
         return (v>>self.off) & self.fmask in self.fbits
-    
+
 
 COND_EQ = 0
 COND_NE = 1
@@ -199,8 +199,8 @@ class bm_cond(bm):
     def str2cond(self, cond):
         if not cond in self.n:
             raise ValueError('unknown cond')
-        self.cond = self.n.index(cond)    
-    
+        self.cond = self.n.index(cond)
+
 class bm_int000000000(bm):
     fbits = '000000000'
 
@@ -406,10 +406,10 @@ class bm_bt(bm):
 
 class bm_ba(bm):
     l = 5
- 
+
 class bm_bb(bm):
     l = 5
-           
+
 class bm_rn(bm):
     l = 4
 
@@ -420,7 +420,7 @@ class bm_rdh(bm):
 class bm_rdl(bm):
     l = 4
 
-    
+
 class ppc_mnemo_metaclass(type):
     global tab_mn
     def __call__(cls, op, offset = 0):
@@ -435,7 +435,7 @@ class ppc_mnemo_metaclass(type):
         else:
             raise ValueError('zarb arg')
         return i
-        
+
     def class_from_op(cls, op):
         ret = filter(lambda x:x.check(op), tab_mn)
         if len(ret)==1:
@@ -452,7 +452,7 @@ class ppc_mnemo_metaclass(type):
         op = bin.readbs(4)
         op = struct.unpack('>L', op)[0]
         return cls(op, bin.offset-4)
-        
+
 
     def asm(cls, txt, symbol_reloc_off = []):
         print txt
@@ -465,7 +465,7 @@ class ppc_mnemo_metaclass(type):
         i = cls.__new__(cls)
         i.__init__(txt, 0, False)
         return [struct.pack('>L', i.bin())]
-        
+
     def __new__(cls, name, bases, dct):
         ret_c = type.__new__(cls, name, bases, dct)
         if name is "ppc_mn":
@@ -476,7 +476,7 @@ class ppc_mnemo_metaclass(type):
             for off in dct['mask']:
                 mc = dct['mask'][off](None, off)#+1)
                 mask.append(mc)
-            
+
         mask_orig = dct["mask_list"]
         ret_c.mask_orig = mask_orig
         off = 32
@@ -488,9 +488,9 @@ class ppc_mnemo_metaclass(type):
                 pfunc = "get_"+pname
                 p = property(lambda self=ret_c, pname=pname:getattr(getattr(self, "bm_"+pname), pname),
                              lambda self=ret_c,val=None,pname=pname:setattr(getattr(self, "bm_"+pname), pname, val))
-                
+
                 setattr(ret_c, pname, p)
-                
+
         if off!=0:
             raise ValueError('invalid mnemonic %d'%off)
         ret_c.mask_chk = mask
@@ -547,20 +547,20 @@ class ppc_mnemo_metaclass(type):
             if is_minux:
                 x = '-'+x
                 is_minux = False
-            
+
             if x == '.':
                 t[-1]+=x
             else:
                 t.append(x)
-                
+
         t.reverse()
         return t
-    
+
     def parse_mnemo(cls, args):
         t = cls.pre_parse_mnemo(args)
         t.reverse()
         return [], t[0], t[1:]
-    
+
     def parse_address(self, a):
         return parse_ad(a)
     def prefix2hex(self, p):
@@ -576,7 +576,7 @@ crb_str = []
 for i in xrange(0x8):
     for x in ['LT', 'GT', 'EQ', 'SO']:
         crb_str.append('CR%d_%s'%(i, x))
-        
+
 cr_str = ['CR%d'%r for r in xrange(0x8)]
 fpr_str = ['FP%d'%r for r in xrange(0x20)]
 spr_str = ['SPR%d'%r for r in xrange(0x400)]
@@ -600,7 +600,7 @@ def is_symbol(a):
     if is_imm(a) or a in all_regs:
         return False
     return True
-        
+
 def parse_ad(a):
     a = a.strip()
     if is_symbol(a):
@@ -666,7 +666,7 @@ class crb:
     @classmethod
     def cls(cls, r):
         return str2crb(r)
-        
+
 
 class fpr:
     @classmethod
@@ -675,7 +675,7 @@ class fpr:
     @classmethod
     def cls(cls, r):
         return str2fpr(r)
-        
+
 
 class cr:
     @classmethod
@@ -683,7 +683,7 @@ class cr:
         return cr2str(r)
     @classmethod
     def cls(cls, r):
-        return str2cr(r)    
+        return str2cr(r)
 
 class spr:
     @classmethod
@@ -725,13 +725,13 @@ def arglist2str(args):
 
 def args2str(args):
     return arglist2str(args2reduce(args))
-            
-       
+
+
 class ppc_mn(object):
     mask_list = []
     __metaclass__ = ppc_mnemo_metaclass
 
-    
+
     def gen_args2str(self):
         args = []
         for r, t in self.args_list:
@@ -749,15 +749,16 @@ class ppc_mn(object):
         self.l = 4
         self.m = None
         self.arg = []
-        
+        self.cmt = ""
+
         for m in self.mask_orig:
-            mc = m(self, off)            
+            mc = m(self, off)
             off-=mc.l
             for pname in m.p_property:
                 setattr(self, "bm_"+pname, mc)
             mask.append(mc)
         self.mask = mask
-        
+
         if dis:
             for m in self.mask:
                 ret = m.parse(op)
@@ -766,7 +767,7 @@ class ppc_mn(object):
         else:
             for m in self.mask:
                 ret = m.setprop()
-            
+
             full_mnemo = ppc_mn.pre_parse_mnemo(op)
             mnemo = full_mnemo.pop()
             name, rest = self.parse_name_cond(mnemo)
@@ -782,7 +783,7 @@ class ppc_mn(object):
                 print "WARNING asm symb", a
                 mnemo_nosymb.append("0")
             full_mnemo = mnemo_nosymb
-            
+
             self.parse_args(full_mnemo)
 
     def parse_opts(self, rest):
@@ -791,7 +792,7 @@ class ppc_mn(object):
         pass
     def str2name(self, n):
         pass
-    
+
     def getname(self):
         name = self.name2str()+self.oe2str()+self.rc2str()
         return name
@@ -829,7 +830,7 @@ class ppc_mn(object):
         return ""
     def rc2str(self):
         return ""
-    
+
 
     def breakflow(self):
         return False
@@ -871,7 +872,7 @@ class ppc_add(ppc_mn):
     strname = dict((x[1], x[0]) for x in namsdct.items())
 
     do_args = [('rt',reg), ('ra',reg), ('rb',reg)]
-    
+
     def name2str(self):
         return self.strname[self.opc9]
     def str2name(self, n):
@@ -907,7 +908,7 @@ class ppc_addi(ppc_mn):
         if self.ra == 0:
             return self.namestr[1]
         return self.namestr[0]
-    
+
     def args2str(self):
         args = []
         args.append(reg2str(self.rt))
@@ -942,13 +943,13 @@ class ppc_addis(ppc_addi):
 class ppc_adde(ppc_mn):
     mask_list = [bm_int011111, bm_rt, bm_ra, bm_int00000, bm_oe, bm_opc9, bm_rc]
     namestr = {'ADDME':234, 'ADDZE':202, 'NEG':104, 'SUBFME':232, 'SUBFZE':200}
-    
+
     mask = {22:bm_set_meta("bm_addeopc",(bm_set,),{"fbits":namestr.values()})}
-    
+
     strname = dict((x[1], x[0]) for x in namestr.items())
 
     do_args = [('rt',reg), ('ra',reg)]
-    
+
     def name2str(self):
         return self.strname[self.opc9]
     def str2name(self, n):
@@ -984,7 +985,7 @@ class ppc_and(ppc_mn):
     strname = dict((x[1], x[0]) for x in namedct.items())
 
     do_args = [('ra',reg), ('rs',reg), ('rb',reg)]
-    
+
     def name2str(self):
         return self.strname[self.opc10]
     def str2name(self, n):
@@ -997,7 +998,7 @@ class ppc_and(ppc_mn):
 
     def rc2str(self):
         return ['','.'][self.rc==1]
-    
+
 
     def parse_opts(self, opts):
         self.rc = 0
@@ -1013,7 +1014,7 @@ class ppc_andip(ppc_mn):
 
     do_args = [('ra',reg), ('rs',reg), ('uimm',imm)]
 
-    
+
     def name2str(self):
         return self.namestr[0]
 
@@ -1104,7 +1105,7 @@ class ppc_b(ppc_mn):
             self.li = lbls[l]>>2
         else:
             self.li = (lbls[l]+4-my_offset)>>2
-        
+
 
 
 class ppc_bc(ppc_mn):
@@ -1157,13 +1158,13 @@ class ppc_bc(ppc_mn):
             name+='A'
         if self.lk:
             name+='L'
-            
+
         return name
 
 
     def parse_opts(self, opts):
         self.bi_done = False
-        
+
         self.bo = 0x14
         self.bi = 0
         self.aa = 0
@@ -1206,17 +1207,17 @@ class ppc_bc(ppc_mn):
             return
         if opts == 'A':
             self.aa = 1
-        return 
+        return
 
     def args2str(self):
         args = []
-        
+
         if not self.bi_parsed:
             if not self.bo & 0x10:
                 index = (self.bo&8)>>1
                 index |= self.bi & 3
                 a = ppc_bc.all_tests[index]
-                
+
                 args.append(a)
             else:
                 pass
@@ -1233,7 +1234,7 @@ class ppc_bc(ppc_mn):
 
             if args[-1] in ppc_bc.all_tests:
                 self.bo &=0xF
-                
+
                 a = args.pop()
                 index = ppc_bc.all_tests.index(a)
                 inv = index&0x4
@@ -1244,9 +1245,9 @@ class ppc_bc(ppc_mn):
                     self.bo&=0x17
             else:
                 self.bo |=0x10
-                
+
                 pass
-            
+
         if len(args) >1:
             tmp = str2cr(args.pop())
             self.bi|=tmp<<2
@@ -1345,14 +1346,14 @@ class ppc_bctr(ppc_mn):
             self.bi_parsed = True
         else:
             pass
-            
+
         return name
 
 
 
     def parse_opts(self, opts):
         self.bi_done = False
-        
+
         self.bo = 0x14
         self.bi = 0
         self.aa = 0
@@ -1395,17 +1396,17 @@ class ppc_bctr(ppc_mn):
             return
         if opts == 'A':
             self.aa = 1
-        return 
+        return
 
     def args2str(self):
         args = []
         if not self.bi_parsed:
             if not self.bo & 0x10:
-                    
+
                 index = (self.bo&8)>>1
                 index |= self.bi & 3
                 a = ppc_bc.all_tests[index]
-                
+
                 args.append(a)
             else:
                 pass
@@ -1415,11 +1416,11 @@ class ppc_bctr(ppc_mn):
 
     def parse_args(self, args):
         if not args:
-            return 
+            return
         if not self.bi_done:
             if args[-1] in ppc_bc.all_tests:
                 self.bo &=0xF
-                
+
                 a = args.pop()
                 index = ppc_bc.all_tests.index(a)
                 inv = index&0x4
@@ -1430,9 +1431,9 @@ class ppc_bctr(ppc_mn):
                     self.bo&=0x17
             else:
                 self.bo |=0x10
-                
+
                 pass
-            
+
         if len(args) >1:
             tmp = str2cr(args.pop())
             self.bi|=tmp<<2
@@ -1468,7 +1469,7 @@ class ppc_cmp(ppc_mn):
         return self.strname[self.opc10]
     def str2name(self, n):
         self.opc10 = self.namedct[n]
-    
+
     def args2str(self):
         args = []
         if self.bf!=0:
@@ -1492,7 +1493,7 @@ class ppc_cmpli(ppc_mn):
 
     def name2str(self):
         return self.namestr[0]
-    
+
     def args2str(self):
         args = []
         if self.bf!=0:
@@ -1505,7 +1506,7 @@ class ppc_cmpli(ppc_mn):
         self.bf = 0
         if len(args)==3:
             self.bf = str2cr(args.pop())
-            
+
         self.ra = str2reg(args.pop())
         self.uimm = str2imm(args.pop())
 
@@ -1516,7 +1517,7 @@ class ppc_cmpi(ppc_mn):
 
     def name2str(self):
         return self.namestr[0]
-    
+
     def args2str(self):
         args = []
         if self.bf!=0:
@@ -1535,7 +1536,7 @@ class ppc_cmpi(ppc_mn):
 class ppc_cntlzw(ppc_mn):
     mask_list = [bm_int011111, bm_rs, bm_ra, bm_int00000, bm_opc10, bm_rc]
     mask = {21:bm_set_meta("bm_cntlzwopc",(bm_set,),{"fbits":[26], 'l':10})}
-    
+
     namestr = ['CNTLZW']
 
     do_args = [('ra',reg), ('rs',reg)]
@@ -1545,7 +1546,7 @@ class ppc_cntlzw(ppc_mn):
 
     def str2name(self, n):
         self.opc10 = 26
-    
+
     @classmethod
     def check_opts(cls, rest):
         if rest in ["", "."]:
@@ -1630,7 +1631,7 @@ class ppc_eieio(ppc_mn):
 class ppc_isync(ppc_eieio):
     mask_list = [bm_int010011, bm_int00000, bm_int00000, bm_int00000, bm_opc10, bm_int0]
     namestr = ['ISYNC', 'RFI']
-    namedct = {'ISYNC':150, 'RFI':50}    
+    namedct = {'ISYNC':150, 'RFI':50}
     mask = {21:bm_set_meta("bm_isyncopc",(bm_set,),{"fbits":namedct.values(), 'l':10})}
     strname = dict((x[1], x[0]) for x in namedct.items())
     def name2str(self):
@@ -1664,7 +1665,7 @@ class ppc_lbz(ppc_mn):
     namestr = ['LBZ']
 
     do_args = [('rt',reg), ('ra',reg), ('simm',imm)]
-    
+
     def name2str(self):
         return self.namestr[0]
 
@@ -1947,7 +1948,7 @@ class ppc_sc(ppc_mn):
         return args
 
 
-    
+
     def parse_args(self, args):
         self.offs = 0
         pass
@@ -1966,7 +1967,7 @@ class ppc_srawi(ppc_cntlzw, ppc_mn):
     mask = {21:bm_set_meta("bm_srawiopc",(bm_set,),{"fbits":[824], 'l':10})}
 
     do_args = [('ra',reg), ('rs',reg), ('sh',imm)]
-    
+
     def str2name(self, n):
         self.opc10 = 824
 
@@ -1978,7 +1979,7 @@ class ppc_subfic(ppc_addi):
 class ppc_sync(ppc_eieio):
     mask_list = [bm_int011111, bm_int00000, bm_int00000, bm_int00000, bm_opc10, bm_int0]
     namestr = ['SYNC', 'TLBSYNC']
-    namedct = {'SYNC':598, 'TLBSYNC':566}    
+    namedct = {'SYNC':598, 'TLBSYNC':566}
     mask = {21:bm_set_meta("bm_syncopc",(bm_set,),{"fbits":namedct.values(), 'l':10})}
     strname = dict((x[1], x[0]) for x in namedct.items())
     def name2str(self):
@@ -2139,12 +2140,12 @@ tab_mn = [ppc_addi, ppc_ori, ppc_oris, ppc_xori, ppc_xoris, ppc_addic, ppc_addic
 
 
 if __name__ == "__main__":
- 
+
     import struct
 
-    
+
     for op in [0x7D4A5214, 0x7FAA4A14, 0x7D615A14]:
-    
+
         m = ppc_mn(op)
         print m
 
@@ -2266,7 +2267,7 @@ if __name__ == "__main__":
     TW 1, R3, R4
     TWI 3, R4, 8
     SC"""
-    
+
 
     #    UNDEF 0x1337, 1
 
@@ -2284,11 +2285,11 @@ if __name__ == "__main__":
         token_b = filter(lambda x:not x in ['-', ',', 'CR0'] and not is_imm(x), token_b)
         print token_a
         print token_b
-            
+
         op2 = ppc_mn.asm(str(m))[0]
         h = struct.unpack('>L', op2)
         print "%.8X"%h
         if op1 !=op2 or (token_a != token_b and not token_b[0] in ['BLE', 'ADDI', 'LI', 'ADDIS', 'LIS']):
             raise ValueError('bug in self test', t)
 
-    
+
diff --git a/miasm/core/asmbloc.py b/miasm/core/asmbloc.py
index f9115105..1860b856 100644
--- a/miasm/core/asmbloc.py
+++ b/miasm/core/asmbloc.py
@@ -1107,9 +1107,8 @@ def getlineby_offset(all_bloc, o):
 
 def getblocby_offset(all_bloc, o):
     for b in all_bloc:
-        for l in b.lines:
-            if l.offset == o:
-                return b
+        if b.lines and b.lines[0].offset == o:
+            return b
     return None
 
 def getblocby_label(all_bloc, l):
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/graph/graph_qt.py b/miasm/graph/graph_qt.py
index adb4fe50..7f1f6abb 100755
--- a/miasm/graph/graph_qt.py
+++ b/miasm/graph/graph_qt.py
@@ -62,6 +62,7 @@ def gen_syntax_rules(symbols = []):
     highlightingRules = []
     number = QtGui.QTextCharFormat()
     label = QtGui.QTextCharFormat()
+    comment = QtGui.QTextCharFormat()
     my_id = QtGui.QTextCharFormat()
     highlight_word = QtGui.QTextCharFormat()
 
@@ -80,6 +81,15 @@ def gen_syntax_rules(symbols = []):
     rule = HighlightingRule( pattern, number )
     highlightingRules.append( rule )
 
+    #comment
+    brushr = QtGui.QBrush( Qt.red, Qt.SolidPattern )
+    pattern = QtCore.QRegExp( ";.*$" )
+    pattern.setMinimal( False )
+    comment.setForeground( brushr )
+    rule = HighlightingRule( pattern, comment )
+    highlightingRules.append( rule )
+
+
     """
     #label
     brushb = QtGui.QBrush( Qt.blue, Qt.SolidPattern )
@@ -812,6 +822,7 @@ class MainWindow(QtGui.QWidget):
             def __init__(self, k = None, data = None):
                 self.data = data
                 self.k = k
+                self.splines = []
                 if not data:
                     self.w, self.h = 80,40
                 else:
diff --git a/miasm/tools/emul_helper.py b/miasm/tools/emul_helper.py
index 66521bf3..ba16eabf 100755
--- a/miasm/tools/emul_helper.py
+++ b/miasm/tools/emul_helper.py
@@ -168,23 +168,23 @@ def get_instr_expr_args(name, modifs, mnemo_mode, args, my_eip):
 
 #"""
 ###XXX for eval abs
-def get_instr_expr_args(name, modifs, opmode, admode, args, my_eip):
+def get_instr_expr_args(l, args, my_eip):
     for a in args:
         if type(a) in [int, long]:
             raise ValueError('int deprec in args')
 
-    info = (opmode, admode)
-    if name in ['jmp']:
+    info = l
+    if l.m.name in ['jmp']:
         if isinstance(args[0], ExprInt):
-            e = mnemo_func[name](info, args[0])
+            e = mnemo_func[l.m.name](info, args[0])
         else:
-            e = mnemo_func[name](info, *args)
-    elif name in jcc:
-        e = mnemo_func[name](info, my_eip, args[0])
-    elif name in ['call']:
-        e = mnemo_func[name](info, my_eip, args[0])
+            e = mnemo_func[l.m.name](info, *args)
+    elif l.m.name in jcc:
+        e = mnemo_func[l.m.name](l, my_eip, args[0])
+    elif l.m.name in ['call']:
+        e = mnemo_func[l.m.name](l, my_eip, args[0])
     else:
-        e = mnemo_func[name](info, *args)
+        e = mnemo_func[l.m.name](l, *args)
     return e
 #"""
 
@@ -194,7 +194,7 @@ def get_instr_expr(l, my_eip, args = None, segm_to_do = {}):
     for x in l.arg:
         args.append(dict_to_Expr(x, l.m.modifs, l.opmode, l.admode, segm_to_do))
     l.arg_expr = args
-    return get_instr_expr_args(l.m.name, l.m.modifs, l.opmode, l.admode, args, my_eip)
+    return get_instr_expr_args(l, args, my_eip)
 
 
 
diff --git a/miasm/tools/emul_lib/libcodenat.h b/miasm/tools/emul_lib/libcodenat.h
index 0f3f99af..026236cb 100644
--- a/miasm/tools/emul_lib/libcodenat.h
+++ b/miasm/tools/emul_lib/libcodenat.h
@@ -157,6 +157,15 @@ typedef struct {
 	unsigned int reg_float_control;
 	unsigned int reg_float_control_new;
 
+	unsigned int reg_float_eip;
+	unsigned int reg_float_eip_new;
+	unsigned int reg_float_cs;
+	unsigned int reg_float_cs_new;
+	unsigned int reg_float_address;
+	unsigned int reg_float_address_new;
+	unsigned int reg_float_ds;
+	unsigned int reg_float_ds_new;
+
 
 	unsigned int tsc1;
 	unsigned int tsc2;
diff --git a/miasm/tools/to_c_helper.py b/miasm/tools/to_c_helper.py
index d3394117..b7b387df 100644
--- a/miasm/tools/to_c_helper.py
+++ b/miasm/tools/to_c_helper.py
@@ -136,6 +136,10 @@ my_C_id = [
     #i_d_new,
     #my_tick,
     float_control,
+    float_eip ,
+    float_cs ,
+    float_address ,
+    float_ds ,
     #cond,
     ds,
     #vm_exception_flags,
@@ -304,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 = []
@@ -932,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