about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorserpilliere <devnull@localhost>2013-02-22 15:51:08 +0100
committerserpilliere <devnull@localhost>2013-02-22 15:51:08 +0100
commitf38372e5e052453c4878cbf0516a23e59b4d712b (patch)
tree5c1a9490fbd9362788804b1d53fd59f63f3aa0f6
parent4f1d29d8527375e81f190dbb0d345eca1eb541f0 (diff)
parent7d1b50444f2c952b1287bf45d046eea222d4ba18 (diff)
downloadmiasm-f38372e5e052453c4878cbf0516a23e59b4d712b.tar.gz
miasm-f38372e5e052453c4878cbf0516a23e59b4d712b.zip
merge
-rwxr-xr-xexample/disas_and_graph.py2
-rw-r--r--miasm/arch/ia32_arch.py40
-rw-r--r--miasm/arch/ia32_sem.py115
-rw-r--r--miasm/expression/expression.py2
-rw-r--r--miasm/tools/emul_lib/libcodenat.c84
-rw-r--r--miasm/tools/emul_lib/libcodenat.h20
-rw-r--r--miasm/tools/nux_api.py2
-rw-r--r--miasm/tools/pe_helper.py27
-rw-r--r--miasm/tools/seh_helper.py211
-rw-r--r--miasm/tools/to_c_helper.py32
10 files changed, 425 insertions, 110 deletions
diff --git a/example/disas_and_graph.py b/example/disas_and_graph.py
index 124b8f4a..0a6a3e5d 100755
--- a/example/disas_and_graph.py
+++ b/example/disas_and_graph.py
@@ -121,7 +121,7 @@ elif data.startswith("\xca\xfe\xba\xbe"):
 
 
 else:
-    print 'WARNING cannot autodetect file type, using raw'
+    print 'WARNING cannot autodetect file type, using raw', repr(data[:10])
     in_str = bin_stream.bin_stream(data)
     if ad_to_dis == None:
         ad_to_dis = 0
diff --git a/miasm/arch/ia32_arch.py b/miasm/arch/ia32_arch.py
index 3f6a5af4..2493948e 100644
--- a/miasm/arch/ia32_arch.py
+++ b/miasm/arch/ia32_arch.py
@@ -166,7 +166,8 @@ unsanity_mnemo = ['nop', 'monitor', 'mwait', 'fadd', 'faddp', 'fiadd', 'fcmovb',
                   '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',
                   "jmpff",
-                  "fcomi", "fucomi", "fucomip", "fdivp"]
+                  "fcomi", "fucomi", "fucomip", "fdivp",
+                  "fisubr", "fsubp"]
 
 
 mask_drcrsg = {cr:0x100, dr:0x200, sg:0x400}
@@ -1096,7 +1097,7 @@ class x86allmncs:
         addop("fadd",  [0xD8],             d0,    no_rm         , {sd:(0,2)}         ,{}         , {},                         )
         addop("fadd",  [0xD8, 0xC0],       reg,   [r_eax]       , {sw:(0,2)}         ,{sd:True,sw:False}, {},                         )
         addop("fiadd", [0xDA],             d0,    no_rm         , {wd:(0,2)}         ,{}                , {},                         )
-        addop("faddp", [0xDE, 0xC0],       reg,   no_rm         , {}                 ,{sd:False}        , {},                         )
+        addop("faddp", [0xDE, 0xC0],       reg,   [r_eax]       , {}                 ,{sd:False,sw:True}, {},                         )
 
         addop("fbld",  [0xDF],             d4,    no_rm         , {}                 ,{}                , {},                         )
         addop("fbstp", [0xDF],             d6,    no_rm         , {}                 ,{}                , {},                         )
@@ -1126,13 +1127,15 @@ class x86allmncs:
 
 
         addop("fdiv",  [0xD8],             d6,    no_rm         , {sd:(0,2)}         ,{}                , {},                         )
-        addop("fdiv",  [0xD8, 0xF0],       reg,   [r_eax]       , {sw:(0,2)}         ,{sd:True,sw:False}, {},                         )
+        addop("fdivr", [0xD8],             d7,    no_rm         , {sd:(0,2)}         ,{}                , {},                         )
+        addop("fdiv",  [0xDC, 0xF8],       reg,   [r_eax]       , {        }         ,{sd:True,sw:True }, {},                         )
         addop("fidiv", [0xDA],             d6,    no_rm         , {wd:(0,2)}         ,{}                , {},                         )
         addop("fidivr",[0xDA],             d7,    no_rm         , {wd:(0,2)}         ,{}                , {},                         )
-        addop("fdivp", [0xDE, 0xF8],       reg,   no_rm         , {}                 ,{sd:True}         , {},                         )
+        addop("fdivp", [0xDE, 0xF8],       reg,   [r_eax]       , {}                 ,{sd:True,sw:True} , {},                         )
 
-        addop("fdivr", [0xD8],             d7,    no_rm         , {sd:(0,2)}         ,{}                , {},                         )
-        addop("fdivr", [0xD8, 0xF8],       reg,   [r_eax]       , {sw:(0,2)}         ,{sd:True,sw:False}, {},                         )
+        addop("fdiv",  [0xD8, 0xF0],       reg,   [r_eax]       , {        }         ,{sd:True,sw:False}, {},                         )
+        addop("fdivr", [0xD8, 0xF8],       reg,   [r_eax]       , {        }         ,{sd:True,sw:False}, {},                         )
+        addop("fdivr", [0xDC, 0xF0],       reg,   [r_eax]       , {        }         ,{sd:True,sw:True }, {},                         )
         addop("fdivrp",[0xDE, 0xF0],       reg,   no_rm         , {}                 ,{sd:False}        , {},                         )
 
         addop("ffree", [0xDD, 0xC0],       reg,   no_rm         , {}                 ,{sd:False}        , {},                         )
