about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--miasm2/analysis/sandbox.py2
-rw-r--r--miasm2/arch/x86/sem.py60
-rw-r--r--test/samples/x86_64/mul_div.S55
-rw-r--r--test/test_all.py51
4 files changed, 130 insertions, 38 deletions
diff --git a/miasm2/analysis/sandbox.py b/miasm2/analysis/sandbox.py
index 9fdae8cf..3b710719 100644
--- a/miasm2/analysis/sandbox.py
+++ b/miasm2/analysis/sandbox.py
@@ -289,7 +289,7 @@ class Arch_x86_32(Arch_x86):
     _ARCH_ = "x86_32"
 
 
-class Arch_x86_64(Arch):
+class Arch_x86_64(Arch_x86):
     _ARCH_ = "x86_64"
 
 
diff --git a/miasm2/arch/x86/sem.py b/miasm2/arch/x86/sem.py
index 93e24350..585d4190 100644
--- a/miasm2/arch/x86/sem.py
+++ b/miasm2/arch/x86/sem.py
@@ -1399,21 +1399,13 @@ def loope(ir, instr, dst):
 # XXX size to do; eflag
 def div(ir, instr, a):
     e = []
-    s = a.size
-    if s == 8:
+    size = a.size
+    if size == 8:
         b = mRAX[instr.mode][:16]
-    elif s == 16:
-        s1, s2 = mRDX[instr.mode][:16], mRAX[instr.mode][:16]
-        b = ExprCompose([(s1, 0, 16),
-                         (s1, 16, 32)])
-    elif s == 32:
-        s1, s2 = mRDX[instr.mode][:32], mRAX[instr.mode][:32]
-        b = ExprCompose([(s2, 0, 32),
-                         (s1, 32, 64)])
-    elif s == 64:
-        s1, s2 = mRDX[instr.mode], mRAX[instr.mode]
-        b = ExprCompose([(s2, 0, 64),
-                         (s1, 64, 128)])
+    elif size in [16, 32, 64]:
+        s1, s2 = mRDX[size], mRAX[size]
+        b = ExprCompose([(s2, 0, size),
+                         (s1, size, size*2)])
     else:
         raise ValueError('div arg not impl', a)
 
@@ -1421,12 +1413,12 @@ def div(ir, instr, a):
     c_r = ExprOp('umod', b, a.zeroExtend(b.size))
 
     # if 8 bit div, only ax is affected
-    if s == 8:
+    if size == 8:
         e.append(ExprAff(b, ExprCompose([(c_d[:8], 0, 8),
                                          (c_r[:8], 8, 16)])))
     else:
-        e.append(ExprAff(s1, c_r[:s]))
-        e.append(ExprAff(s2, c_d[:s]))
+        e.append(ExprAff(s1, c_r[:size]))
+        e.append(ExprAff(s2, c_d[:size]))
     return e, []
 
 # XXX size to do; eflag
@@ -1434,18 +1426,14 @@ def div(ir, instr, a):
 
 def idiv(ir, instr, a):
     e = []
-    s = a.size
+    size = a.size
 
-    if s == 8:
+    if size == 8:
         b = mRAX[instr.mode][:16]
-    elif s == 16:
-        s1, s2 = mRDX[instr.mode][:16], mRAX[instr.mode][:16]
-        b = ExprCompose([(s1, 0, 16),
-                         (s1, 16, 32)])
-    elif s == 32:
-        s1, s2 = mRDX[instr.mode][:32], mRAX[instr.mode][:32]
-        b = ExprCompose([(s2, 0, 32),
-                         (s1, 32, 64)])
+    elif size in [16, 32]:
+        s1, s2 = mRDX[size], mRAX[size]
+        b = ExprCompose([(s2, 0, size),
+                         (s1, size, size*2)])
     else:
         raise ValueError('div arg not impl', a)
 
@@ -1453,12 +1441,12 @@ def idiv(ir, instr, a):
     c_r = ExprOp('imod', b, a.signExtend(b.size))
 
     # if 8 bit div, only ax is affected
-    if s == 8:
+    if size == 8:
         e.append(ExprAff(b, ExprCompose([(c_d[:8], 0, 8),
                                          (c_r[:8], 8, 16)])))
     else:
-        e.append(ExprAff(s1, c_r[:s]))
-        e.append(ExprAff(s2, c_d[:s]))
+        e.append(ExprAff(s1, c_r[:size]))
+        e.append(ExprAff(s2, c_d[:size]))
     return e, []
 
 # XXX size to do; eflag
@@ -1469,10 +1457,10 @@ def mul(ir, instr, a):
     size = a.size
     if a.size in [16, 32, 64]:
         result = ExprOp('*',
-                        mRAX[instr.mode][:size].zeroExtend(size * 2),
+                        mRAX[size].zeroExtend(size * 2),
                         a.zeroExtend(size * 2))
