about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorserpilliere <fabrice.desclaux@cea.fr>2015-04-05 23:48:24 +0200
committerFabrice Desclaux <fabrice.desclaux@cea.fr>2015-04-22 11:31:21 +0200
commit65feb2335c3fd525efde115932b512e7bbc720d1 (patch)
treed945f7f094beb6be3c822b67d06bb888f2e67712
parente6676c92ea2ea3e1f69c10902313094c1b83e375 (diff)
downloadmiasm-65feb2335c3fd525efde115932b512e7bbc720d1.tar.gz
miasm-65feb2335c3fd525efde115932b512e7bbc720d1.zip
Jitter: get/set mem is now wrapped in cpu
The get/set mem used during jit is wrapped by cpu. This allows cpu object to
callback (or not, depending on arch) a cache update.
-rw-r--r--miasm2/analysis/debugging.py4
-rw-r--r--miasm2/ir/translators/C.py4
-rw-r--r--miasm2/jitter/arch/JitCore_arm.c166
-rw-r--r--miasm2/jitter/arch/JitCore_arm.h3
-rw-r--r--miasm2/jitter/arch/JitCore_mips32.c163
-rw-r--r--miasm2/jitter/arch/JitCore_mips32.h2
-rw-r--r--miasm2/jitter/arch/JitCore_msp430.c200
-rw-r--r--miasm2/jitter/arch/JitCore_msp430.h3
-rw-r--r--miasm2/jitter/arch/JitCore_x86.c162
-rw-r--r--miasm2/jitter/arch/JitCore_x86.h2
-rw-r--r--miasm2/jitter/jitcore.py11
-rw-r--r--miasm2/jitter/jitcore_python.py5
-rw-r--r--miasm2/jitter/jitload.py7
-rw-r--r--miasm2/jitter/vm_mngr.c67
-rw-r--r--miasm2/jitter/vm_mngr.h20
-rw-r--r--miasm2/jitter/vm_mngr_py.c216
-rw-r--r--miasm2/jitter/vm_mngr_py.h13
-rwxr-xr-xsetup.py8
18 files changed, 723 insertions, 333 deletions
diff --git a/miasm2/analysis/debugging.py b/miasm2/analysis/debugging.py
index 57f30181..4e6982b3 100644
--- a/miasm2/analysis/debugging.py
+++ b/miasm2/analysis/debugging.py
@@ -1,5 +1,6 @@
 import cmd
 from miasm2.core.utils import hexdump
+from miasm2.core.interval import interval
 import miasm2.jitter.csts as csts
 from miasm2.jitter.jitload import ExceptionHandle
 
@@ -152,7 +153,8 @@ class Debugguer(object):
         "Step in jit"
 
         self.myjit.jit.set_options(jit_maxline=1)
-        self.myjit.jit.updt_automod_code(self.myjit.vm, self.myjit.pc, 8)
+        self.myjit.jit.addr_mod = interval([(self.myjit.pc, self.myjit.pc)])
+        self.myjit.jit.updt_automod_code(self.myjit.vm)
 
         res = self.myjit.continue_run(step=True)
         self.handle_exception(res)
diff --git a/miasm2/ir/translators/C.py b/miasm2/ir/translators/C.py
index 8ec4af7a..3de1dea4 100644
--- a/miasm2/ir/translators/C.py
+++ b/miasm2/ir/translators/C.py
@@ -45,8 +45,8 @@ class TranslatorC(Translator):
                                         (expr.cond, expr.src1, expr.src2)))
 
     def from_ExprMem(self, expr):
-        return "MEM_LOOKUP_%.2d(vm_mngr, %s)" % (expr.size,
-                                                 self.from_expr(expr.arg))
+        return "MEM_LOOKUP_%.2d(vmcpu, %s)" % (expr.size,
+                                               self.from_expr(expr.arg))
 
     def from_ExprOp(self, expr):
         if len(expr.args) == 1:
diff --git a/miasm2/jitter/arch/JitCore_arm.c b/miasm2/jitter/arch/JitCore_arm.c
index 46cff736..9d23ff44 100644
--- a/miasm2/jitter/arch/JitCore_arm.c
+++ b/miasm2/jitter/arch/JitCore_arm.c
@@ -3,6 +3,9 @@
 #include "structmember.h"
 #include <stdint.h>
 #include <inttypes.h>
+#include "../queue.h"
+#include "../vm_mngr.h"
+#include "../vm_mngr_py.h"
 #include "JitCore_arm.h"
 
 #define RAISE(errtype, msg) {PyObject* p; p = PyErr_Format( errtype, msg ); return p;}
@@ -225,6 +228,154 @@ JitCpu_set_cpu(JitCpu *self, PyObject *value, void *closure)
 	return -1;
 }
 
+
+static PyObject *
+JitCpu_get_vmmngr(JitCpu *self, void *closure)
+{
+	return self->vmcpu.pyvm;
+}
+
+static PyObject *
+JitCpu_set_vmmngr(JitCpu *self, PyObject *value, void *closure)
+{
+	self->vmcpu.pyvm = value;
+	return 0;
+}
+
+static PyObject *
+JitCpu_get_jitter(JitCpu *self, void *closure)
+{
+	return self->vmcpu.jitter;
+}
+
+static PyObject *
+JitCpu_set_jitter(JitCpu *self, PyObject *value, void *closure)
+{
+	self->vmcpu.jitter = value;
+	return 0;
+}
+
+uint8_t MEM_LOOKUP_08(vm_cpu_t* vmcpu, uint64_t addr)
+{
+	return vm_MEM_LOOKUP_08(&(((VmMngr*)vmcpu->pyvm)->vm_mngr), addr);
+}
+
+uint16_t MEM_LOOKUP_16(vm_cpu_t* vmcpu, uint64_t addr)
+{
+	return vm_MEM_LOOKUP_16(&(((VmMngr*)vmcpu->pyvm)->vm_mngr), addr);
+}
+
+uint32_t MEM_LOOKUP_32(vm_cpu_t* vmcpu, uint64_t addr)
+{
+	return vm_MEM_LOOKUP_32(&(((VmMngr*)vmcpu->pyvm)->vm_mngr), addr);
+}
+
+uint64_t MEM_LOOKUP_64(vm_cpu_t* vmcpu, uint64_t addr)
+{
+	return vm_MEM_LOOKUP_64(&(((VmMngr*)vmcpu->pyvm)->vm_mngr), addr);
+}
+
+
+
+void check_automod(vm_cpu_t* vmcpu, uint64_t addr, int size)
+{
+	PyObject *result;
+
+	if (!((((VmMngr*)vmcpu->pyvm)->vm_mngr).exception_flags & EXCEPT_CODE_AUTOMOD))
+		return;
+	result = PyObject_CallMethod((PyObject *)vmcpu->jitter, "automod_cb", "LL", addr, size);
+	Py_DECREF(result);
+
+}
+
+void MEM_WRITE_08(vm_cpu_t* vmcpu, uint64_t addr, uint8_t src)
+{
+	vm_MEM_WRITE_08(&(((VmMngr*)vmcpu->pyvm)->vm_mngr), addr, src);
+	check_automod(vmcpu, addr, 8);
+}
+
+void MEM_WRITE_16(vm_cpu_t* vmcpu, uint64_t addr, uint16_t src)
+{
+	vm_MEM_WRITE_16(&(((VmMngr*)vmcpu->pyvm)->vm_mngr), addr, src);
+	check_automod(vmcpu, addr, 16);
+}
+
+void MEM_WRITE_32(vm_cpu_t* vmcpu, uint64_t addr, uint32_t src)
+{
+	vm_MEM_WRITE_32(&(((VmMngr*)vmcpu->pyvm)->vm_mngr), addr, src);
+	check_automod(vmcpu, addr, 32);
+}
+
+void MEM_WRITE_64(vm_cpu_t* vmcpu, uint64_t addr, uint64_t src)
+{
+	vm_MEM_WRITE_64(&(((VmMngr*)vmcpu->pyvm)->vm_mngr), addr, src);
+	check_automod(vmcpu, addr, 64);
+}
+
+
+
+PyObject* vm_set_mem(JitCpu *self, PyObject* args)
+{
+       PyObject *py_addr;
+       PyObject *py_buffer;
+       Py_ssize_t py_length;
+
+       char * buffer;
+       uint64_t size;
+       uint64_t addr;
+       int ret = 0x1337;
+
+       if (!PyArg_ParseTuple(args, "OO", &py_addr, &py_buffer))
+	       return NULL;
+
+       PyGetInt(py_addr, addr);
+
+       if(!PyString_Check(py_buffer))
+	       RAISE(PyExc_TypeError,"arg must be str");
+
+       size = PyString_Size(py_buffer);
+       PyString_AsStringAndSize(py_buffer, &buffer, &py_length);
+
+       ret = vm_write_mem(&(((VmMngr*)self->vmcpu.pyvm)->vm_mngr), addr, buffer, size);
+       if (ret < 0)
+	       RAISE(PyExc_TypeError,"arg must be str");
+       check_automod(&self->vmcpu, addr, size*8);
+
+       Py_INCREF(Py_None);
+       return Py_None;
+}
+
+PyObject* vm_get_mem(JitCpu *self, PyObject* args)
+{
+       PyObject *py_addr;
+       PyObject *py_len;
+
+       uint64_t addr;
+       uint64_t size;
+       PyObject *obj_out;
+       char * buf_out;
+       int ret;
+
+       if (!PyArg_ParseTuple(args, "OO", &py_addr, &py_len))
+	       return NULL;
+
+       PyGetInt(py_addr, addr);
+       PyGetInt(py_len, size);
+
+       ret = vm_read_mem(&(((VmMngr*)self->vmcpu.pyvm)->vm_mngr), addr, &buf_out, size);
+       if (ret < 0) {
+	       free(buf_out);
+	       PyErr_SetString(PyExc_RuntimeError, "cannot find address");
+	       return NULL;
+       }
+
+       obj_out = PyString_FromStringAndSize(buf_out, size);
+       free(buf_out);
+       return obj_out;
+}
+
+
+
 static PyMemberDef JitCpu_members[] = {
     {NULL}  /* Sentinel */
 };
