about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorserpilliere <devnull@localhost>2014-06-17 13:09:31 +0200
committerserpilliere <devnull@localhost>2014-06-17 13:09:31 +0200
commit180b3907cdfcda2e8f3bd719b1d3531ba2e32a5f (patch)
treec91a5e6564ac6579f0a97d9a913540708464f8c3
parent1a1f8fb1bf35def45e651452eb5db27d36486dda (diff)
parentb4672a0881de3a62d6ea711603870db9a28f6cce (diff)
downloadmiasm-180b3907cdfcda2e8f3bd719b1d3531ba2e32a5f.tar.gz
miasm-180b3907cdfcda2e8f3bd719b1d3531ba2e32a5f.zip
merge
-rw-r--r--miasm2/arch/arm/regs.py2
-rw-r--r--miasm2/arch/msp430/regs.py2
-rw-r--r--miasm2/arch/sh4/regs.py2
-rw-r--r--miasm2/arch/x86/regs.py19
-rw-r--r--miasm2/jitter/jitcore_python.py89
-rw-r--r--miasm2/jitter/vm_mngr_py.c19
-rw-r--r--test/test_all.py48
7 files changed, 122 insertions, 59 deletions
diff --git a/miasm2/arch/arm/regs.py b/miasm2/arch/arm/regs.py
index 6ddac2ef..2787605a 100644
--- a/miasm2/arch/arm/regs.py
+++ b/miasm2/arch/arm/regs.py
@@ -66,6 +66,8 @@ all_regs_ids = [
     zf, nf, of, cf
 ]
 