@@ -1159,7 +1162,7 @@ class x86allmncs:
         addop("fmul",  [0xD8],             d1,    no_rm         , {sd:(0,2)}         ,{}                , {},                         )
         addop("fmul",  [0xD8, 0xC8],       reg,   [r_eax]       , {sw:(0,2)}         ,{sd:True,sw:False}, {},                         )
         addop("fimul", [0xDA],             d1,    no_rm         , {wd:(0,2)}         ,{}                , {},                         )
-        addop("fmulp", [0xDE, 0xC8],       reg,   no_rm         , {}                 ,{sd:False}        , {},                         )
+        addop("fmulp", [0xDE, 0xC8],       reg,   [r_eax]         , {}               ,{sd:False,sw:True}, {},                         )
 
 
         addop("frstor",[0xDD],             d4,    no_rm         , {}                 ,{wd:False}        , {},                         ) #XXX 94/108
@@ -1170,7 +1173,7 @@ class x86allmncs:
 
         addop("fst",   [0xD9],             d2,    no_rm         , {sd:(0,2)}         ,{}                , {},                         )
         addop("fst",   [0xDD, 0xD0],       reg,   no_rm         , {}                 ,{sd:False}        , {},                         )
-        addop("fstp",  [0xD9],             d3,    no_rm         , {sd:(0,2)}         ,{sd:False}        , {},                         )
+        addop("fstp",  [0xD9],             d3,    no_rm         , {sd:(0,2)}         ,{sd:True}        , {},                         )
         addop("fstp",  [0xDB],             d7,    no_rm         , {}                 ,{sd:False}        , {},                         ) #XXX 80
         addop("fstp",  [0xDD, 0xD8],       reg,   no_rm         , {}                 ,{sd:True}         , {},                         )
 
@@ -1224,14 +1227,25 @@ class x86allmncs:
         #ddop("fstsw",[0x9B, 0xDF, 0xE0],  noafs, no_rm         , {}                 ,{wd:False}        , {},                         ) #XXX no mnemo
         addop("fnstsw",[0xDF, 0xE0],       noafs, no_rm         , {}                 ,{wd:False}        , {},                         )
 
+        #addop("fsub",  [0xD8],             d4,    no_rm         , {sd:(0,2)}         ,{}                , {},                         )
+        #addop("fsubr", [0xD8],             d5,    no_rm         , {sd:(0,2)}         ,{}                , {},                         )
+        #addop("fsub",  [0xD8, 0xE0],       reg,   [r_eax]       , {        }         ,{sd:True,sw:False}, {},                         )
+        #addop("fisub", [0xDA],             d4,    no_rm         , {wd:(0,2)}         ,{}                , {},                         )
+        #addop("fsubp", [0xDE, 0xE8],       reg,   [r_eax]       , {}                 ,{sd:False,sw:True}, {},                         )
+        #
+        #addop("fsubr", [0xD8, 0xE8],       reg,   [r_eax]       , {sw:(0,2)}         ,{sd:True,sw:False}, {},                         )
+        #addop("fisubr",[0xDA],             d5,    no_rm         , {wd:(0,2)}         ,{}                , {},                         )
+        #addop("fsubrp",[0xDE, 0xE0],       reg,   no_rm         , {}                 ,{sd:False}        , {},                         )
         addop("fsub",  [0xD8],             d4,    no_rm         , {sd:(0,2)}         ,{}                , {},                         )
-        addop("fsub",  [0xD8, 0xE0],       reg,   [r_eax]       , {sw:(0,2)}         ,{sd:True,sw:False}, {},                         )
-        addop("fisub", [0xDA],             d4,    no_rm         , {wd:(0,2)}         ,{}                , {},                         )
-        addop("fsubp", [0xDE, 0xE8],       reg,   no_rm         , {}                 ,{sd:False}        , {},                         )
-
         addop("fsubr", [0xD8],             d5,    no_rm         , {sd:(0,2)}         ,{}                , {},                         )
-        addop("fsubr", [0xD8, 0xE8],       reg,   [r_eax]       , {sw:(0,2)}         ,{sd:True,sw:False}, {},                         )
+        addop("fsub",  [0xDC, 0xE8],       reg,   [r_eax]       , {        }         ,{sd:True,sw:True }, {},                         )
+        addop("fisub", [0xDA],             d4,    no_rm         , {wd:(0,2)}         ,{}                , {},                         )
         addop("fisubr",[0xDA],             d5,    no_rm         , {wd:(0,2)}         ,{}                , {},                         )
+        addop("fsubp", [0xDE, 0xE8],       reg,   [r_eax]       , {}                 ,{sd:True,sw:True} , {},                         )
+
+        addop("fsub",  [0xD8, 0xE0],       reg,   [r_eax]       , {        }         ,{sd:True,sw:False}, {},                         )
+        addop("fsubr", [0xD8, 0xE8],       reg,   [r_eax]       , {        }         ,{sd:True,sw:False}, {},                         )
+        addop("fsubr", [0xDC, 0xE0],       reg,   [r_eax]       , {        }         ,{sd:True,sw:True }, {},                         )
         addop("fsubrp",[0xDE, 0xE0],       reg,   no_rm         , {}                 ,{sd:False}        , {},                         )
 
         addop("ftst",  [0xD9, 0xE4],       noafs, no_rm         , {}                 ,{sd:False}        , {},                         )
diff --git a/miasm/arch/ia32_sem.py b/miasm/arch/ia32_sem.py
index 46619e1a..059661e4 100644
--- a/miasm/arch/ia32_sem.py
+++ b/miasm/arch/ia32_sem.py
@@ -269,6 +269,17 @@ float_st5 = ExprId(reg_float_st5, 64)
 float_st6 = ExprId(reg_float_st6, 64)
 float_st7 = ExprId(reg_float_st7, 64)
 
