about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorserpilliere <devnull@localhost>2012-01-05 13:15:30 +0100
committerserpilliere <devnull@localhost>2012-01-05 13:15:30 +0100
commit4bdf44eb84410b5f9b496512dfed58700417ed31 (patch)
treefac48fa2716c265e3e2af8f741c333d532c8442d
parentb617192330c9f0738e1f6c06a6dd3e7cbc651743 (diff)
downloadmiasm-4bdf44eb84410b5f9b496512dfed58700417ed31.tar.gz
miasm-4bdf44eb84410b5f9b496512dfed58700417ed31.zip
fix 16 bit bug in x86 arch
-rw-r--r--miasm/arch/ia32_arch.py14
-rw-r--r--miasm/arch/ia32_sem.py65
-rw-r--r--miasm/expression/expression.py4
-rw-r--r--miasm/tools/emul_lib/libcodenat.c13
-rw-r--r--miasm/tools/emul_lib/libcodenat.h4
5 files changed, 85 insertions, 15 deletions
diff --git a/miasm/arch/ia32_arch.py b/miasm/arch/ia32_arch.py
index 6d4b7b24..9638dea8 100644
--- a/miasm/arch/ia32_arch.py
+++ b/miasm/arch/ia32_arch.py
@@ -1677,7 +1677,7 @@ class x86_mn:
                              x86_afs.ad:True,
                              x86_afs.size:s,
                              x86_afs.segm:x86_afs.reg_sg.index(x86_afs.r_es)}]
-            if self.m.name.startswith("movs"):
+            if self.m.name != "movsx" and self.m.name.startswith("movs"):
                 if self.m.name[-1] == "b":
                     s = u08
                 elif self.opmode == u16:
@@ -2263,6 +2263,18 @@ if __name__ == '__main__':
     test_out = []
     log.setLevel(logging.DEBUG)
 