+all_regs_ids_no_alias = all_regs_ids
+
 all_regs_ids_byname = dict([(x.name, x) for x in all_regs_ids])
 
 all_regs_ids_init = [R0_init, R1_init, R2_init, R3_init,
diff --git a/miasm2/arch/msp430/regs.py b/miasm2/arch/msp430/regs.py
index 7a389ae1..ea86e1fc 100644
--- a/miasm2/arch/msp430/regs.py
+++ b/miasm2/arch/msp430/regs.py
@@ -89,6 +89,8 @@ all_regs_ids = [
     cpuoff, gie, osc, scg0, scg1, res,
 ]
 
+all_regs_ids_no_alias = all_regs_ids
+
 all_regs_ids_byname = dict([(x.name, x) for x in all_regs_ids])
 
 all_regs_ids_init = [PC_init, SP_init, SR_init, R3_init,
diff --git a/miasm2/arch/sh4/regs.py b/miasm2/arch/sh4/regs.py
index bfc61b04..6ffe9691 100644
--- a/miasm2/arch/sh4/regs.py
+++ b/miasm2/arch/sh4/regs.py
@@ -70,6 +70,8 @@ all_regs_ids = [
     PC, PR, R0, GBR, SR, VBR, SSR, SPC,
     SGR, DBR, MACH, MACL, FPUL, FR0]
 
+all_regs_ids_no_alias = all_regs_ids
+
 all_regs_ids_byname = dict([(x.name, x) for x in all_regs_ids])
 
 all_regs_ids_init = [ExprId("%s_init" % x.name, x.size) for x in all_regs_ids]
diff --git a/miasm2/arch/x86/regs.py b/miasm2/arch/x86/regs.py
index 532b4f0c..293f81e7 100644
--- a/miasm2/arch/x86/regs.py
+++ b/miasm2/arch/x86/regs.py
@@ -384,6 +384,25 @@ all_regs_ids = [
     exception_flags,
 ] + fltregs32_expr
 
+all_regs_ids_no_alias = [
+    RAX, RBX, RCX, RDX, RSP, RBP, RIP, RSI, RDI,
+    R8, R9, R10, R11, R12, R13, R14, R15, R15,
+    zf, nf, pf, of, cf, af, df,
+    tf, i_f, iopl, nt, rf, vm, ac, vif, vip, i_d,
+    float_control, float_eip, float_cs, float_address, float_ds,
+    tsc1, tsc2,
+    ES, CS, SS, DS, FS, GS,
+    float_st0, float_st1, float_st2, float_st3,
+    float_st4, float_st5, float_st6, float_st7,
+    float_c0, float_c1, float_c2, float_c3,
+    cr0, cr3,
+    dr0, dr1, dr2, dr3, dr4, dr5, dr6, dr7,
+    float_stack_ptr,
+    mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7,
+
+    exception_flags,
+] + fltregs32_expr
+
 all_regs_ids_byname = dict([(x.name, x) for x in all_regs_ids])
 
 all_regs_ids_init = [ExprId("%s_init" % x.name, x.size) for x in all_regs_ids]
diff --git a/miasm2/jitter/jitcore_python.py b/miasm2/jitter/jitcore_python.py
index e054efa5..90c8bace 100644
--- a/miasm2/jitter/jitcore_python.py
+++ b/miasm2/jitter/jitcore_python.py
@@ -1,9 +1,51 @@
 import miasm2.jitter.jitcore as jitcore
 import miasm2.expression.expression as m2_expr
+import miasm2.jitter.csts as csts
 from miasm2.expression.simplifications import expr_simp
 from miasm2.ir.symbexec import symbexec
 
 
+################################################################################
+#                      Util methods for Python jitter                          #
+################################################################################
+
+def update_cpu_from_engine(cpu, exec_engine):
+    """Updates @cpu instance according to new CPU values
+    @cpu: JitCpu instance
+    @exec_engine: symbexec instance"""
+
+    for symbol in exec_engine.symbols:
+        if isinstance(symbol, m2_expr.ExprId):
+            if hasattr(cpu, symbol.name):
+                value = exec_engine.symbols.symbols_id[symbol]
+                if not isinstance(value, m2_expr.ExprInt):
+                    raise ValueError("A simplification is missing: %s" % value)
+
+                setattr(cpu, symbol.name, value.arg.arg)
+        else:
+            raise NotImplementedError("Type not handled: %s" % symbol)
+
+
+def update_engine_from_cpu(cpu, exec_engine):
+    """Updates CPU values according to @cpu instance
+    @cpu: JitCpu instance
+    @exec_engine: symbexec instance"""
+
+    for symbol in exec_engine.symbols:
+        if isinstance(symbol, m2_expr.ExprId):
+            if hasattr(cpu, symbol.name):
+                value = m2_expr.ExprInt_fromsize(symbol.size,
+                                                 getattr(cpu, symbol.name))
+                exec_engine.symbols.symbols_id[symbol] = value
+        else:
+            raise NotImplementedError("Type not handled: %s" % symbol)
+
+
+################################################################################
+#                              Python jitter Core                              #
+################################################################################
+
+
 class JitCore_Python(jitcore.JitCore):
     "JiT management, using Miasm2 Symbol Execution engine as backend"
 
@@ -15,7 +57,7 @@ class JitCore_Python(jitcore.JitCore):
         "Preload symbols according to current architecture"
 
         symbols_init =  {}
-        for i, r in enumerate(arch.regs.all_regs_ids):
+        for i, r in enumerate(arch.regs.all_regs_ids_no_alias):
             symbols_init[r] = arch.regs.all_regs_ids_init[i]
 
         self.symbexec = symbexec(arch, symbols_init,
@@ -72,6 +114,9 @@ class JitCore_Python(jitcore.JitCore):
             cur_label = label
             loop = True
 
+            # Required to detect new instructions
+            offsets_jitted = set()
+
             # Get exec engine
             exec_engine = self.symbexec
 
@@ -89,29 +134,33 @@ class JitCore_Python(jitcore.JitCore):
                 assert(loop is not False)
 
                 # Refresh CPU values according to @cpu instance
-                for symbol in exec_engine.symbols:
-                    if isinstance(symbol, m2_expr.ExprId):
-                        if hasattr(cpu, symbol.name):
-                            value = m2_expr.ExprInt_fromsize(symbol.size,
-                                                             getattr(cpu, symbol.name))
-                            exec_engine.symbols.symbols_id[symbol] = value
-                    else:
-                        raise NotImplementedError("Type not handled: %s" % symbol)
+                update_engine_from_cpu(cpu, exec_engine)
 
                 # Execute current ir bloc
-                ad = expr_simp(exec_engine.emulbloc(irb))
+                for ir, line in zip(irb.irs, irb.lines):
+
+                    # For each new instruction (in assembly)
+                    if line.offset not in offsets_jitted:
+                        offsets_jitted.add(line.offset)
+
+                        # Check for memory exception
+                        if (vmmngr.vm_get_exception() != 0):
+                            update_cpu_from_engine(cpu, exec_engine)
+                            return line.offset
+
+                    # Eval current instruction (in IR)
+                    exec_engine.eval_ir(ir)
+
+                    # Check for memory exception which do not update PC
+                    if (vmmngr.vm_get_exception() & csts.EXCEPT_DO_NOT_UPDATE_PC != 0):
+                        update_cpu_from_engine(cpu, exec_engine)
+                        return line.offset
+
+                # Get next bloc address
+                ad = expr_simp(exec_engine.eval_expr(irb.dst))
 
                 # Updates @cpu instance according to new CPU values
-                for symbol in exec_engine.symbols:
-                    if isinstance(symbol, m2_expr.ExprId):
-                        if hasattr(cpu, symbol.name):
-                            value = exec_engine.symbols.symbols_id[symbol]
-                            if not isinstance(value, m2_expr.ExprInt):
-                                raise ValueError("A simplification is missing: %s" % value)
-
-                            setattr(cpu, symbol.name, value.arg.arg)
-                    else:
-                        raise NotImplementedError("Type not handled: %s" % symbol)
+                update_cpu_from_engine(cpu, exec_engine)
 
                 # Manage resulting address
                 if isinstance(ad, m2_expr.ExprInt):
diff --git a/miasm2/jitter/vm_mngr_py.c b/miasm2/jitter/vm_mngr_py.c
index a99890fd..19686930 100644
--- a/miasm2/jitter/vm_mngr_py.c
+++ b/miasm2/jitter/vm_mngr_py.c
@@ -163,9 +163,6 @@ PyObject* vm_set_mem(VmMngr* self, PyObject* args)
 	Py_ssize_t length;
 	int ret = 0x1337;
 	uint64_t val;
-	uint64_t l;
-
-	struct memory_page_node * mpn;
 
 	if (!PyArg_ParseTuple(args, "OO", &addr, &item_str))
 		return NULL;
@@ -178,18 +175,12 @@ PyObject* vm_set_mem(VmMngr* self, PyObject* args)
 	buf_size = PyString_Size(item_str);
 	PyString_AsStringAndSize(item_str, &buf_data, &length);
 
-	/* read is multiple page wide */
+	/* write is multiple page wide */
 	while (buf_size){
-		mpn = get_memory_page_from_address(&self->vm_mngr, val);
-		if (!mpn){
-			PyErr_SetString(PyExc_RuntimeError, "cannot find address");
-			return 0;
-		}
-		l = MIN(buf_size, mpn->size - (val-mpn->ad));
-		memcpy(mpn->ad_hp + (val-mpn->ad), buf_data, l);
-		buf_data += l;
-		val += l;
-		buf_size -= l;
+		MEM_WRITE_08(&self->vm_mngr, val, (char) *(buf_data));
+		buf_data += 1;
+		val += 1;
+		buf_size -= 1;
 	}
 
 	return PyLong_FromUnsignedLongLong((uint64_t)ret);
diff --git a/test/test_all.py b/test/test_all.py
index 55511a84..d822b244 100644
--- a/test/test_all.py
+++ b/test/test_all.py
@@ -5,6 +5,18 @@ import time
 import argparse
 import tempfile
 
+# Test derivations
+def all_jit(assembly_line):
+    """Add all available jitter options to assembly_line thanks to '--jitter'
+    option.
+    @assembly_line: list(str)
+    Return a list of assembly lines: list(list(str)).
+    """
+    out = []
+    for jitter in ["tcc", "llvm", "python"]:
+        out.append(assembly_line + ["--jitter", jitter])
+    return out
+
 # Available tests
 
 all_tests = {
@@ -67,31 +79,17 @@ all_tests = {
             ["expression/solve_condition_stp.py",
                 "expression/simple_test.bin"],
         ],
-        "jitter": [
-            ["unpack_upx.py", "--jitter", "tcc", "box_upx.exe"],
-            ["unpack_upx.py", "--jitter", "llvm", "box_upx.exe"],
-            ["test_jit_x86_32.py", "--jitter", "tcc", "x86_32_sc.bin"],
-            ["test_jit_x86_32.py", "--jitter", "llvm", "x86_32_sc.bin"],
-            ["test_jit_x86_32.py", "--jitter", "python", "x86_32_sc.bin"],
-            ["test_jit_arm.py", "--jitter", "tcc","md5_arm", "A684"],
-            ["test_jit_arm.py", "--jitter", "llvm","md5_arm", "A684"],
-            ["test_jit_arm.py", "--jitter", "python","md5_arm", "A684"],
-            ["sandbox_pe_x86_32.py", "--jitter", "tcc", "box_x86_32.bin"],
-            ["sandbox_pe_x86_32.py", "--jitter", "llvm", "box_x86_32.bin"],
-            ["sandbox_pe_x86_32.py", "--jitter", "python", "box_x86_32.bin"],
-            ["sandbox_pe_x86_32.py", "--jitter", "tcc", "box_x86_32_enc.bin"],
-            ["sandbox_pe_x86_32.py", "--jitter", "llvm", "box_x86_32_enc.bin"],
-            ["sandbox_pe_x86_32.py", "--jitter", "tcc", "box_x86_32_mod.bin"],
-            ["sandbox_pe_x86_32.py", "--jitter", "llvm", "box_x86_32_mod.bin"],
-            ["sandbox_pe_x86_32.py", "--jitter",
-                "tcc", "box_x86_32_mod_self.bin"],
-            ["sandbox_pe_x86_32.py", "--jitter",
-                "llvm", "box_x86_32_mod_self.bin"],
-            ["sandbox_pe_x86_32.py", "--jitter",
-                "tcc", "box_x86_32_repmod.bin"],
-            ["sandbox_pe_x86_32.py", "--jitter",
-                "llvm", "box_x86_32_repmod.bin"],
-        ],
+        "jitter": reduce(lambda x, y: x + y,
+                         map(all_jit, [
+                    ["unpack_upx.py", "box_upx.exe"], # Take 5 mins on a Core i5
+                    ["test_jit_x86_32.py", "x86_32_sc.bin"],
+                    ["test_jit_arm.py", "md5_arm", "A684"],
+                    ["sandbox_pe_x86_32.py", "box_x86_32.bin"],
+                    ["sandbox_pe_x86_32.py", "box_x86_32_enc.bin"],
+                    ["sandbox_pe_x86_32.py", "box_x86_32_mod.bin"],
+                    ["sandbox_pe_x86_32.py", "box_x86_32_repmod.bin"],
+                    ["sandbox_pe_x86_32.py", "box_x86_32_mod_self.bin"],
+                    ])),
         "order": [
             "assembler",
             "expression",