+float_list = [
+    float_st0 ,
+    float_st1 ,
+    float_st2 ,
+    float_st3 ,
+    float_st4 ,
+    float_st5 ,
+    float_st6 ,
+    float_st7 ,
+    ]
+
 
 
 init_regs = {
@@ -839,35 +850,7 @@ def shl(info, a, b):
     return e
 
 def shld_cl(info, a, b):
-    e= []
-    shifter = ExprOp('&',ecx, ExprInt_from(a, 0x1f))
-    c = ExprOp('|',
-            ExprOp('<<', a, shifter),
-            ExprOp('>>', b, ExprOp('-',
-                                    ExprInt_from(a, a.get_size()),
-                                    shifter)
-                                    )
-          )
-
-    new_cf = ExprOp('&',
-                    ExprInt_from(a, 1),
-                    ExprOp('>>',
-                           a,
-                           ExprOp('-',
-                                  ExprInt_from(b, a.get_size()),
-                                  shifter
-                                  )
-                           )
-                    )
-    e.append(ExprAff(cf, ExprCond(shifter,
-                                  new_cf,
-                                  cf)
-                     )
-             )
-    e+=update_flag_znp(c)
-    e.append(ExprAff(of, ExprOp('^', get_op_msb(c), new_cf)))
-    e.append(ExprAff(a, c))
-    return e
+    return shld(info, a, b, ecx)
 
 def shld(info, a, b, c):
     e= []
@@ -895,9 +878,12 @@ def shld(info, a, b, c):
                                   cf)
                      )
              )
+    # XXX todo: don't update flag if shifter is 0
     e+=update_flag_znp(c)
     e.append(ExprAff(of, ExprOp('^', get_op_msb(c), new_cf)))
-    e.append(ExprAff(a, c))
+    e.append(ExprAff(a, ExprCond(shifter,
+                                 c,
+                                 a)))
     return e
 
 
@@ -1645,8 +1631,17 @@ def movs(info, a, b):
 
     return e
 
+def float_prev(flt):
+    if not flt in float_list:
+        return None
+    i = float_list.index(flt)
+    if i == 0:
+        fds
+    flt = float_list[i-1]
+    return flt
 
 def float_pop(avoid_flt = None):
+    avoid_flt = float_prev(avoid_flt)
     e= []
     if avoid_flt != float_st0:
         e.append(ExprAff(float_st0, float_st1))
@@ -1803,11 +1798,17 @@ def fadd(info, a, b = None):
     return e
 
 def faddp(info, a, b = None):
-    e = fadd(a, b)
     if b == None:
-        e+=float_pop(float_st0)
+        b = a
+        a = float_st0
+    e = []
+    if isinstance(b, ExprMem):
+        src = ExprOp('mem_%.2d_to_double'%b.get_size(), b)
     else:
-        e+=float_pop(a)
+        src = b
+    e.append(ExprAff(float_prev(a), ExprOp('fadd', a, src)))
+    e += set_float_cs_eip(info)
+    e += float_pop(a)
     return e
 
 def fninit(info):
@@ -1881,11 +1882,47 @@ def fdiv(info, a, b = None):
     e += set_float_cs_eip(info)
     return e
 
+def fdivr(info, a, b = None):
+    if b == None:
+        b = a
+        a = float_st0
+    e = []
+    if isinstance(b, ExprMem):
+        src = ExprOp('mem_%.2d_to_double'%b.get_size(), b)
+    else:
+        src = b
+    e.append(ExprAff(a, ExprOp('fdiv', src, a)))
+    e += set_float_cs_eip(info)
+    return e
+
 def fdivp(info, a):
     # Invalid emulation
+    if b == None:
+        b = a
+        a = float_st0
     e = []
-    e.append(ExprAff(a, ExprOp('fdiv', a, float_st0)))
-    e+=float_pop(a)
+    if isinstance(b, ExprMem):
+        src = ExprOp('mem_%.2d_to_double'%b.get_size(), b)
+    else:
+        src = b
+    e.append(ExprAff(float_prev(a), ExprOp('fdiv', a, src)))
+    e += set_float_cs_eip(info)
+    e += float_pop(a)
+    return e
+
+def fmulp(info, a, b):
+    # Invalid emulation
+    if b == None:
+        b = a
+        a = float_st0
+    e = []
+    if isinstance(b, ExprMem):
+        src = ExprOp('mem_%.2d_to_double'%b.get_size(), b)
+    else:
+        src = b
+    e.append(ExprAff(float_prev(a), ExprOp('fmul', a, src)))
+    e += set_float_cs_eip(info)
+    e += float_pop(a)
     return e
 
 def ftan(info, a):
@@ -1922,12 +1959,6 @@ def fptan(info):
     e.append(ExprAff(float_stack_ptr, ExprOp('+', float_stack_ptr, ExprInt32(1))))
     return e
 
-    e.append(ExprAff(float_st0, ExprOp('ftan', src)))
-
-    e = ftan(a)
-    e+=float_pop(a)
-    return e
-
 
 def frndint(info):
     e = []