+    instr = x86mnemo.dis('0fbe13'.replace(' ', '').decode('hex'),)
+                         #admode=x86_afs.u16,
+                         #opmode=x86_afs.u16)
+    print instr
+    print instr.arg
+    print instr.l
+    print instr.arg[1]["imm"].__class__
+    print instr.opmode, instr.admode
+    fds
+
+
+
     instr = x86mnemo.dis('038678ff'.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 4f921708..114540f6 100644
--- a/miasm/arch/ia32_sem.py
+++ b/miasm/arch/ia32_sem.py
@@ -1070,30 +1070,44 @@ def popfw(info):
 
 def pushad(info):
     e = []
-    s = 32
-    if not s in [16,32]:
-        raise 'bad size stacker!'
-    regs = [eax, ecx, edx, ebx, esp, ebp, esi, edi]
+    opmode, admode = info
+    if opmode == u16:
+        s = 16
+        myesp = esp[:16]
+        regs = [eax[:16], ecx[:16], edx[:16], ebx[:16],
+                esp[:16], ebp[:16], esi[:16], edi[:16]]
+    else:
+        s = 32
+        myesp = esp
+        regs = [eax, ecx, edx, ebx, esp, ebp, esi, edi]
+    int_cast = tab_uintsize[s]
     for i in xrange(len(regs)):
-        c = ExprOp('+', esp, ExprInt(uint32(-(s/8)*(i+1))))
+        c = ExprOp('+', myesp, ExprInt(int_cast(-(s/8)*(i+1))))
         e.append(ExprAff(ExprMem(c, s), regs[i]))
-    e.append(ExprAff(esp, c))
+    e.append(ExprAff(myesp, c))
     return e
 
 def popad(info):
     e = []
-    s = 32
-    if not s in [16,32]:
-        raise 'bad size stacker!'
-    regs = [eax, ecx, edx, ebx, esp, ebp, esi, edi]
+    opmode, admode = info
+    if opmode == u16:
+        s = 16
+        myesp = esp[:16]
+        regs = [eax[:16], ecx[:16], edx[:16], ebx[:16],
+                esp[:16], ebp[:16], esi[:16], edi[:16]]
+    else:
+        s = 32
+        myesp = esp
+        regs = [eax, ecx, edx, ebx, esp, ebp, esi, edi]
+    int_cast = tab_uintsize[s]
     regs.reverse()
     for i in xrange(len(regs)):
-        if regs[i] == esp:
+        if regs[i] == myesp:
             continue
-        c = ExprOp('+', esp, ExprInt(uint32((s/8)*i)))
+        c = ExprOp('+', esp, ExprInt(int_cast((s/8)*i)))
         e.append(ExprAff(regs[i], ExprMem(c, s)))
 
-    c = ExprOp('+', esp, ExprInt(uint32((s/8)*(i+1))))
+    c = ExprOp('+', myesp, ExprInt(int_cast((s/8)*(i+1))))
     e.append(ExprAff(esp, c))
 
     return e
@@ -1130,6 +1144,24 @@ def ret(info, a = ExprInt(uint32(0))):
     e.append(ExprAff(eip, ExprMem(myesp, size = s)))
     return e
 
+def retf(info, a = ExprInt(uint32(0))):
+    e = []
+    opmode, admode = info
+    if opmode == u16:
+        s = 16
+        myesp = esp[:16]
+    else:
+        s = 32
+        myesp = esp
+    int_cast = tab_uintsize[s]
+    e.append(ExprAff(myesp, ExprOp('+', myesp, ExprOp('+', ExprInt(int_cast(s/8 + 2)), a))))
+    e.append(ExprAff(eip, ExprMem(myesp, size = s)))
+    e.append(ExprAff(cs, ExprMem(ExprOp('+', myesp, ExprInt(int_cast(s/8))),
+                                 size=16)))
+
+
+    return e
+
 def leave(info):
     opmode, admode = info
     if opmode == u16:
@@ -2008,6 +2040,7 @@ mnemo_func = {'mov': mov,
               'popad':popad,
               'call':call,
               'ret':ret,
+              'retf':retf,
               'leave':leave,
               'enter':enter,
               'jmp':jmp,
@@ -2304,7 +2337,11 @@ def dict_to_Expr(d, modifs = {}, opmode = u32, admode = u32, segm_to_do = {}):
             return ExprInt(uint32(myval))
     elif is_address(d):
         int_cast = tab_afs_int[admode]
-        segm = None
+        #segm = None
+        # XXX test
+        segm = x86_afs.r_ds
+        segm = segm_dict[segm]
+
 
         size = {ia32_rexpr.u08:8, ia32_rexpr.u16:16, ia32_rexpr.u32:32, ia32_rexpr.f32:32, ia32_rexpr.f64:64}[size]
         if ia32_rexpr.size in d:
diff --git a/miasm/expression/expression.py b/miasm/expression/expression.py
index 55e7e265..07cb0e1f 100644
--- a/miasm/expression/expression.py
+++ b/miasm/expression/expression.py
@@ -535,6 +535,10 @@ class ExprOp(Expr):
                             self.args[0].toC(),
                             self.args[1].toC())
 
+            elif self.op in ['umul16_lo', 'umul16_hi']:
+                return '%s(%s, %s)' %(self.op,
+                            self.args[0].toC(),
+                            self.args[1].toC())
             elif self.op in ['bsr', 'bsf']:
                 return 'my_%s(%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 7a3e0daa..469928d4 100644
--- a/miasm/tools/emul_lib/libcodenat.c
+++ b/miasm/tools/emul_lib/libcodenat.c
@@ -635,6 +635,19 @@ int imul_hi_op_32(int a, int b)
 	return res>>32;
 }
 
+unsigned int umul16_lo(unsigned short a, unsigned short b)
+{
+	return (a*b) & 0xffff;
+}
+
+unsigned int umul16_hi(unsigned short a, unsigned short b)
+{
+	uint32_t c;
+	c = a*b;
+	return (c>>16) & 0xffff;
+}
+
+
 
 
 unsigned int div_op(unsigned int size, unsigned int a, unsigned int b, unsigned int c)
diff --git a/miasm/tools/emul_lib/libcodenat.h b/miasm/tools/emul_lib/libcodenat.h
index bb123096..3c4c16e1 100644
--- a/miasm/tools/emul_lib/libcodenat.h
+++ b/miasm/tools/emul_lib/libcodenat.h
@@ -336,6 +336,10 @@ int imul_hi_op_16(short a, short b);
 int imul_hi_op_32(int a, int b);
 
 
+unsigned int umul16_lo(unsigned short a, unsigned short b);
+unsigned int umul16_hi(unsigned short a, unsigned short b);
+
+
 unsigned int div_op(unsigned int size, unsigned int a, unsigned int b, unsigned int c);
 unsigned int rem_op(unsigned int size, unsigned int a, unsigned int b, unsigned int c);
 int rot_left(unsigned int size, unsigned int a, unsigned int b);