@@ -242,6 +393,10 @@ static PyMethodDef JitCpu_methods[] = {
 	 "X"},
 	{"set_exception", (PyCFunction)cpu_set_exception, METH_VARARGS,
 	 "X"},
+	{"set_mem", (PyCFunction)vm_set_mem, METH_VARARGS,
+	 "X"},
+	{"get_mem", (PyCFunction)vm_get_mem, METH_VARARGS,
+	 "X"},
 	{NULL}  /* Sentinel */
 };
 
@@ -432,6 +587,17 @@ static PyGetSetDef JitCpu_getseters[] = {
      (getter)JitCpu_get_cpu, (setter)JitCpu_set_cpu,
      "first name",
      NULL},
+    {"vmmngr",
+     (getter)JitCpu_get_vmmngr, (setter)JitCpu_set_vmmngr,
+     "vmmngr",
+     NULL},
+
+    {"jitter",
+     (getter)JitCpu_get_jitter, (setter)JitCpu_set_jitter,
+     "jitter",
+     NULL},
+
+
 
     {"R0" , (getter)JitCpu_get_R0 , (setter)JitCpu_set_R0 , "R0" , NULL},
     {"R1" , (getter)JitCpu_get_R1 , (setter)JitCpu_set_R1 , "R1" , NULL},
diff --git a/miasm2/jitter/arch/JitCore_arm.h b/miasm2/jitter/arch/JitCore_arm.h
index cf985ea7..32aecfc7 100644
--- a/miasm2/jitter/arch/JitCore_arm.h
+++ b/miasm2/jitter/arch/JitCore_arm.h
@@ -138,7 +138,8 @@ typedef struct {
 	uint64_t pfmem64_19;
 
 
-	uint32_t segm_base[0x10000];
+	PyObject *pyvm;
+	PyObject *jitter;
 
 }vm_cpu_t;
 
diff --git a/miasm2/jitter/arch/JitCore_mips32.c b/miasm2/jitter/arch/JitCore_mips32.c
index a1e938ba..ecc7500c 100644
--- a/miasm2/jitter/arch/JitCore_mips32.c
+++ b/miasm2/jitter/arch/JitCore_mips32.c
@@ -3,6 +3,9 @@
 #include "structmember.h"
 #include <stdint.h>
 #include <inttypes.h>
+#include "../queue.h"
+#include "../vm_mngr.h"
+#include "../vm_mngr_py.h"
 #include "JitCore_mips32.h"
 
 #define RAISE(errtype, msg) {PyObject* p; p = PyErr_Format( errtype, msg ); return p;}
@@ -266,6 +269,153 @@ JitCpu_set_cpu(JitCpu *self, PyObject *value, void *closure)
 	return -1;
 }
 
+
+
+static PyObject *
+JitCpu_get_vmmngr(JitCpu *self, void *closure)
+{
+	return self->vmcpu.pyvm;
+}
+
+static PyObject *
+JitCpu_set_vmmngr(JitCpu *self, PyObject *value, void *closure)
+{
+	self->vmcpu.pyvm = value;
+	return 0;
+}
+
+static PyObject *
+JitCpu_get_jitter(JitCpu *self, void *closure)
+{
+	return self->vmcpu.jitter;
+}
+
+static PyObject *
+JitCpu_set_jitter(JitCpu *self, PyObject *value, void *closure)
+{
+	self->vmcpu.jitter = value;
+	return 0;
+}
+
+uint8_t MEM_LOOKUP_08(vm_cpu_t* vmcpu, uint64_t addr)
+{
+	return vm_MEM_LOOKUP_08(&(((VmMngr*)vmcpu->pyvm)->vm_mngr), addr);
+}
+
+uint16_t MEM_LOOKUP_16(vm_cpu_t* vmcpu, uint64_t addr)
+{
+	return vm_MEM_LOOKUP_16(&(((VmMngr*)vmcpu->pyvm)->vm_mngr), addr);
+}
+
+uint32_t MEM_LOOKUP_32(vm_cpu_t* vmcpu, uint64_t addr)
+{
+	return vm_MEM_LOOKUP_32(&(((VmMngr*)vmcpu->pyvm)->vm_mngr), addr);
+}
+
+uint64_t MEM_LOOKUP_64(vm_cpu_t* vmcpu, uint64_t addr)
+{
+	return vm_MEM_LOOKUP_64(&(((VmMngr*)vmcpu->pyvm)->vm_mngr), addr);
+}
+
+
+
+void check_automod(vm_cpu_t* vmcpu, uint64_t addr, int size)
+{
+	PyObject *result;
+
+	if (!((((VmMngr*)vmcpu->pyvm)->vm_mngr).exception_flags & EXCEPT_CODE_AUTOMOD))
+		return;
+	result = PyObject_CallMethod((PyObject *)vmcpu->jitter, "automod_cb", "LL", addr, size);
+	Py_DECREF(result);
+
+}
+
+void MEM_WRITE_08(vm_cpu_t* vmcpu, uint64_t addr, uint8_t src)
+{
+	vm_MEM_WRITE_08(&(((VmMngr*)vmcpu->pyvm)->vm_mngr), addr, src);
+	check_automod(vmcpu, addr, 8);
+}
+
+void MEM_WRITE_16(vm_cpu_t* vmcpu, uint64_t addr, uint16_t src)
+{
+	vm_MEM_WRITE_16(&(((VmMngr*)vmcpu->pyvm)->vm_mngr), addr, src);
+	check_automod(vmcpu, addr, 16);
+}
+
+void MEM_WRITE_32(vm_cpu_t* vmcpu, uint64_t addr, uint32_t src)
+{
+	vm_MEM_WRITE_32(&(((VmMngr*)vmcpu->pyvm)->vm_mngr), addr, src);
+	check_automod(vmcpu, addr, 32);
+}
+
+void MEM_WRITE_64(vm_cpu_t* vmcpu, uint64_t addr, uint64_t src)
+{
+	vm_MEM_WRITE_64(&(((VmMngr*)vmcpu->pyvm)->vm_mngr), addr, src);
+	check_automod(vmcpu, addr, 64);
+}
+
+
+
+PyObject* vm_set_mem(JitCpu *self, PyObject* args)
+{
+       PyObject *py_addr;
+       PyObject *py_buffer;
+       Py_ssize_t py_length;
+
+       char * buffer;
+       uint64_t size;
+       uint64_t addr;
+       int ret = 0x1337;
+
+       if (!PyArg_ParseTuple(args, "OO", &py_addr, &py_buffer))
+	       return NULL;
+
+       PyGetInt(py_addr, addr);
+
+       if(!PyString_Check(py_buffer))
+	       RAISE(PyExc_TypeError,"arg must be str");
+
+       size = PyString_Size(py_buffer);
+       PyString_AsStringAndSize(py_buffer, &buffer, &py_length);
+
+       ret = vm_write_mem(&(((VmMngr*)self->vmcpu.pyvm)->vm_mngr), addr, buffer, size);
+       if (ret < 0)
+	       RAISE(PyExc_TypeError,"arg must be str");
+       check_automod(&self->vmcpu, addr, size*8);
+
+       Py_INCREF(Py_None);
+       return Py_None;
+}
+
+PyObject* vm_get_mem(JitCpu *self, PyObject* args)
+{
+       PyObject *py_addr;
+       PyObject *py_len;
+
+       uint64_t addr;
+       uint64_t size;
+       PyObject *obj_out;
+       char * buf_out;
+       int ret;
+
+       if (!PyArg_ParseTuple(args, "OO", &py_addr, &py_len))
+	       return NULL;
+
+       PyGetInt(py_addr, addr);
+       PyGetInt(py_len, size);
+
+       ret = vm_read_mem(&(((VmMngr*)self->vmcpu.pyvm)->vm_mngr), addr, &buf_out, size);
+       if (ret < 0) {
+	       free(buf_out);
+	       PyErr_SetString(PyExc_RuntimeError, "cannot find address");
+	       return NULL;
+       }
+
+       obj_out = PyString_FromStringAndSize(buf_out, size);
+       free(buf_out);
+       return obj_out;
+}
+
 static PyMemberDef JitCpu_members[] = {
     {NULL}  /* Sentinel */
 };