@@ -2421,7 +2452,9 @@ mnemo_func = {'mov': mov,
               'faddp':faddp,
               'fsub':fsub,
               'fmul':fmul,
+              'fmulp':fmulp,
               'fdiv':fdiv,
+              'fdivr':fdivr,
               'fdivp':fdivp,
               'fxch':fxch,
               'fptan':fptan,
diff --git a/miasm/expression/expression.py b/miasm/expression/expression.py
index 6018be4a..5ec5f4f0 100644
--- a/miasm/expression/expression.py
+++ b/miasm/expression/expression.py
@@ -444,7 +444,7 @@ class ExprOp(Expr):
                 return "parity(%s&0x%x)"%(self.args[0].toC(), my_size_mask[self.args[0].get_size()])
             elif self.op == '!':
                 return "(~ %s)&0x%x"%(self.args[0].toC(), my_size_mask[self.args[0].get_size()])
-            elif self.op in ['int_32_to_double', 'int_64_to_double']:
+            elif self.op in ['int_16_to_double', 'int_32_to_double', 'int_64_to_double']:
                 return "%s(%s)"%(self.op, self.args[0].toC())
             elif self.op == 'double_to_int_32':
                 return "%s(%s)"%(self.op, self.args[0].toC())
diff --git a/miasm/tools/emul_lib/libcodenat.c b/miasm/tools/emul_lib/libcodenat.c
index 31a2be31..ba491e16 100644
--- a/miasm/tools/emul_lib/libcodenat.c
+++ b/miasm/tools/emul_lib/libcodenat.c
@@ -683,8 +683,9 @@ int imul_hi_op_16(short a, short b)
 int imul_hi_op_32(int a, int b)
 {
 	int64_t res = 0;
-	res = a*b;
-	return res>>32;
+	res = (int64_t)a*(int64_t)b;
+	//printf("%x %x dd %"PRIx64"\n", a, b, res);
+	return res>>32ULL;
 }
 
 unsigned int umul16_lo(unsigned short a, unsigned short b)
@@ -918,6 +919,20 @@ unsigned int cpuid(unsigned int a, unsigned int reg_num)
 
 #define DEBUG_MIASM_DOUBLE
 
+
+void dump_float(void)
+{
+	printf("%e\n", vmcpu.float_st0);
+	printf("%e\n", vmcpu.float_st1);
+	printf("%e\n", vmcpu.float_st2);
+	printf("%e\n", vmcpu.float_st3);
+	printf("%e\n", vmcpu.float_st4);
+	printf("%e\n", vmcpu.float_st5);
+	printf("%e\n", vmcpu.float_st6);
+	printf("%e\n", vmcpu.float_st7);
+
+}
+
 double mem_32_to_double(unsigned int m)
 {
 	float f;
@@ -926,7 +941,8 @@ double mem_32_to_double(unsigned int m)
 	f = *((float*)&m);
 	d = f;
 #ifdef DEBUG_MIASM_DOUBLE
-	printf("%d %e\n", m, d);
+	dump_float();
+	printf("%d float %e\n", m, d);
 #endif
 	return d;
 }
@@ -937,7 +953,20 @@ double mem_64_to_double(uint64_t m)
 	double d;
 	d = *((double*)&m);
 #ifdef DEBUG_MIASM_DOUBLE
-	printf("%"PRId64" %e\n", m, d);
+	dump_float();
+	printf("%"PRId64" double %e\n", m, d);
+#endif
+	return d;
+}
+
+double int_16_to_double(unsigned int m)
+{
+	double d;
+
+	d = (double)(m&0xffff);
+#ifdef DEBUG_MIASM_DOUBLE
+	dump_float();
+	printf("%d double %e\n", m, d);
 #endif
 	return d;
 }
@@ -948,7 +977,8 @@ double int_32_to_double(unsigned int m)
 
 	d = (double)m;
 #ifdef DEBUG_MIASM_DOUBLE
-	printf("%d %e\n", m, d);
+	dump_float();
+	printf("%d double %e\n", m, d);
 #endif
 	return d;
 }
@@ -959,7 +989,8 @@ double int_64_to_double(uint64_t m)
 
 	d = (double)m;
 #ifdef DEBUG_MIASM_DOUBLE
-	printf("%"PRId64" %e\n", m, d);
+	dump_float();
+	printf("%"PRId64" double %e\n", m, d);
 #endif
 	return d;
 }
@@ -970,7 +1001,8 @@ int double_to_int_32(double d)
 
 	i = (int)d;
 #ifdef DEBUG_MIASM_DOUBLE
-	printf("%e %d\n", d, i);
+	dump_float();
+	printf("%e int %d\n", d, i);
 #endif
 	return i;
 }
@@ -980,7 +1012,8 @@ double fadd(double a, double b)
 	double c;
 	c = a + b;
 #ifdef DEBUG_MIASM_DOUBLE
-	printf("%e %e %e\n", a, b, c);
+	dump_float();
+	printf("%e + %e -> %e\n", a, b, c);
 #endif
 	return c;
 }
@@ -990,7 +1023,8 @@ double fsub(double a, double b)
 	double c;
 	c = a - b;
 #ifdef DEBUG_MIASM_DOUBLE
-	printf("%e %e %e\n", a, b, c);
+	dump_float();
+	printf("%e - %e -> %e\n", a, b, c);
 #endif
 	return c;
 }
@@ -1000,7 +1034,8 @@ double fmul(double a, double b)
 	double c;
 	c = a * b;
 #ifdef DEBUG_MIASM_DOUBLE
-	printf("%e %e %e\n", a, b, c);
+	dump_float();
+	printf("%e * %e -> %e\n", a, b, c);
 #endif
 	return c;
 }
@@ -1010,7 +1045,8 @@ double fdiv(double a, double b)
 	double c;
 	c = a / b;
 #ifdef DEBUG_MIASM_DOUBLE
-	printf("%e %e %e\n", a, b, c);
+	dump_float();
+	printf("%e / %e -> %e\n", a, b, c);
 #endif
 	return c;
 }
@@ -1020,7 +1056,8 @@ double ftan(double a)
 	double b;
 	b = tan(a);
 #ifdef DEBUG_MIASM_DOUBLE
-	printf("%e %e\n", a, b);
+	dump_float();
+	printf("%e tan %e\n", a, b);
 #endif
 	return b;
 }
@@ -1032,7 +1069,8 @@ double frndint(double a)
 	b = (int64_t)a;
 	c = (double)b;
 #ifdef DEBUG_MIASM_DOUBLE
-	printf("%e %e\n", a, c);
+	dump_float();
+	printf("%e double %e\n", a, c);
 #endif
 	return c;
 }
@@ -1042,7 +1080,8 @@ double fsin(double a)
 	double b;
 	b = sin(a);
 #ifdef DEBUG_MIASM_DOUBLE
-	printf("%e %e\n", a, b);
+	dump_float();
+	printf("%e sin %e\n", a, b);
 #endif
 	return b;
 }
@@ -1052,7 +1091,8 @@ double fcos(double a)
 	double b;
 	b = cos(a);
 #ifdef DEBUG_MIASM_DOUBLE
-	printf("%e %e\n", a, b);
+	dump_float();
+	printf("%e cos %e\n", a, b);
 #endif
 	return b;
 }
@@ -1063,7 +1103,8 @@ double fscale(double a, double b)
 	double c;
 	c = a * exp2(trunc(b));
 #ifdef DEBUG_MIASM_DOUBLE