-        e.append(ExprAff(mRAX[instr.mode][:size], result[:size]))
-        e.append(ExprAff(mRDX[instr.mode][:size], result[size:size * 2]))
+        e.append(ExprAff(mRAX[size], result[:size]))
+        e.append(ExprAff(mRDX[size], result[size:size * 2]))
 
     elif a.size == 8:
         result = ExprOp('*',
@@ -1498,10 +1486,10 @@ def imul(ir, instr, a, b=None, c=None):
     if b is None:
         if size in [16, 32, 64]:
             result = ExprOp('*',
-                            mRAX[instr.mode][:size].signExtend(size * 2),
+                            mRAX[size].signExtend(size * 2),
                             a.signExtend(size * 2))
-            e.append(ExprAff(mRAX[instr.mode][:size], result[:size]))
-            e.append(ExprAff(mRDX[instr.mode][:size], result[size:size * 2]))
+            e.append(ExprAff(mRAX[size], result[:size]))
+            e.append(ExprAff(mRDX[size], result[size:size * 2]))
         elif size == 8:
             dst = mRAX[instr.mode][:16]
             result = ExprOp('*',
diff --git a/test/samples/x86_64/mul_div.S b/test/samples/x86_64/mul_div.S
new file mode 100644
index 00000000..4a5fcfdd
--- /dev/null
+++ b/test/samples/x86_64/mul_div.S
@@ -0,0 +1,55 @@
+main:
+	;; MUL
+	MOV RCX, 0x20000002
+	MOV RAX, 0x1122334455667788
+	MOV RDX, RAX
+	MOV RAX, 0x1122334400000020
+	MUL ECX
+	CMP RAX, 0x40
+	JNZ bad
+	CMP RDX, 0x4
+	JNZ bad
+
+	;; IMUL
+	MOV RCX, 0xFFFFFFF2
+	MOV RAX, 0x1122334455667788
+	MOV RDX, RAX
+	MOV RAX, 0x1122334400000020
+	IMUL ECX
+	MOV ESI, 0xFFFFFE40
+	CMP RAX, RSI
+	JNZ bad
+	MOV ESI 0xFFFFFFFF
+	CMP RDX, RSI
+	JNZ bad
+
+	;; DIV
+	MOV RAX, 0x1122334400000002
+	MOV RCX, RAX
+	MOV RAX, 0x1122334400000000
+	MOV RDX, RAX
+	MOV RAX, 0x1122334440000003
+	DIV ECX
+	CMP RAX, 0x20000001
+	JNZ bad
+	CMP RDX, 0x1
+	JNZ bad
+
+	;; IDIV
+	MOV RAX, 0x11223344FFFFFFF2
+	MOV RCX, RAX
+	MOV RAX, 0x11223344FFFFFFFF
+	MOV RDX, RAX
+	MOV RAX, 0x11223344FFFFFFF2
+	IDIV ECX
+	CMP RAX, 0x1
+	JNZ bad
+	CMP RDX, 0x0
+	JNZ bad
+
+
+	RET
+
+bad:
+	INT 0x3
+
diff --git a/test/test_all.py b/test/test_all.py
index 66620375..5f0721fc 100644
--- a/test/test_all.py
+++ b/test/test_all.py
@@ -42,6 +42,56 @@ for script in ["x86/sem.py",
                "mips32/arch.py",
                ]:
     testset += RegressionTest([script], base_dir="arch")
+
+
+## Semantic
+class SemanticTestAsm(RegressionTest):
+    """Assemble an asm file"""
+
+    shellcode_script = os.path.join("example", "asm", "shellcode.py")
+    container_dct = {"PE": "--PE"}
+
+    def __init__(self, arch, container, *args, **kwargs):
+        super(SemanticTestAsm, self).__init__(*args, **kwargs)
+        self.base_dir = os.path.join(self.base_dir, "..")
+        sample_dir = os.path.join("test", "samples", arch)
+        base_filename = os.path.join(sample_dir, self.command_line[0])
+        input_filename = base_filename + ".S"
+        output_filename = base_filename + ".bin"
+        self.command_line = [self.shellcode_script,
+                             arch,
+                             input_filename,
+                             output_filename,
+                             self.container_dct.get(container, '')]
+        self.products = [output_filename, "graph.txt"]
+
+
+class SemanticTestExec(RegressionTest):
+    """Execute a binary file"""
+
+    launcher_dct = {("PE", "x86_64"): "sandbox_pe_x86_64.py"}
+    launcher_base = os.path.join("example", "jitter")
+
+    def __init__(self, arch, container, address, *args, **kwargs):
+        super(SemanticTestExec, self).__init__(*args, **kwargs)
+        self.base_dir = os.path.join(self.base_dir, "..")
+        sample_dir = os.path.join("test", "samples", arch)
+        base_filename = os.path.join(sample_dir, self.command_line[0])
+        input_filename = base_filename + ".bin"
+        launcher = os.path.join(self.launcher_base,
+                                self.launcher_dct[(container, arch)])
+        self.command_line = [launcher,
+                             input_filename,
+                             "-a", hex(address)]
+        self.products = []
+
+
+
+test_x86_64_mul_div = SemanticTestAsm("x86_64", "PE", ["mul_div"])
+testset += test_x86_64_mul_div
+testset += SemanticTestExec("x86_64", "PE", 0x401000, ["mul_div"],
+                            depends=[test_x86_64_mul_div])
+
 ## Core
 for script in ["interval.py",
                "graph.py",
@@ -116,7 +166,6 @@ class ExampleShellcode(ExampleAssembler):
                              self.command_line[3:]
         self.products = [self.command_line[3], "graph.txt"]
 
-
 testset += ExampleShellcode(['x86_32', 'x86_32_manip_ptr.S', "demo_x86_32.bin"])
 
 test_box = {}