@@ -283,6 +433,10 @@ static PyMethodDef JitCpu_methods[] = {
 	 "X"},
 	{"set_exception", (PyCFunction)cpu_set_exception, METH_VARARGS,
 	 "X"},
+	{"set_mem", (PyCFunction)vm_set_mem, METH_VARARGS,
+	 "X"},
+	{"get_mem", (PyCFunction)vm_get_mem, METH_VARARGS,
+	 "X"},
 	{NULL}  /* Sentinel */
 };
 
@@ -518,6 +672,15 @@ static PyGetSetDef JitCpu_getseters[] = {
      (getter)JitCpu_get_cpu, (setter)JitCpu_set_cpu,
      "first name",
      NULL},
+    {"vmmngr",
+     (getter)JitCpu_get_vmmngr, (setter)JitCpu_set_vmmngr,
+     "vmmngr",
+     NULL},
+
+    {"jitter",
+     (getter)JitCpu_get_jitter, (setter)JitCpu_set_jitter,
+     "jitter",
+     NULL},
 
     {"ZERO" , (getter)JitCpu_get_ZERO , (setter)JitCpu_set_ZERO , "ZERO" , NULL},
     {"AT" , (getter)JitCpu_get_AT , (setter)JitCpu_set_AT , "AT" , NULL},
diff --git a/miasm2/jitter/arch/JitCore_mips32.h b/miasm2/jitter/arch/JitCore_mips32.h
index ac128250..7cc9740d 100644
--- a/miasm2/jitter/arch/JitCore_mips32.h
+++ b/miasm2/jitter/arch/JitCore_mips32.h
@@ -235,6 +235,8 @@ typedef struct {
 	double F30_new;
 	double F31_new;
 
+	PyObject *pyvm;
+	PyObject *jitter;
 
 }vm_cpu_t;
 
diff --git a/miasm2/jitter/arch/JitCore_msp430.c b/miasm2/jitter/arch/JitCore_msp430.c
index b52ad5d0..94a1b4e2 100644
--- a/miasm2/jitter/arch/JitCore_msp430.c
+++ b/miasm2/jitter/arch/JitCore_msp430.c
@@ -3,44 +3,13 @@
 #include "structmember.h"
 #include <stdint.h>
 #include <inttypes.h>
+#include "../queue.h"
+#include "../vm_mngr.h"
+#include "../vm_mngr_py.h"
 #include "JitCore_msp430.h"
 
 #define RAISE(errtype, msg) {PyObject* p; p = PyErr_Format( errtype, msg ); return p;}
 
-/*
-void check_align(uint64_t addr)
-{
-	if (addr & 1) {
-		printf("unaligned mem lookup %X\n", addr);
-		exit(0);
-	}
-}
-
-void VM_MEM_WRITE_08(vm_mngr_t* vm_mngr, uint64_t addr, unsigned char src)
-{
-	//check_align(addr);
-	MEM_WRITE_08(vm_mngr, addr, src);
-}
-
-void VM_MEM_WRITE_16(vm_mngr_t* vm_mngr, uint64_t addr, unsigned short src)
-{
-	check_align(addr);
-	MEM_WRITE_16(vm_mngr, addr, src);
-}
-
-void VM_MEM_WRITE_32(vm_mngr_t* vm_mngr, uint64_t addr, unsigned int src)
-{
-	check_align(addr);
-	MEM_WRITE_32(vm_mngr, addr, src);
-}
-
-void VM_MEM_WRITE_64(vm_mngr_t* vm_mngr, uint64_t addr, uint64_t src)
-{
-	check_align(addr);
-	MEM_WRITE_64(vm_mngr, addr, src);
-}
-*/
-
 typedef struct _reg_dict{
     char* name;
     unsigned long offset;
@@ -518,6 +487,156 @@ JitCpu_set_cpu(JitCpu *self, PyObject *value, void *closure)
 	return -1;
 }
 