-	printf("%e %e %e\n", a, b, c);
+	dump_float();
+	printf("%e *exp2 %e -> %e\n", a, b, c);
 #endif
 	return c;
 }
@@ -1073,7 +1114,8 @@ double f2xm1(double a)
 	double b;
 	b = exp2(a)-1;
 #ifdef DEBUG_MIASM_DOUBLE
-	printf("%e %e\n", a, b);
+	dump_float();
+	printf("%e exp2 -1 %e\n", a, b);
 #endif
 	return b;
 }
@@ -1083,7 +1125,8 @@ double fsqrt(double a)
 	double b;
 	b = sqrt(a);
 #ifdef DEBUG_MIASM_DOUBLE
-	printf("%e %e\n", a, b);
+	dump_float();
+	printf("%e sqrt %e\n", a, b);
 #endif
 	return b;
 }
@@ -1093,7 +1136,8 @@ double fabs(double a)
 	double b;
 	b = abs(a);
 #ifdef DEBUG_MIASM_DOUBLE
-	printf("%e %e\n", a, b);
+	dump_float();
+	printf("%e abs %e\n", a, b);
 #endif
 	return b;
 }
@@ -1130,6 +1174,7 @@ unsigned int double_to_mem_32(double d)
 	f = d;
 	m = *((unsigned int*)&f);
 #ifdef DEBUG_MIASM_DOUBLE
+	dump_float();
 	printf("%d %e\n", m, d);
 #endif
 	return m;
@@ -1140,6 +1185,7 @@ uint64_t double_to_mem_64(double d)
 	uint64_t m;
 	m = *((uint64_t*)&d);
 #ifdef DEBUG_MIASM_DOUBLE
+	dump_float();
 	printf("%"PRId64" %e\n", m, d);
 #endif
 	return m;
diff --git a/miasm/tools/emul_lib/libcodenat.h b/miasm/tools/emul_lib/libcodenat.h
index 43d247e8..d0f4930a 100644
--- a/miasm/tools/emul_lib/libcodenat.h
+++ b/miasm/tools/emul_lib/libcodenat.h
@@ -506,6 +506,7 @@ unsigned int fcom_c3(double a, double b);
 
 double mem_32_to_double(unsigned int m);
 double mem_64_to_double(uint64_t m);
+double int_16_to_double(unsigned int m);
 double int_32_to_double(unsigned int m);
 double int_64_to_double(uint64_t m);
 int double_to_int_32(double d);
@@ -515,26 +516,25 @@ uint64_t double_to_mem_64(double d);
 
 
 #define shift_right_arith_08(a, b)\
-	((((char)(a)) >> ((int)(b)))&0xff)
+	((((char)(a)) >> ((int)(b)&0x1f))&0xff)
 #define shift_right_arith_16(a, b)\
-	((((short)(a)) >> ((int)(b)))&0xffff)
+	((((short)(a)) >> ((int)(b)&0x1f))&0xffff)
 #define shift_right_arith_32(a, b)\
-	((((int)(a)) >> ((int)(b)))&0xffffffff)
+	((((int)(a)) >> ((int)(b)&0x1f))&0xffffffff)
 
 
 #define shift_right_logic_08(a, b)\
-	((((unsigned char)(a)) >> ((unsigned int)(b)))&0xff)
+	((((unsigned char)(a)) >> ((unsigned int)(b)&0x1f))&0xff)
 #define shift_right_logic_16(a, b)\
-	((((unsigned short)(a)) >> ((unsigned int)(b)))&0xffff)
+	((((unsigned short)(a)) >> ((unsigned int)(b)&0x1f))&0xffff)
 #define shift_right_logic_32(a, b)\
-	((((unsigned int)(a)) >> ((unsigned int)(b)))&0xffffffff)
-
+	((((unsigned int)(a)) >> ((unsigned int)(b)&0x1f))&0xffffffff)
 
 #define shift_left_logic_08(a, b)\
-	(((a)<<(b))&0xff)
+	(((a)<<((b)&0x1f))&0xff)
 #define shift_left_logic_16(a, b)\
-	(((a)<<(b))&0xffff)
+	(((a)<<((b)&0x1f))&0xffff)
 #define shift_left_logic_32(a, b)\
-	(((a)<<(b))&0xffffffff)
+	(((a)<<((b)&0x1f))&0xffffffff)
 
 #endif
diff --git a/miasm/tools/nux_api.py b/miasm/tools/nux_api.py
index 07a7aca9..569a0f3b 100644
--- a/miasm/tools/nux_api.py
+++ b/miasm/tools/nux_api.py
@@ -693,6 +693,8 @@ def parse_fmt(s):
         i+=1
         while fmt[i+j] in "0123456789$.":
             j+=1
+        if fmt[i+j] in ['l']:
+            j +=1
         if fmt[i+j] == "h":
             x = fmt[i+j:i+j+2]
         else:
diff --git a/miasm/tools/pe_helper.py b/miasm/tools/pe_helper.py
index f8955eb1..b3c70278 100644
--- a/miasm/tools/pe_helper.py
+++ b/miasm/tools/pe_helper.py
@@ -64,13 +64,13 @@ def func_from_import(pe_name, func):
     if type(func) is str:
         for i, n in enumerate(e.DirExport.f_names):
             if n.name.name == func:
-                found = e.DirExport.f_address[e.DirExport.f_nameordinals[i].ordinal]
+                found = e.DirExport.f_address[e.DirExport.f_nameordinals[i].ordinal].rva
                 break
 
     elif type(func) in [int, long]:
         for i, n in enumerate(e.DirExport.f_names):
             if e.DirExport.f_nameordinals[i].ordinal+e.DirExport.expdesc.base == func:
-                found = e.DirExport.f_address[e.DirExport.f_nameordinals[i].ordinal]
+                found = e.DirExport.f_address[e.DirExport.f_nameordinals[i].ordinal].rva
                 break
     else:
         raise ValueError('unknown fund type', func)