+
+
+static PyObject *
+JitCpu_get_vmmngr(JitCpu *self, void *closure)
+{
+	return self->vmcpu.pyvm;
+}
+
+static PyObject *
+JitCpu_set_vmmngr(JitCpu *self, PyObject *value, void *closure)
+{
+	self->vmcpu.pyvm = value;
+	return 0;
+}
+
+static PyObject *
+JitCpu_get_jitter(JitCpu *self, void *closure)
+{
+	return self->vmcpu.jitter;
+}
+
+static PyObject *
+JitCpu_set_jitter(JitCpu *self, PyObject *value, void *closure)
+{
+	self->vmcpu.jitter = value;
+	return 0;
+}
+
+uint8_t MEM_LOOKUP_08(vm_cpu_t* vmcpu, uint64_t addr)
+{
+	return vm_MEM_LOOKUP_08(&(((VmMngr*)vmcpu->pyvm)->vm_mngr), addr);
+}
+
+uint16_t MEM_LOOKUP_16(vm_cpu_t* vmcpu, uint64_t addr)
+{
+	return vm_MEM_LOOKUP_16(&(((VmMngr*)vmcpu->pyvm)->vm_mngr), addr);
+}
+
+uint32_t MEM_LOOKUP_32(vm_cpu_t* vmcpu, uint64_t addr)
+{
+	return vm_MEM_LOOKUP_32(&(((VmMngr*)vmcpu->pyvm)->vm_mngr), addr);
+}
+
+uint64_t MEM_LOOKUP_64(vm_cpu_t* vmcpu, uint64_t addr)
+{
+	return vm_MEM_LOOKUP_64(&(((VmMngr*)vmcpu->pyvm)->vm_mngr), addr);
+}
+
+
+
+void check_automod(vm_cpu_t* vmcpu, uint64_t addr, int size)
+{
+	PyObject *result;
+
+	if (!((((VmMngr*)vmcpu->pyvm)->vm_mngr).exception_flags & EXCEPT_CODE_AUTOMOD))
+		return;
+	result = PyObject_CallMethod((PyObject *)vmcpu->jitter, "automod_cb", "LL", addr, size);
+	Py_DECREF(result);
+
+}
+
+void MEM_WRITE_08(vm_cpu_t* vmcpu, uint64_t addr, uint8_t src)
+{
+	vm_MEM_WRITE_08(&(((VmMngr*)vmcpu->pyvm)->vm_mngr), addr, src);
+	check_automod(vmcpu, addr, 8);
+}
+
+void MEM_WRITE_16(vm_cpu_t* vmcpu, uint64_t addr, uint16_t src)
+{
+	vm_MEM_WRITE_16(&(((VmMngr*)vmcpu->pyvm)->vm_mngr), addr, src);
+	check_automod(vmcpu, addr, 16);
+}
+
+void MEM_WRITE_32(vm_cpu_t* vmcpu, uint64_t addr, uint32_t src)
+{
+	vm_MEM_WRITE_32(&(((VmMngr*)vmcpu->pyvm)->vm_mngr), addr, src);
+	check_automod(vmcpu, addr, 32);
+}
+
+void MEM_WRITE_64(vm_cpu_t* vmcpu, uint64_t addr, uint64_t src)
+{
+	vm_MEM_WRITE_64(&(((VmMngr*)vmcpu->pyvm)->vm_mngr), addr, src);
+	check_automod(vmcpu, addr, 64);
+}
+
+
+
+
+PyObject* vm_set_mem(JitCpu *self, PyObject* args)
+{
+       PyObject *py_addr;
+       PyObject *py_buffer;
+       Py_ssize_t py_length;
+
+       char * buffer;
+       uint64_t size;
+       uint64_t addr;
+       int ret = 0x1337;
+
+       if (!PyArg_ParseTuple(args, "OO", &py_addr, &py_buffer))
+	       return NULL;
+
+       PyGetInt(py_addr, addr);
+
+       if(!PyString_Check(py_buffer))
+	       RAISE(PyExc_TypeError,"arg must be str");
+
+       size = PyString_Size(py_buffer);
+       PyString_AsStringAndSize(py_buffer, &buffer, &py_length);
+
+       ret = vm_write_mem(&(((VmMngr*)self->vmcpu.pyvm)->vm_mngr), addr, buffer, size);
+       if (ret < 0)
+	       RAISE(PyExc_TypeError,"arg must be str");
+       check_automod(&self->vmcpu, addr, size*8);
+
+       Py_INCREF(Py_None);
+       return Py_None;
+}
+
+PyObject* vm_get_mem(JitCpu *self, PyObject* args)
+{
+       PyObject *py_addr;
+       PyObject *py_len;
+
+       uint64_t addr;
+       uint64_t size;
+       PyObject *obj_out;
+       char * buf_out;
+       int ret;
+
+       if (!PyArg_ParseTuple(args, "OO", &py_addr, &py_len))
+	       return NULL;
+
+       PyGetInt(py_addr, addr);
+       PyGetInt(py_len, size);
+
+       ret = vm_read_mem(&(((VmMngr*)self->vmcpu.pyvm)->vm_mngr), addr, &buf_out, size);
+       if (ret < 0) {
+	       free(buf_out);
+	       PyErr_SetString(PyExc_RuntimeError, "cannot find address");
+	       return NULL;
+       }
+
+       obj_out = PyString_FromStringAndSize(buf_out, size);
+       free(buf_out);
+       return obj_out;
+}
+
+
+
 static PyMemberDef JitCpu_members[] = {
     {NULL}  /* Sentinel */
 };
@@ -535,6 +654,10 @@ static PyMethodDef JitCpu_methods[] = {
 	 "X"},
 	{"set_exception", (PyCFunction)cpu_set_exception, METH_VARARGS,
 	 "X"},
+	{"set_mem", (PyCFunction)vm_set_mem, METH_VARARGS,
+	 "X"},
+	{"get_mem", (PyCFunction)vm_get_mem, METH_VARARGS,
+	 "X"},
 	{NULL}  /* Sentinel */
 };
 
@@ -578,6 +701,15 @@ static PyGetSetDef JitCpu_getseters[] = {
      (getter)JitCpu_get_cpu, (setter)JitCpu_set_cpu,
      "first name",
      NULL},
+    {"vmmngr",
+     (getter)JitCpu_get_vmmngr, (setter)JitCpu_set_vmmngr,
+     "vmmngr",
+     NULL},
+
+    {"jitter",
+     (getter)JitCpu_get_jitter, (setter)JitCpu_set_jitter,
+     "jitter",
+     NULL},
 
 
     {"PC" , (getter)JitCpu_get_PC      , (setter)JitCpu_set_PC     , "PC" , NULL},
diff --git a/miasm2/jitter/arch/JitCore_msp430.h b/miasm2/jitter/arch/JitCore_msp430.h
index e1c001b7..f830028f 100644
--- a/miasm2/jitter/arch/JitCore_msp430.h
+++ b/miasm2/jitter/arch/JitCore_msp430.h
@@ -152,7 +152,8 @@ typedef struct {
 	uint64_t pfmem64_19;
 
 
-	uint32_t segm_base[0x10000];
+	PyObject *pyvm;
+	PyObject *jitter;
 
 }vm_cpu_t;
 
diff --git a/miasm2/jitter/arch/JitCore_x86.c b/miasm2/jitter/arch/JitCore_x86.c
index 5c7b9c02..c77d45f2 100644
--- a/miasm2/jitter/arch/JitCore_x86.c
+++ b/miasm2/jitter/arch/JitCore_x86.c
@@ -5,6 +5,7 @@
 #include <inttypes.h>
 #include "../queue.h"
 #include "../vm_mngr.h"
+#include "../vm_mngr_py.h"
 #include "JitCore_x86.h"
 
 #define RAISE(errtype, msg) {PyObject* p; p = PyErr_Format( errtype, msg ); return p;}
@@ -357,6 +358,153 @@ JitCpu_set_cpu(JitCpu *self, PyObject *value, void *closure)
 	return -1;
 }
 
+
+
+static PyObject *
+JitCpu_get_vmmngr(JitCpu *self, void *closure)
+{
+	return self->vmcpu.pyvm;
+}
+
+static PyObject *
+JitCpu_set_vmmngr(JitCpu *self, PyObject *value, void *closure)
+{
+	self->vmcpu.pyvm = value;
+	return 0;
+}
+
+static PyObject *
+JitCpu_get_jitter(JitCpu *self, void *closure)
+{
+	return self->vmcpu.jitter;
+}
+
+static PyObject *
+JitCpu_set_jitter(JitCpu *self, PyObject *value, void *closure)
+{
+	self->vmcpu.jitter = value;
+	return 0;
+}
+
+uint8_t MEM_LOOKUP_08(vm_cpu_t* vmcpu, uint64_t addr)
+{
+	return vm_MEM_LOOKUP_08(&(((VmMngr*)vmcpu->pyvm)->vm_mngr), addr);
+}
+
+uint16_t MEM_LOOKUP_16(vm_cpu_t* vmcpu, uint64_t addr)
+{
+	return vm_MEM_LOOKUP_16(&(((VmMngr*)vmcpu->pyvm)->vm_mngr), addr);
+}
+
+uint32_t MEM_LOOKUP_32(vm_cpu_t* vmcpu, uint64_t addr)
+{
+	return vm_MEM_LOOKUP_32(&(((VmMngr*)vmcpu->pyvm)->vm_mngr), addr);
+}
+
+uint64_t MEM_LOOKUP_64(vm_cpu_t* vmcpu, uint64_t addr)
+{
+	return vm_MEM_LOOKUP_64(&(((VmMngr*)vmcpu->pyvm)->vm_mngr), addr);
+}
+
+
+
+void check_automod(vm_cpu_t* vmcpu, uint64_t addr, int size)
+{
+	PyObject *result;
+
+	if (!((((VmMngr*)vmcpu->pyvm)->vm_mngr).exception_flags & EXCEPT_CODE_AUTOMOD))
+		return;
+	result = PyObject_CallMethod((PyObject *)vmcpu->jitter, "automod_cb", "LL", addr, size);
+	Py_DECREF(result);
+
+}
+
+void MEM_WRITE_08(vm_cpu_t* vmcpu, uint64_t addr, uint8_t src)
+{
+	vm_MEM_WRITE_08(&(((VmMngr*)vmcpu->pyvm)->vm_mngr), addr, src);
+	check_automod(vmcpu, addr, 8);
+}
+
+void MEM_WRITE_16(vm_cpu_t* vmcpu, uint64_t addr, uint16_t src)
+{
+	vm_MEM_WRITE_16(&(((VmMngr*)vmcpu->pyvm)->vm_mngr), addr, src);
+	check_automod(vmcpu, addr, 16);
+}
+
+void MEM_WRITE_32(vm_cpu_t* vmcpu, uint64_t addr, uint32_t src)
+{
+	vm_MEM_WRITE_32(&(((VmMngr*)vmcpu->pyvm)->vm_mngr), addr, src);
+	check_automod(vmcpu, addr, 32);
+}
+
+void MEM_WRITE_64(vm_cpu_t* vmcpu, uint64_t addr, uint64_t src)
+{
+	vm_MEM_WRITE_64(&(((VmMngr*)vmcpu->pyvm)->vm_mngr), addr, src);
+	check_automod(vmcpu, addr, 64);
+}
+
+
+
+PyObject* vm_set_mem(JitCpu *self, PyObject* args)
+{
+       PyObject *py_addr;
+       PyObject *py_buffer;
+       Py_ssize_t py_length;
+
+       char * buffer;
+       uint64_t size;
+       uint64_t addr;
+       int ret = 0x1337;
+
+       if (!PyArg_ParseTuple(args, "OO", &py_addr, &py_buffer))
+	       return NULL;
+
+       PyGetInt(py_addr, addr);
+
+       if(!PyString_Check(py_buffer))
+	       RAISE(PyExc_TypeError,"arg must be str");
+
+       size = PyString_Size(py_buffer);
+       PyString_AsStringAndSize(py_buffer, &buffer, &py_length);
+
+       ret = vm_write_mem(&(((VmMngr*)self->vmcpu.pyvm)->vm_mngr), addr, buffer, size);
+       if (ret < 0)
+	       RAISE(PyExc_TypeError,"arg must be str");
+       check_automod(&self->vmcpu, addr, size*8);
+
+       Py_INCREF(Py_None);
+       return Py_None;
+}
+
+PyObject* vm_get_mem(JitCpu *self, PyObject* args)
+{
+       PyObject *py_addr;
+       PyObject *py_len;
+
+       uint64_t addr;
+       uint64_t size;
+       PyObject *obj_out;
+       char * buf_out;
+       int ret;
+
+       if (!PyArg_ParseTuple(args, "OO", &py_addr, &py_len))
+	       return NULL;
+
+       PyGetInt(py_addr, addr);
+       PyGetInt(py_len, size);
+
+       ret = vm_read_mem(&(((VmMngr*)self->vmcpu.pyvm)->vm_mngr), addr, &buf_out, size);
+       if (ret < 0) {
+	       free(buf_out);
+	       PyErr_SetString(PyExc_RuntimeError, "cannot find address");
+	       return NULL;
+       }
+
+       obj_out = PyString_FromStringAndSize(buf_out, size);
+       free(buf_out);
+       return obj_out;
+}
+
 static PyMemberDef JitCpu_members[] = {
     {NULL}  /* Sentinel */
 };
@@ -378,6 +526,10 @@ static PyMethodDef JitCpu_methods[] = {
 	 "X"},
 	{"set_exception", (PyCFunction)cpu_set_exception, METH_VARARGS,
 	 "X"},
+	{"set_mem", (PyCFunction)vm_set_mem, METH_VARARGS,
+	 "X"},
+	{"get_mem", (PyCFunction)vm_get_mem, METH_VARARGS,
+	 "X"},
 	{NULL}  /* Sentinel */
 };
 
@@ -701,6 +853,16 @@ static PyGetSetDef JitCpu_getseters[] = {
      (getter)JitCpu_get_cpu, (setter)JitCpu_set_cpu,
      "first name",
      NULL},
+    {"vmmngr",
+     (getter)JitCpu_get_vmmngr, (setter)JitCpu_set_vmmngr,
+     "vmmngr",
+     NULL},
+
+    {"jitter",
+     (getter)JitCpu_get_jitter, (setter)JitCpu_set_jitter,
+     "jitter",
+     NULL},
+
 
     {"RAX", (getter)JitCpu_get_RAX, (setter)JitCpu_set_RAX, "RAX", NULL},
     {"RBX", (getter)JitCpu_get_RBX, (setter)JitCpu_set_RBX, "RBX", NULL},
diff --git a/miasm2/jitter/arch/JitCore_x86.h b/miasm2/jitter/arch/JitCore_x86.h
index 844c13c0..6ac4f734 100644
--- a/miasm2/jitter/arch/JitCore_x86.h
+++ b/miasm2/jitter/arch/JitCore_x86.h
@@ -266,6 +266,8 @@ typedef struct {
 	uint64_t MM7_new;
 
 	uint32_t segm_base[0x10000];
+	PyObject *pyvm;
+	PyObject *jitter;
 
 }vm_cpu_t;
 
diff --git a/miasm2/jitter/jitcore.py b/miasm2/jitter/jitcore.py
index 16f201c9..cf3bf7ae 100644
--- a/miasm2/jitter/jitcore.py
+++ b/miasm2/jitter/jitcore.py
@@ -51,6 +51,7 @@ class JitCore(object):
         self.blocs_mem_interval = interval()
         self.disasm_cb = None
         self.split_dis = set()
+        self.addr_mod = interval()
 
         self.options = {"jit_maxline": 50  # Maximum number of line jitted
                         }
@@ -249,13 +250,17 @@ class JitCore(object):
 
         return modified_blocs
 
-    def updt_automod_code(self, vm, addr, size):
+    def updt_automod_code(self, vm):
         """Remove code jitted in range [addr, addr + size]
         @vm: VmMngr instance
         @addr: Address of modified code in sandbox
         @size: Modification range size (in bits)
         """
-
-        self.del_bloc_in_range(addr, addr + size / 8)
+        for addr_start, addr_stop in self.addr_mod:
+            self.del_bloc_in_range(addr_start, addr_stop+1)
         self.__updt_jitcode_mem_range(vm)
+        self.addr_mod = interval()
 
+    def automod_cb(self, addr=0, size=0):
+        self.addr_mod+= interval([(addr, addr+size/8 - 1)])
+        return None
diff --git a/miasm2/jitter/jitcore_python.py b/miasm2/jitter/jitcore_python.py
index 0df9f615..b768b338 100644
--- a/miasm2/jitter/jitcore_python.py
+++ b/miasm2/jitter/jitcore_python.py
@@ -71,7 +71,7 @@ class JitCore_Python(jitcore.JitCore):
 
         addr = expr_mem.arg.arg.arg
         size = expr_mem.size / 8