@@ -300,6 +300,10 @@ def code_is_jmp_imp(e, ad, imp_d):
     return is_jmp_imp(l, imp_d)
 
 
+def test_ret_and_cc(in_str, ad):
+    while in_str[ad] == "\xCC":
+        ad -=1
+    return in_str[ad] == '\xC3' or in_str[ad-2] == "\xC2"
 
 # giving e and address in function guess function start
 def guess_func_start(in_str, line_ad, max_offset = 0x200):
@@ -317,7 +321,10 @@ def guess_func_start(in_str, line_ad, max_offset = 0x200):
             if in_str[ad] == "\xCC":
                 if in_str[((ad+3)&~3)-1] == "\xCC":
                     ad_found = ((ad+3)&~3)
-                    break
+                    if test_ret_and_cc(in_str, ad_found):
+                        break
+                    else:
+                        continue
                 else:
                     continue
             l = x86_mn.dis(in_str[ad:ad+15])
@@ -388,8 +395,10 @@ def is_redirected_export(e, ad):
 
 def canon_libname_libfunc(libname, libfunc):
     dn = libname.split('.')[0]
-    fn = "%s"%libfunc
-    return "%s_%s"%(dn, fn)
+    if type(libfunc) == str:
+        return "%s_%s"%(dn, libfunc)
+    else:
+        return str(dn), libfunc
 
 class libimp:
     def __init__(self, lib_base_ad = 0x77700000):
@@ -661,10 +670,18 @@ def preload_elf(e, patch_vm_imp = True, lib_base_ad = 0x77700000):
 
 def get_export_name_addr_list(e):
     out = []
+    # add func name
     for i, n in enumerate(e.DirExport.f_names):
         addr = e.DirExport.f_address[e.DirExport.f_nameordinals[i].ordinal]
         f_name = n.name.name
+        #print f_name, hex(e.rva2virt(addr.rva))
         out.append((f_name, e.rva2virt(addr.rva)))
+
+    # add func ordinal
+    for i, o in enumerate(e.DirExport.f_nameordinals):
+        addr = e.DirExport.f_address[o.ordinal]
+        #print o.ordinal, e.DirExport.expdesc.base, hex(e.rva2virt(addr.rva))
+        out.append((o.ordinal+e.DirExport.expdesc.base, e.rva2virt(addr.rva)))
     return out
 
 
diff --git a/miasm/tools/seh_helper.py b/miasm/tools/seh_helper.py
index c0d95d3f..efdd7191 100644
--- a/miasm/tools/seh_helper.py
+++ b/miasm/tools/seh_helper.py
@@ -17,7 +17,16 @@
 #
 #from codenat import *
 from to_c_helper import *
+from elfesteem import *
 import to_c_helper
+import logging
+
+
+log = logging.getLogger("seh_helper")
+console_handler = logging.StreamHandler()
+console_handler.setFormatter(logging.Formatter("%(levelname)-5s: %(message)s"))
+log.addHandler(console_handler)
+log.setLevel(logging.WARN)
 
 FS_0_AD = 0x7ff70000
 PEB_AD = 0x7ffdf000
@@ -32,17 +41,21 @@ peb_ldr_data_offset = 0x1ea0
 peb_ldr_data_address = LDR_AD + peb_ldr_data_offset#PEB_AD + 0x1000
 
 
-InInitializationOrderModuleList_offset = 0x1f48
+modules_list_offset = 0x1f00
+
+InInitializationOrderModuleList_offset = 0x1ee0 #0x1f48
 InInitializationOrderModuleList_address = LDR_AD + InInitializationOrderModuleList_offset#PEB_AD + 0x2000
 
-InLoadOrderModuleList_offset = 0x1f48 + MAX_MODULES*0x1000
+InLoadOrderModuleList_offset = 0x1ee0+MAX_MODULES*0x1000#0x1f48 + MAX_MODULES*0x1000
 InLoadOrderModuleList_address = LDR_AD + InLoadOrderModuleList_offset#PEB_AD + 0x2000
 
 #in_load_order_module_1 = LDR_AD + in_load_order_module_list_offset#PEB_AD + 0x3000
 default_seh = PEB_AD + 0x20000
 
+process_environment_address = 0x10000
+process_parameters_address = 0x200000
 
-context_address = 0x200000
+context_address = 0x201000
 exception_record_address = context_address+0x1000
 return_from_exception = 0x6eadbeef
 
@@ -86,6 +99,7 @@ def build_fake_peb():
     +0x004 Mutant                   : Ptr32 Void
     +0x008 ImageBaseAddress         : Ptr32 Void
     +0x00c Ldr                      : Ptr32 _PEB_LDR_DATA
+    +0x010 processparameter
     """
 
     offset_serverdata = 0x100
@@ -98,6 +112,7 @@ def build_fake_peb():
     else:
         o += "AAAA"
     o += pdw(peb_ldr_data_address)
+    o += pdw(process_parameters_address)
 
     o += (0x54 - len(o)) *"A"
     o += pdw(peb_address+offset_serverdata)
@@ -113,7 +128,7 @@ def build_fake_peb():
     return o
 
 
-def build_fake_ldr_data():
+def build_fake_ldr_data(modules_info):
     """
     +0x000 Length                          : Uint4B
     +0x004 Initialized                     : UChar
@@ -127,9 +142,31 @@ def build_fake_ldr_data():
     o += "\x00" * peb_ldr_data_offset
     o += "\x00"*0xc
     #text XXX