-        value = self.vmmngr.get_mem(addr, size)
+        value = self.cpu.get_mem(addr, size)
 
         return m2_expr.ExprInt_fromsize(expr_mem.size,
                                         int(value[::-1].encode("hex"), 16))
@@ -97,7 +97,7 @@ class JitCore_Python(jitcore.JitCore):
         content = content.decode("hex")[::-1]
 
         # Write in VmMngr context
-        self.vmmngr.set_mem(addr, content)
+        self.cpu.set_mem(addr, content)
 
     def jitirblocs(self, label, irblocs):
         """Create a python function corresponding to an irblocs' group.
@@ -195,6 +195,7 @@ class JitCore_Python(jitcore.JitCore):
 
         # Update memory state
         self.vmmngr = vmmngr
+        self.cpu = cpu
 
         # Execute the function
         return fc_ptr(cpu, vmmngr)
diff --git a/miasm2/jitter/jitload.py b/miasm2/jitter/jitload.py
index 97fd3c80..6faa3a9f 100644
--- a/miasm2/jitter/jitload.py
+++ b/miasm2/jitter/jitload.py
@@ -217,9 +217,12 @@ class jitter:
         self.vm.set_addr2obj(self.jit.addr2obj)
 
         self.jit.load()
+        self.cpu.vmmngr = self.vm
+        self.cpu.jitter = self.jit
         self.stack_size = 0x10000
         self.stack_base = 0x1230000
 
+
         # Init callback handler
         self.breakpoints_handler = CallbackHandler()
         self.exceptions_handler = CallbackHandlerBitflag()
@@ -231,10 +234,8 @@ class jitter:
 
         def exception_automod(jitter):
             "Tell the JiT backend to update blocs modified"
-            addr = self.vm.get_last_write_ad()
-            size = self.vm.get_last_write_size()
 
-            self.jit.updt_automod_code(self.vm, addr, size)
+            self.jit.updt_automod_code(jitter.vm)
             self.vm.set_exception(0)
 
             return True
diff --git a/miasm2/jitter/vm_mngr.c b/miasm2/jitter/vm_mngr.c
index a9bdd8ca..ec7fa01c 100644
--- a/miasm2/jitter/vm_mngr.c
+++ b/miasm2/jitter/vm_mngr.c
@@ -395,13 +395,7 @@ void dump_code_bloc(vm_mngr_t* vm_mngr)
 void check_write_code_bloc(vm_mngr_t* vm_mngr, uint64_t my_size, uint64_t addr)
 {
 	struct code_bloc_node * cbp;
-	vm_mngr->last_write_ad = addr;
-	vm_mngr->last_write_size = my_size;
 
-
-
-	//if(vmmngr.my_tick> my_tick)
-	//	printf("M_WRITE %2d %.8X %.8X\n", my_size, addr, src);
 	if (!(addr + my_size/8 <= vm_mngr->code_bloc_pool_ad_min ||
 	      addr >=vm_mngr->code_bloc_pool_ad_max)){
 		LIST_FOREACH(cbp, &vm_mngr->code_bloc_pool, next){
@@ -444,93 +438,48 @@ PyObject* addr2BlocObj(vm_mngr_t* vm_mngr, uint64_t addr)
 	return b;
 }
 
-/*
-PyObject* add_code_resolver(vm_mngr_t* vm_mngr, uint64_t addr)
-{
-	pyaddr = PyLong_FromUnsignedLongLong(addr);
-
-	func_resolver* f = malloc(sizeof(func_resolver));
-	f->func = addr2blocobj;
-	fsdfsd
-	return f;
-}
-*/
-/*
-void MEM_WRITE(vm_mngr_t* vm_mngr, unsigned int my_size, uint64_t addr, unsigned int src)
-{
-	struct code_bloc_node * cbp;
-
-	vm_mngr->last_write_ad = addr;
-	vm_mngr->last_write_size = my_size;
-
-	//if(vmmngr.my_tick> my_tick)
-	//	printf("M_WRITE %2d %.8X %.8X\n", my_size, addr, src);
-	if (!(addr + my_size/8 <= vm_mngr->code_bloc_pool_ad_min ||
-	      addr >= vm_mngr->code_bloc_pool_ad_max)){
-		LIST_FOREACH(cbp, &vm_mngr->code_bloc_pool, next){
-			if ((cbp->ad_start <= addr + my_size/8) &&
-			    (addr < cbp->ad_stop)){
-#ifdef DEBUG_MIASM_AUTOMOD_CODE
-				fprintf(stderr, "self modifying code %"PRIX64" %.8X\n",
-				       addr, my_size);
-#endif
-				vm_mngr->exception_flags |= EXCEPT_CODE_AUTOMOD;
-				break;
-			}
-		}
-	}
 
-	memory_page_write(vm_mngr, my_size, addr, src);
-}
-*/
-void MEM_WRITE_08(vm_mngr_t* vm_mngr, uint64_t addr, unsigned char src)
+void vm_MEM_WRITE_08(vm_mngr_t* vm_mngr, uint64_t addr, unsigned char src)
 {
 	check_write_code_bloc(vm_mngr, 8, addr);
 	memory_page_write(vm_mngr, 8, addr, src);
 }
 
-void MEM_WRITE_16(vm_mngr_t* vm_mngr, uint64_t addr, unsigned short src)
+void vm_MEM_WRITE_16(vm_mngr_t* vm_mngr, uint64_t addr, unsigned short src)
 {
 	check_write_code_bloc(vm_mngr, 16, addr);
 	memory_page_write(vm_mngr, 16, addr, src);
 }
-void MEM_WRITE_32(vm_mngr_t* vm_mngr, uint64_t addr, unsigned int src)
+void vm_MEM_WRITE_32(vm_mngr_t* vm_mngr, uint64_t addr, unsigned int src)
 {
 	check_write_code_bloc(vm_mngr, 32, addr);
 	memory_page_write(vm_mngr, 32, addr, src);
 }
-void MEM_WRITE_64(vm_mngr_t* vm_mngr, uint64_t addr, uint64_t src)
+void vm_MEM_WRITE_64(vm_mngr_t* vm_mngr, uint64_t addr, uint64_t src)
 {
 	check_write_code_bloc(vm_mngr, 64, addr);
 	memory_page_write(vm_mngr, 64, addr, src);
 }
 
-unsigned int MEM_LOOKUP(vm_mngr_t* vm_mngr, unsigned int my_size, uint64_t addr)
-{
-    unsigned int ret;
-    ret = memory_page_read(vm_mngr, my_size, addr);
-    return ret;
-}
-
-unsigned char MEM_LOOKUP_08(vm_mngr_t* vm_mngr, uint64_t addr)
+unsigned char vm_MEM_LOOKUP_08(vm_mngr_t* vm_mngr, uint64_t addr)
 {
     unsigned char ret;
     ret = memory_page_read(vm_mngr, 8, addr);
     return ret;
 }
-unsigned short MEM_LOOKUP_16(vm_mngr_t* vm_mngr, uint64_t addr)
+unsigned short vm_MEM_LOOKUP_16(vm_mngr_t* vm_mngr, uint64_t addr)
 {
     unsigned short ret;
     ret = memory_page_read(vm_mngr, 16, addr);
     return ret;
 }
-unsigned int MEM_LOOKUP_32(vm_mngr_t* vm_mngr, uint64_t addr)
+unsigned int vm_MEM_LOOKUP_32(vm_mngr_t* vm_mngr, uint64_t addr)
 {
     unsigned int ret;
     ret = memory_page_read(vm_mngr, 32, addr);
     return ret;
 }
-uint64_t MEM_LOOKUP_64(vm_mngr_t* vm_mngr, uint64_t addr)
+uint64_t vm_MEM_LOOKUP_64(vm_mngr_t* vm_mngr, uint64_t addr)
 {
     uint64_t ret;
     ret = memory_page_read(vm_mngr, 64, addr);
diff --git a/miasm2/jitter/vm_mngr.h b/miasm2/jitter/vm_mngr.h
index 9589f601..72c64319 100644
--- a/miasm2/jitter/vm_mngr.h
+++ b/miasm2/jitter/vm_mngr.h
@@ -79,9 +79,6 @@ typedef struct {
 
 	uint64_t exception_flags;
 	uint64_t exception_flags_new;
-	uint64_t last_write_ad;
-	uint64_t last_write_size ;
-	PyObject *cb_automod;
 	PyObject *addr2obj;
 }vm_mngr_t;
 
@@ -150,20 +147,19 @@ struct memory_breakpoint_info {
 
 int is_mem_mapped(vm_mngr_t* vm_mngr, uint64_t ad);
 uint64_t get_mem_base_addr(vm_mngr_t* vm_mngr, uint64_t addr, uint64_t *addr_base);
-void MEM_WRITE(vm_mngr_t* vm_mngr, unsigned int my_size, uint64_t addr, unsigned int src);
 unsigned int MEM_LOOKUP(vm_mngr_t* vm_mngr, unsigned int my_size, uint64_t addr);
 
 
-void MEM_WRITE_08(vm_mngr_t* vm_mngr, uint64_t addr, unsigned char src);
-void MEM_WRITE_16(vm_mngr_t* vm_mngr, uint64_t addr, unsigned short src);
-void MEM_WRITE_32(vm_mngr_t* vm_mngr, uint64_t addr, unsigned int src);
-void MEM_WRITE_64(vm_mngr_t* vm_mngr, uint64_t addr, uint64_t src);
+void vm_MEM_WRITE_08(vm_mngr_t* vm_mngr, uint64_t addr, unsigned char src);
+void vm_MEM_WRITE_16(vm_mngr_t* vm_mngr, uint64_t addr, unsigned short src);
+void vm_MEM_WRITE_32(vm_mngr_t* vm_mngr, uint64_t addr, unsigned int src);
+void vm_MEM_WRITE_64(vm_mngr_t* vm_mngr, uint64_t addr, uint64_t src);
 
 
-unsigned char MEM_LOOKUP_08(vm_mngr_t* vm_mngr, uint64_t addr);
-unsigned short MEM_LOOKUP_16(vm_mngr_t* vm_mngr, uint64_t addr);
-unsigned int MEM_LOOKUP_32(vm_mngr_t* vm_mngr, uint64_t addr);
-uint64_t MEM_LOOKUP_64(vm_mngr_t* vm_mngr, uint64_t addr);
+unsigned char vm_MEM_LOOKUP_08(vm_mngr_t* vm_mngr, uint64_t addr);
+unsigned short vm_MEM_LOOKUP_16(vm_mngr_t* vm_mngr, uint64_t addr);
+unsigned int vm_MEM_LOOKUP_32(vm_mngr_t* vm_mngr, uint64_t addr);
+uint64_t vm_MEM_LOOKUP_64(vm_mngr_t* vm_mngr, uint64_t addr);
 
 
 void MEM_WRITE_08_PASSTHROUGH(uint64_t addr, unsigned char src);
diff --git a/miasm2/jitter/vm_mngr_py.c b/miasm2/jitter/vm_mngr_py.c
index fdc4837d..c5d56719 100644
--- a/miasm2/jitter/vm_mngr_py.c
+++ b/miasm2/jitter/vm_mngr_py.c
@@ -22,6 +22,7 @@
 #include <signal.h>
 #include "queue.h"
 #include "vm_mngr.h"
+#include "vm_mngr_py.h"
 
 #define MIN(a,b)  (((a)<(b))?(a):(b))
 #define MAX(a,b)  (((a)>(b))?(a):(b))
@@ -33,12 +34,6 @@ extern struct code_bloc_list_head code_bloc_pool;
 
 
 
-typedef struct {
-	PyObject_HEAD
-	PyObject *vmmngr;
-	vm_mngr_t vm_mngr;
-} VmMngr;
-
 /* XXX POC signals */
 VmMngr* global_vmmngr;
 
@@ -305,16 +300,6 @@ PyObject* vm_remove_memory_breakpoint(VmMngr* self, PyObject* args)
 }
 
 
-PyObject* vm_get_last_write_ad(VmMngr* self, PyObject* args)
-{
-	return PyInt_FromLong((uint64_t)self->vm_mngr.last_write_ad);
-}
-
-PyObject* vm_get_last_write_size(VmMngr* self, PyObject* args)
-{
-	return PyLong_FromUnsignedLongLong((uint64_t)self->vm_mngr.last_write_size);
-}
-
 PyObject* vm_set_exception(VmMngr* self, PyObject* args)
 {
 	PyObject *item1;
@@ -441,60 +426,6 @@ PyObject* vm_reset_code_bloc_pool(VmMngr* self, PyObject* args)
 }
 
 
-
-
-
-
-PyObject* vm_call_pyfunc_from_globals(VmMngr* self, PyObject* args)
-{
-	char* funcname;
-	PyObject  *mod,  *func, *rslt, *globals, *func_globals;
-
-
-	if (!PyArg_ParseTuple(args, "s", &funcname))
-		return NULL;
-
-
-	fprintf(stderr, "getting pyfunc %s\n", funcname);
-	mod = PyEval_GetBuiltins();
-
-	if (!mod) {
-		fprintf(stderr, "cannot find module\n");
-		exit(0);
-	}
-
-	func_globals = PyDict_GetItemString(mod, "globals");
-	if (!func_globals) {
-		fprintf(stderr, "cannot find function globals\n");
-		exit(0);
-	}
-
-	if (!PyCallable_Check (func_globals)) {
-		fprintf(stderr, "function not callable\n");
-		exit(0);
-	}
-
-	globals = PyObject_CallObject (func_globals, NULL);
-	if (!globals) {
-		fprintf(stderr, "cannot get globals\n");
-		exit(0);
-	}
-
-	func = PyDict_GetItemString (globals, funcname);
-	if (!func) {
-		fprintf(stderr, "cannot find function %s\n", funcname);
-		exit(0);
-	}
-
-	if (!PyCallable_Check (func)) {
-		fprintf(stderr, "function not callable\n");
-		exit(0);
-	}
-
-	rslt = PyObject_CallObject (func, NULL);
-	return rslt;
-}
-
 PyObject* vm_add_code_bloc(VmMngr *self, PyObject *args)
 {
 	PyObject *item1;
@@ -527,138 +458,6 @@ PyObject* vm_dump_code_bloc_pool(VmMngr* self)
 }
 
 
-PyObject* vm_exec_blocs(VmMngr* self, PyObject* args)
-{
-	PyObject* my_eip;
-	PyObject* b;
-	PyObject* module;
-	PyObject* func;
-	PyObject* meip;
-	uint64_t tmp;
-
-	PyObject* known_blocs;
-	PyObject* e;
-
-	if (!PyArg_ParseTuple(args, "OO", &my_eip, &known_blocs))
-		return NULL;
-
-	if(!PyDict_Check(known_blocs))
-		RAISE(PyExc_TypeError, "arg must be dict");
-
-	PyGetInt(my_eip, tmp);
-	meip = PyLong_FromUnsignedLongLong((uint64_t)tmp);
-	while (1){
-		b = PyDict_GetItem(known_blocs, meip);
-		if (b == NULL)
-			return meip;
-
-		module = PyObject_GetAttrString(b, "module_c");
-		if (module == NULL){
-			fprintf(stderr, "assert eip module_c in pyobject\n");
-			exit(0);
-		}
-		func = PyObject_GetAttrString(module, "func");
-		if (func == NULL){
-			fprintf(stderr, "assert func module_c in pyobject\n");
-			exit(0);
-		}
-
-		Py_DECREF(module);
-		if (!PyCallable_Check (func)) {
-			fprintf(stderr, "function not callable\n");
-			exit(0);
-		}
-		Py_DECREF(meip);
-		//printf("exec bloc %"PRIX64"\n", tmp);
-		meip = PyObject_CallObject (func, NULL);
-
-		Py_DECREF(func);
-		e = PyErr_Occurred ();
-		if (e){
-			fprintf(stderr, "exception\n");
-			return meip;
-		}
-
-		if (self->vm_mngr.exception_flags)
-			return meip;
-
-	}
-}
-
-
-
-PyObject* vm_exec_bloc(PyObject* self, PyObject* args)
-{
-	PyObject* b;
-	PyObject* module;
-	PyObject* func;
-	PyObject* meip;
-	uint64_t tmp;
-
-	PyObject* my_eip;
-	PyObject* known_blocs;
-	PyObject* e;
-
-	if (!PyArg_ParseTuple(args, "OO", &my_eip, &known_blocs))
-		return NULL;
-
-
-	if (PyInt_Check(my_eip)){
-		tmp = (uint64_t)PyInt_AsLong(my_eip);
-	}
-	else if (PyLong_Check(my_eip)){
-		tmp = (uint64_t)PyLong_AsUnsignedLongLong(my_eip);
-	}
-	else{
-		RAISE(PyExc_TypeError,"arg1 must be int");
-	}
-
-	meip = PyInt_FromLong((long)tmp);
-	b = PyDict_GetItem(known_blocs, my_eip);
-	if (b == NULL)
-		return meip;
-	module = PyObject_GetAttrString(b, "module_c");
-	if (module == NULL)
-		return meip;
-	func = PyObject_GetAttrString(module, "func");
-	if (func == NULL)
-		return meip;
-	Py_DECREF(module);
-	if (!PyCallable_Check (func)) {
-		fprintf(stderr, "function not callable\n");
-		exit(0);
-	}
-	Py_DECREF(meip);
-	meip = PyObject_CallObject (func, NULL);
-
-	Py_DECREF(func);
-	e = PyErr_Occurred ();
-	if (e){
-		fprintf(stderr, "exception\n");
-		return meip;
-	}
-
-	return meip;
-}
-
-
-PyObject* vm_set_automod_cb(VmMngr* self, PyObject* args)
-{
-	PyObject* cb_automod;
-
-	if (!PyArg_ParseTuple(args, "O", &cb_automod))
-		return NULL;
-
-	if (self->vm_mngr.cb_automod != NULL){
-		Py_DECREF(self->vm_mngr.cb_automod);
-	}
-
-	Py_INCREF(cb_automod);
-	self->vm_mngr.cb_automod = cb_automod;
-	Py_INCREF(Py_None);
-	return Py_None;
-}
-
 PyObject* vm_set_addr2obj(VmMngr* self, PyObject* args)
 {
 	PyObject* addr2obj;
@@ -759,16 +558,10 @@ static PyMethodDef VmMngr_methods[] = {
 	 "X"},
 	{"set_mem", (PyCFunction)vm_set_mem, METH_VARARGS,
 	 "X"},
-	{"set_automod_cb", (PyCFunction)vm_set_automod_cb, METH_VARARGS,
-	 "X"},
 	{"set_addr2obj", (PyCFunction)vm_set_addr2obj, METH_VARARGS,
 	 "X"},
 	{"add_code_bloc",(PyCFunction)vm_add_code_bloc, METH_VARARGS,
 	 "X"},
-	{"exec_bloc",(PyCFunction)vm_exec_bloc, METH_VARARGS,
-	 "X"},
-	{"exec_blocs",(PyCFunction)vm_exec_blocs, METH_VARARGS,
-	 "X"},
 	{"get_mem", (PyCFunction)vm_get_mem, METH_VARARGS,
 	 "X"},
 	{"add_memory_page",(PyCFunction)vm_add_memory_page, METH_VARARGS,
@@ -793,17 +586,10 @@ static PyMethodDef VmMngr_methods[] = {
 	 "X"},
 	{"set_alarm", (PyCFunction)set_alarm, METH_VARARGS,
 	 "X"},
-	{"call_pyfunc_from_globals",(PyCFunction)vm_call_pyfunc_from_globals, METH_VARARGS,
-	 "X"},
-
 	{"get_exception",(PyCFunction)vm_get_exception, METH_VARARGS,
 	 "X"},
 	{"get_exception",(PyCFunction)vm_get_exception, METH_VARARGS,
 	 "X"},
-	{"get_last_write_ad", (PyCFunction)vm_get_last_write_ad, METH_VARARGS,
-	 "X"},
-	{"get_last_write_size",(PyCFunction)vm_get_last_write_size, METH_VARARGS,
-	 "X"},
 
 	{"set_big_endian",(PyCFunction)vm_set_big_endian, METH_VARARGS,
 	 "X"},
diff --git a/miasm2/jitter/vm_mngr_py.h b/miasm2/jitter/vm_mngr_py.h
new file mode 100644
index 00000000..3c7c487b
--- /dev/null
+++ b/miasm2/jitter/vm_mngr_py.h
@@ -0,0 +1,13 @@
+#ifndef VM_MNGR_PY_H
+#define VM_MNGR_PY_H
+
+
+
+typedef struct {
+	PyObject_HEAD
+	PyObject *vmmngr;
+	vm_mngr_t vm_mngr;
+} VmMngr;
+
+
+#endif// VM_MNGR_PY_H
diff --git a/setup.py b/setup.py
index 8c2b100a..2397ca57 100755
--- a/setup.py
+++ b/setup.py
@@ -29,15 +29,19 @@ def buil_all():
                    "miasm2/jitter/vm_mngr_py.c"]),
         Extension("miasm2.jitter.arch.JitCore_x86",
                   ["miasm2/jitter/arch/JitCore.c",
+                   "miasm2/jitter/vm_mngr.c",
                    "miasm2/jitter/arch/JitCore_x86.c"]),
         Extension("miasm2.jitter.arch.JitCore_arm",
                   ["miasm2/jitter/arch/JitCore.c",
+                   "miasm2/jitter/vm_mngr.c",
                    "miasm2/jitter/arch/JitCore_arm.c"]),
         Extension("miasm2.jitter.arch.JitCore_msp430",
                   ["miasm2/jitter/arch/JitCore.c",
+                   "miasm2/jitter/vm_mngr.c",
                    "miasm2/jitter/arch/JitCore_msp430.c"]),
         Extension("miasm2.jitter.arch.JitCore_mips32",
                   ["miasm2/jitter/arch/JitCore.c",
+                   "miasm2/jitter/vm_mngr.c",
                    "miasm2/jitter/arch/JitCore_mips32.c"]),
         Extension("miasm2.jitter.Jitllvm",
                   ["miasm2/jitter/Jitllvm.c"]),
@@ -49,15 +53,19 @@ def buil_all():
                    "miasm2/jitter/vm_mngr_py.c"]),
         Extension("miasm2.jitter.arch.JitCore_x86",
                   ["miasm2/jitter/arch/JitCore.c",
+                   "miasm2/jitter/vm_mngr.c",
                    "miasm2/jitter/arch/JitCore_x86.c"]),
         Extension("miasm2.jitter.arch.JitCore_arm",
                   ["miasm2/jitter/arch/JitCore.c",
+                   "miasm2/jitter/vm_mngr.c",
                    "miasm2/jitter/arch/JitCore_arm.c"]),
         Extension("miasm2.jitter.arch.JitCore_msp430",
                   ["miasm2/jitter/arch/JitCore.c",
+                   "miasm2/jitter/vm_mngr.c",
                    "miasm2/jitter/arch/JitCore_msp430.c"]),
         Extension("miasm2.jitter.arch.JitCore_mips32",
                   ["miasm2/jitter/arch/JitCore.c",
+                   "miasm2/jitter/vm_mngr.c",
                    "miasm2/jitter/arch/JitCore_mips32.c"]),
         Extension("miasm2.jitter.Jitllvm",
                   ["miasm2/jitter/Jitllvm.c"]),