-    o += pdw(InLoadOrderModuleList_address) + pdw(0)
-    o += pdw(InInitializationOrderModuleList_address+8) + pdw(0)
-    o += pdw(InInitializationOrderModuleList_address+0x10) + pdw(0)
+
+    # get main pe info
+    m_e = None
+    for bname, (addr, e) in modules_info.items():
+        if e == main_pe:
+            m_e = (e, bname, addr)
+            break
+    if not m_e:
+        log.warn('no main pe, ldr data will be unconsistant')
+    else:
+        print 'inloadorder first', hex(m_e[2])
+        o += pdw(m_e[2]) + pdw(0)
+
+    # get ntdll
+    ntdll_e = None
+    for bname, (addr, e) in modules_info.items():
+        if bname[::2].lower() == "ntdll.dll":
+            ntdll_e = (e, bname, addr)
+            continue
+    if not ntdll_e:
+        log.warn('no ntdll, ldr data will be unconsistant')
+    else:
+        print 'ntdll', hex(ntdll_e[2])
+        o += pdw(ntdll_e[2]+0x10) + pdw(0) # XXX TODO
+        o += pdw(ntdll_e[2]+0x10) + pdw(0)
 
 
     return o
@@ -237,6 +274,151 @@ def build_fake_InInitializationOrderModuleList(modules_name):
     return o
 
 
+dummy_e = pe_init.PE()
+dummy_e.NThdr.ImageBase = 0
+dummy_e.Opthdr.AddressOfEntryPoint = 0
+dummy_e.NThdr.sizeofimage = 0
+
+def create_modules_chain(modules_name):
+    modules_info = {}
+    base_addr = LDR_AD + modules_list_offset #XXXX
+    offset_name = 0x500
+    offset_path = 0x600
+
+
+    out = ""
+    for i, m in enumerate([(main_pe_name, main_pe), ("", dummy_e)] + modules_name):
+        addr = base_addr + i*0x1000
+        #fname = os.path.join('win_dll', m)
+        if isinstance(m, tuple):
+            fname, e = m
+        else:
+            fname, e = m, None
+        bpath = fname.replace('/', '\\')
+        bname = os.path.split(fname)[1].lower()
+        bname = "\x00".join(bname)+"\x00"
+        print "add module", repr(bname), repr(bpath)
+        #print hex(InInitializationOrderModuleList_address+i*0x1000)
+        if e == None:
+            e = pe_init.PE(open(fname, 'rb').read())
+        modules_info[bname] = addr, e
+
+        m_o = ""
+        m_o += pdw(0)
+        m_o += pdw(0)
+        m_o += pdw(0)
+        m_o += pdw(0)
+        m_o += pdw(0)
+        m_o += pdw(0)
+        m_o += pdw(e.NThdr.ImageBase)
+        m_o += pdw(e.rva2virt(e.Opthdr.AddressOfEntryPoint))
+        m_o += pdw(e.NThdr.sizeofimage)
+
+        m_o += (0x24 - len(m_o))*"A"
+        print hex(len(bname)), repr(bname)
+        m_o += struct.pack('HH', len(bname), len(bname)+2)
+        m_o += pdw(addr+offset_path)
+
+        m_o += (0x2C - len(m_o))*"A"
+        m_o += struct.pack('HH', len(bname), len(bname)+2)
+        m_o += pdw(addr + offset_name)
+
+        m_o += (offset_name - len(m_o))*"B"
+        m_o += bname
+        m_o += "\x00"*3
+
+        m_o += (offset_path - len(m_o))*"B"
+        m_o += "\x00".join(bpath)+"\x00"
+        m_o += "\x00"*3
+        #out += m_o
+        vm_set_mem(addr, m_o)
+    return modules_info
+
+
+def fix_InLoadOrderModuleList(module_info):
+    # first binary is PE
+    # last is dumm_e
+    olist =[]
+    m_e = None
+    d_e = None
+    for bname, (addr, e) in module_info.items():
+        print bname
+        if e == main_pe:
+            m_e = (e, bname, addr)
+            continue
+        elif e == dummy_e:
+            d_e = (e, bname, addr)
+            continue
+        olist.append((e, bname, addr))
+    if not m_e or not d_e:
+        log.warn('no main pe, ldr data will be unconsistant')
+    else:
+        olist[0:0] =[m_e]
+    olist.append(d_e)
+
+    last_addr = 0
+    for i in xrange(len(olist)):
+        e, bname, addr = olist[i]
+        p_e, p_bname, p_addr = olist[(i-1)%len(olist)]
+        n_e, n_bname, n_addr = olist[(i+1)%len(olist)]
+        vm_set_mem(addr+0, pdw(p_addr)+pdw(n_addr))
+
+
+
+def fix_InInitializationOrderModuleList(module_info):
+    # first binary is ntdll
+    # second binary is kernel32
+    olist =[]
+    ntdll_e = None
+    kernel_e= None
+    for bname, (addr, e) in module_info.items():
+        if bname[::2].lower() == "ntdll.dll":
+            ntdll_e = (e, bname, addr)
+            continue
+        elif bname[::2].lower() == "kernel32.dll":
+            kernel_e = (e, bname, addr)
+            continue
+        elif e == dummy_e:
+            d_e = (e, bname, addr)
+            continue
+        elif e == main_pe:
+            continue
+        olist.append((e, bname, addr))
+    if not ntdll_e or not kernel_e or not d_e:
+        log.warn('no kernel ntdll, ldr data will be unconsistant')
+    else:
+        olist[0:0] =[ntdll_e]
+        olist[1:1] =[kernel_e]
+
+    olist.append(d_e)
+
+    last_addr = 0
+    for i in xrange(len(olist)):
+        e, bname, addr = olist[i]
+        p_e, p_bname, p_addr = olist[(i-1)%len(olist)]
+        n_e, n_bname, n_addr = olist[(i+1)%len(olist)]
+        vm_set_mem(addr+0x10, pdw(p_addr)+pdw(n_addr))
+
+
+def add_process_env():
+    env_str = 'ALLUSERSPROFILE=C:\\Documents and Settings\\All Users\x00'
+    env_str = '\x00'.join(env_str)
+    env_str += "\x00"*0x10
+    vm_add_memory_page(process_environment_address,
+                       PAGE_READ | PAGE_WRITE,
+                       env_str)
+    vm_set_mem(process_environment_address, env_str)
+
+def add_process_parameters():
+    o = ""
+    o+= pdw(0x1000) #size
+    o += "E"*(0x48 - len(o))
+    o += pdw(process_environment_address)
+    vm_add_memory_page(process_parameters_address,
+                       PAGE_READ | PAGE_WRITE,
+                       o)
+
+
 def build_fake_InLoadOrderModuleList(modules_name):
     """
     +0x000 Flink : Ptr32                                 -+ This distance
@@ -349,13 +531,24 @@ def init_seh():
     vm_add_memory_page(peb_address, PAGE_READ | PAGE_WRITE, build_fake_peb())
     #vm_add_memory_page(peb_ldr_data_address, PAGE_READ | PAGE_WRITE, p(0) * 3 + p(in_load_order_module_list_address) + p(0) * 0x20)
 
-    ldr_data = build_fake_ldr_data()
+    """
     ldr_data += "\x00"*(InInitializationOrderModuleList_offset - len(ldr_data))
     ldr_data += build_fake_InInitializationOrderModuleList(loaded_modules)
     ldr_data += "\x00"*(InLoadOrderModuleList_offset - len(ldr_data))
     ldr_data += build_fake_InLoadOrderModuleList(loaded_modules)
+    """
+    vm_add_memory_page(LDR_AD, PAGE_READ | PAGE_WRITE, "\x00"*MAX_MODULES*0x1000)
+    module_info = create_modules_chain(loaded_modules)
+    fix_InLoadOrderModuleList(module_info)
+    fix_InInitializationOrderModuleList(module_info)
+
+    ldr_data = build_fake_ldr_data(module_info)
+    vm_set_mem(LDR_AD, ldr_data)
+    add_process_env()
+    add_process_parameters()
+
+    #fds
 
-    vm_add_memory_page(LDR_AD, PAGE_READ | PAGE_WRITE, ldr_data)
     #vm_add_memory_page(in_load_order_module_list_address, PAGE_READ | PAGE_WRITE, p(0) * 40)
     #    vm_add_memory_page(in_load_order_module_list_address, PAGE_READ | PAGE_WRITE, build_fake_inordermodule(loaded_modules))
     vm_add_memory_page(default_seh, PAGE_READ | PAGE_WRITE, p(0xffffffff) + p(0x41414141) + p(0x42424242))
diff --git a/miasm/tools/to_c_helper.py b/miasm/tools/to_c_helper.py
index 38f21272..d8d77db1 100644
--- a/miasm/tools/to_c_helper.py
+++ b/miasm/tools/to_c_helper.py
@@ -1163,7 +1163,11 @@ def load_pe_in_vm(fname_in, options, all_imp_dll = None, **kargs):
     from miasm.tools import pe_helper
     from miasm.tools import codenat
 
-    e = pe_init.PE(open(fname_in, 'rb').read())
+    parse_resources = True
+    if 'parse_resources' in kargs:
+        parse_resources = kargs['parse_resources']
+    e = pe_init.PE(open(fname_in, 'rb').read(),
+                   parse_resources = parse_resources)
 
     vm_init_regs()
     init_memory_page_pool_py()
@@ -1201,7 +1205,7 @@ def load_pe_in_vm(fname_in, options, all_imp_dll = None, **kargs):
     seh_helper.runtime_dll = runtime_dll
     if options.loadmainpe:
         seh_helper.main_pe = e
-    seh_helper.main_pe_name = "c:\\xxx\\"+kargs.get("main_pe_name", "toto.exe")
+    seh_helper.main_pe_name = kargs.get("main_pe_name", "toto.exe")
     seh_helper.loaded_modules = all_pe
     dll_dyn_funcs = pe_helper.preload_lib(e, runtime_dll)
 
@@ -1215,7 +1219,11 @@ def load_pe_in_vm(fname_in, options, all_imp_dll = None, **kargs):
     if 'stack_size' in kargs:
         stack_size = kargs['stack_size']
 
-    stack_base_ad = kargs.get('stack_base_ad', 0x1230000)
+    stack_base = 0x1230000
+    if 'stack_base' in kargs:
+        stack_base = kargs['stack_base']
+
+    stack_base_ad = kargs.get('stack_base_ad', stack_base)
     stack_size = kargs.get('stack_size', stack_size)
     vm_add_memory_page(stack_base_ad,
                                    codenat.PAGE_READ|codenat.PAGE_WRITE,
@@ -1269,13 +1277,15 @@ def vm2pe(fname, runtime_dll = None, e_orig = None, max_addr = 1<<64):
         xx = str(mye)
         mye.content = xx
         ad = e_orig.rva2virt(e_orig.NThdr.optentries[pe.DIRECTORY_ENTRY_RESOURCE].rva)
-        ad = mye.virt2rva(ad)
-        mye.NThdr.optentries[pe.DIRECTORY_ENTRY_RESOURCE].rva = ad
-        mye.DirRes = pe.DirRes.unpack(xx,ad,mye)
-        #print repr(mye.DirRes)
-        s_res = mye.SHList.add_section(name = "myres", rawsize = len(mye.DirRes))
-        mye.DirRes.set_rva(s_res.addr)
-        print repr(mye.DirRes)
+        print 'dirres', hex(ad)
+        if ad != 0:
+            ad = mye.virt2rva(ad)
+            mye.NThdr.optentries[pe.DIRECTORY_ENTRY_RESOURCE].rva = ad
+            mye.DirRes = pe.DirRes.unpack(xx,ad,mye)
+            #print repr(mye.DirRes)
+            s_res = mye.SHList.add_section(name = "myres", rawsize = len(mye.DirRes))
+            mye.DirRes.set_rva(s_res.addr)
+            print repr(mye.DirRes)
 
     # generation
     open(fname, 'w').write(str(mye))
@@ -1319,7 +1329,7 @@ def do_bloc_emul(known_blocs, in_str, my_eip, symbol_pool,
     if not known_blocs[my_eip].b.lines:
         raise ValueError('cannot disasm bloc')
     try:
-        my_eip = vm_exec_blocs(my_eip, known_blocs)
+        my_eip = vm_exec_bloc(my_eip, known_blocs)
     except KeyboardInterrupt:
         return None, None
     py_exception = vm_get_exception()