about summary refs log tree commit diff stats
path: root/miasm/jitter
diff options
context:
space:
mode:
Diffstat (limited to 'miasm/jitter')
-rw-r--r--miasm/jitter/JitCore.c19
-rw-r--r--miasm/jitter/JitCore.h2
-rw-r--r--miasm/jitter/arch/JitCore_mips32.h56
-rw-r--r--miasm/jitter/arch/JitCore_ppc32_regs.h69
-rw-r--r--miasm/jitter/arch/JitCore_x86.c11
-rw-r--r--miasm/jitter/bn.h2
-rw-r--r--miasm/jitter/codegen.py8
-rw-r--r--miasm/jitter/csts.py1
-rw-r--r--miasm/jitter/emulatedsymbexec.py8
-rw-r--r--miasm/jitter/jitcore.py16
-rw-r--r--miasm/jitter/jitcore_cc_base.py7
-rw-r--r--miasm/jitter/jitcore_gcc.py3
-rw-r--r--miasm/jitter/jitcore_llvm.py12
-rw-r--r--miasm/jitter/jitload.py22
-rw-r--r--miasm/jitter/loader/pe.py11
-rw-r--r--miasm/jitter/vm_mngr.c40
16 files changed, 229 insertions, 58 deletions
diff --git a/miasm/jitter/JitCore.c b/miasm/jitter/JitCore.c
index 1ba082c5..dfead5a8 100644
--- a/miasm/jitter/JitCore.c
+++ b/miasm/jitter/JitCore.c
@@ -41,6 +41,25 @@ PyObject * JitCpu_set_vmmngr(JitCpu *self, PyObject *value, void *closure)
 	return 0;
 }
 
+
+
+PyObject * JitCpu_get_vmcpu(JitCpu *self, void *closure)
+{
+	PyObject * ret;
+	uint64_t addr;
+	addr = (uint64_t) self->cpu;
+	ret = PyLong_FromUnsignedLongLong(addr);
+	return ret;
+}
+
+PyObject * JitCpu_set_vmcpu(JitCpu *self, PyObject *value, void *closure)
+{
+	fprintf(stderr, "Set vmcpu not supported yet\n");
+	exit(-1);
+}
+
+
+
 PyObject * JitCpu_get_jitter(JitCpu *self, void *closure)
 {
 	if (self->jitter) {
diff --git a/miasm/jitter/JitCore.h b/miasm/jitter/JitCore.h
index 7b7f6c13..ff6ff159 100644
--- a/miasm/jitter/JitCore.h
+++ b/miasm/jitter/JitCore.h
@@ -203,6 +203,8 @@ void JitCpu_dealloc(JitCpu* self);
 PyObject * JitCpu_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
 PyObject * JitCpu_get_vmmngr(JitCpu *self, void *closure);
 PyObject * JitCpu_set_vmmngr(JitCpu *self, PyObject *value, void *closure);
+PyObject * JitCpu_get_vmcpu(JitCpu *self, void *closure);
+PyObject * JitCpu_set_vmcpu(JitCpu *self, PyObject *value, void *closure);
 PyObject * JitCpu_get_jitter(JitCpu *self, void *closure);
 PyObject * JitCpu_set_jitter(JitCpu *self, PyObject *value, void *closure);
 void Resolve_dst(block_id* BlockDst, uint64_t addr, uint64_t is_local);
diff --git a/miasm/jitter/arch/JitCore_mips32.h b/miasm/jitter/arch/JitCore_mips32.h
index 74eb35ef..8478fb53 100644
--- a/miasm/jitter/arch/JitCore_mips32.h
+++ b/miasm/jitter/arch/JitCore_mips32.h
@@ -83,7 +83,7 @@ struct vm_cpu {
 	uint32_t CPR0_5;
 	uint32_t CPR0_6;
 	uint32_t CPR0_7;
-	uint32_t CPR0_8;
+	uint32_t RANDOM;
 	uint32_t CPR0_9;
 	uint32_t CPR0_10;
 	uint32_t CPR0_11;
@@ -107,8 +107,8 @@ struct vm_cpu {
 	uint32_t CPR0_29;
 	uint32_t CPR0_30;
 	uint32_t CPR0_31;
-	uint32_t CPR0_32;
-	uint32_t CPR0_33;
+	uint32_t CONTEXT;
+	uint32_t CONTEXTCONFIG;
 	uint32_t CPR0_34;
 	uint32_t CPR0_35;
 	uint32_t CPR0_36;
@@ -116,20 +116,20 @@ struct vm_cpu {
 	uint32_t CPR0_38;
 	uint32_t CPR0_39;
 	uint32_t PAGEMASK;
-	uint32_t CPR0_41;
-	uint32_t CPR0_42;
-	uint32_t CPR0_43;
-	uint32_t CPR0_44;
-	uint32_t CPR0_45;
-	uint32_t CPR0_46;
-	uint32_t CPR0_47;
-	uint32_t CPR0_48;
+	uint32_t PAGEGRAIN;
+	uint32_t SEGCTL0;
+	uint32_t SEGCTL1;
+	uint32_t SEGCTL2;
+	uint32_t PWBASE;
+	uint32_t PWFIELD;
+	uint32_t PWSIZE;
+	uint32_t WIRED;
 	uint32_t CPR0_49;
 	uint32_t CPR0_50;
 	uint32_t CPR0_51;
 	uint32_t CPR0_52;
 	uint32_t CPR0_53;
-	uint32_t CPR0_54;
+	uint32_t PWCTL;
 	uint32_t CPR0_55;
 	uint32_t CPR0_56;
 	uint32_t CPR0_57;
@@ -139,9 +139,9 @@ struct vm_cpu {
 	uint32_t CPR0_61;
 	uint32_t CPR0_62;
 	uint32_t CPR0_63;
-	uint32_t CPR0_64;
-	uint32_t CPR0_65;
-	uint32_t CPR0_66;
+	uint32_t BADVADDR;
+	uint32_t BADINSTR;
+	uint32_t BADINSTRP;
 	uint32_t CPR0_67;
 	uint32_t CPR0_68;
 	uint32_t CPR0_69;
@@ -195,8 +195,8 @@ struct vm_cpu {
 	uint32_t CPR0_117;
 	uint32_t CPR0_118;
 	uint32_t CPR0_119;
-	uint32_t CPR0_120;
-	uint32_t CPR0_121;
+	uint32_t PRID;
+	uint32_t EBASE;
 	uint32_t CPR0_122;
 	uint32_t CPR0_123;
 	uint32_t CPR0_124;
@@ -204,11 +204,11 @@ struct vm_cpu {
 	uint32_t CPR0_126;
 	uint32_t CPR0_127;
 	uint32_t CONFIG;
-	uint32_t CPR0_129;
-	uint32_t CPR0_130;
-	uint32_t CPR0_131;
-	uint32_t CPR0_132;
-	uint32_t CPR0_133;
+	uint32_t CONFIG1;
+	uint32_t CONFIG2;
+	uint32_t CONFIG3;
+	uint32_t CONFIG4;
+	uint32_t CONFIG5;
 	uint32_t CPR0_134;
 	uint32_t CPR0_135;
 	uint32_t CPR0_136;
@@ -325,12 +325,12 @@ struct vm_cpu {
 	uint32_t CPR0_247;
 	uint32_t CPR0_248;
 	uint32_t CPR0_249;
-	uint32_t CPR0_250;
-	uint32_t CPR0_251;
-	uint32_t CPR0_252;
-	uint32_t CPR0_253;
-	uint32_t CPR0_254;
-	uint32_t CPR0_255;
+	uint32_t KSCRATCH0;
+	uint32_t KSCRATCH1;
+	uint32_t KSCRATCH2;
+	uint32_t KSCRATCH3;
+	uint32_t KSCRATCH4;
+	uint32_t KSCRATCH5;
 };
 
 _MIASM_EXPORT void dump_gpregs(struct vm_cpu* vmcpu);
diff --git a/miasm/jitter/arch/JitCore_ppc32_regs.h b/miasm/jitter/arch/JitCore_ppc32_regs.h
index a16d1e95..79191d32 100644
--- a/miasm/jitter/arch/JitCore_ppc32_regs.h
+++ b/miasm/jitter/arch/JitCore_ppc32_regs.h
@@ -121,3 +121,72 @@ JITCORE_PPC_REG_EXPAND(DBAT2L, 32)
 JITCORE_PPC_REG_EXPAND(DBAT3U, 32)
 JITCORE_PPC_REG_EXPAND(DBAT3L, 32)
 JITCORE_PPC_REG_EXPAND(SDR1, 32)
+
+JITCORE_PPC_REG_EXPAND(FPR0, 64)
+JITCORE_PPC_REG_EXPAND(FPR1, 64)
+JITCORE_PPC_REG_EXPAND(FPR2, 64)
+JITCORE_PPC_REG_EXPAND(FPR3, 64)
+JITCORE_PPC_REG_EXPAND(FPR4, 64)
+JITCORE_PPC_REG_EXPAND(FPR5, 64)
+JITCORE_PPC_REG_EXPAND(FPR6, 64)
+JITCORE_PPC_REG_EXPAND(FPR7, 64)
+JITCORE_PPC_REG_EXPAND(FPR8, 64)
+JITCORE_PPC_REG_EXPAND(FPR9, 64)
+JITCORE_PPC_REG_EXPAND(FPR10, 64)
+JITCORE_PPC_REG_EXPAND(FPR11, 64)
+JITCORE_PPC_REG_EXPAND(FPR12, 64)
+JITCORE_PPC_REG_EXPAND(FPR13, 64)
+JITCORE_PPC_REG_EXPAND(FPR14, 64)
+JITCORE_PPC_REG_EXPAND(FPR15, 64)
+JITCORE_PPC_REG_EXPAND(FPR16, 64)
+JITCORE_PPC_REG_EXPAND(FPR17, 64)
+JITCORE_PPC_REG_EXPAND(FPR18, 64)
+JITCORE_PPC_REG_EXPAND(FPR19, 64)
+JITCORE_PPC_REG_EXPAND(FPR20, 64)
+JITCORE_PPC_REG_EXPAND(FPR21, 64)
+JITCORE_PPC_REG_EXPAND(FPR22, 64)
+JITCORE_PPC_REG_EXPAND(FPR23, 64)
+JITCORE_PPC_REG_EXPAND(FPR24, 64)
+JITCORE_PPC_REG_EXPAND(FPR25, 64)
+JITCORE_PPC_REG_EXPAND(FPR26, 64)
+JITCORE_PPC_REG_EXPAND(FPR27, 64)
+JITCORE_PPC_REG_EXPAND(FPR28, 64)
+JITCORE_PPC_REG_EXPAND(FPR29, 64)
+JITCORE_PPC_REG_EXPAND(FPR30, 64)
+JITCORE_PPC_REG_EXPAND(FPR31, 64)
+JITCORE_PPC_REG_EXPAND(FPSCR, 32)
+
+JITCORE_PPC_REG_EXPAND(VR0, 128)
+JITCORE_PPC_REG_EXPAND(VR1, 128)
+JITCORE_PPC_REG_EXPAND(VR2, 128)
+JITCORE_PPC_REG_EXPAND(VR3, 128)
+JITCORE_PPC_REG_EXPAND(VR4, 128)
+JITCORE_PPC_REG_EXPAND(VR5, 128)
+JITCORE_PPC_REG_EXPAND(VR6, 128)
+JITCORE_PPC_REG_EXPAND(VR7, 128)
+JITCORE_PPC_REG_EXPAND(VR8, 128)
+JITCORE_PPC_REG_EXPAND(VR9, 128)
+JITCORE_PPC_REG_EXPAND(VR10, 128)
+JITCORE_PPC_REG_EXPAND(VR11, 128)
+JITCORE_PPC_REG_EXPAND(VR12, 128)
+JITCORE_PPC_REG_EXPAND(VR13, 128)
+JITCORE_PPC_REG_EXPAND(VR14, 128)
+JITCORE_PPC_REG_EXPAND(VR15, 128)
+JITCORE_PPC_REG_EXPAND(VR16, 128)
+JITCORE_PPC_REG_EXPAND(VR17, 128)
+JITCORE_PPC_REG_EXPAND(VR18, 128)
+JITCORE_PPC_REG_EXPAND(VR19, 128)
+JITCORE_PPC_REG_EXPAND(VR20, 128)
+JITCORE_PPC_REG_EXPAND(VR21, 128)
+JITCORE_PPC_REG_EXPAND(VR22, 128)
+JITCORE_PPC_REG_EXPAND(VR23, 128)
+JITCORE_PPC_REG_EXPAND(VR24, 128)
+JITCORE_PPC_REG_EXPAND(VR25, 128)
+JITCORE_PPC_REG_EXPAND(VR26, 128)
+JITCORE_PPC_REG_EXPAND(VR27, 128)
+JITCORE_PPC_REG_EXPAND(VR28, 128)
+JITCORE_PPC_REG_EXPAND(VR29, 128)
+JITCORE_PPC_REG_EXPAND(VR30, 128)
+JITCORE_PPC_REG_EXPAND(VR31, 128)
+JITCORE_PPC_REG_EXPAND(VRSAVE, 32)
+JITCORE_PPC_REG_EXPAND(VSCR, 32)
diff --git a/miasm/jitter/arch/JitCore_x86.c b/miasm/jitter/arch/JitCore_x86.c
index 361b18b4..9081f3d8 100644
--- a/miasm/jitter/arch/JitCore_x86.c
+++ b/miasm/jitter/arch/JitCore_x86.c
@@ -414,7 +414,7 @@ PyObject* cpu_set_segm_base(JitCpu* self, PyObject* args)
 
 	PyGetInt_uint64_t(item1, segm_num);
 	PyGetInt_uint64_t(item2, segm_base);
-	((struct vm_cpu*)self->cpu)->segm_base[segm_num] = segm_base;
+	((struct vm_cpu*)self->cpu)->segm_base[segm_num & 0xFFFF] = segm_base;
 
 	Py_INCREF(Py_None);
 	return Py_None;
@@ -429,13 +429,13 @@ PyObject* cpu_get_segm_base(JitCpu* self, PyObject* args)
 	if (!PyArg_ParseTuple(args, "O", &item1))
 		RAISE(PyExc_TypeError,"Cannot parse arguments");
 	PyGetInt_uint64_t(item1, segm_num);
-	v = PyLong_FromLong((long)(((struct vm_cpu*)self->cpu)->segm_base[segm_num]));
+	v = PyLong_FromLong((long)(((struct vm_cpu*)self->cpu)->segm_base[segm_num & 0xFFFF]));
 	return v;
 }
 
 uint64_t segm2addr(JitCpu* jitcpu, uint64_t segm, uint64_t addr)
 {
-	return addr + ((struct vm_cpu*)jitcpu->cpu)->segm_base[segm];
+	return addr + ((struct vm_cpu*)jitcpu->cpu)->segm_base[segm & 0xFFFF];
 }
 
 void MEM_WRITE_08(JitCpu* jitcpu, uint64_t addr, uint8_t src)
@@ -730,6 +730,11 @@ static PyGetSetDef JitCpu_getseters[] = {
      "vmmngr",
      NULL},
 
+    {"vmcpu",
+     (getter)JitCpu_get_vmcpu, (setter)JitCpu_set_vmcpu,
+     "vmcpu",
+     NULL},
+
     {"jitter",
      (getter)JitCpu_get_jitter, (setter)JitCpu_set_jitter,
      "jitter",
diff --git a/miasm/jitter/bn.h b/miasm/jitter/bn.h
index 1aa6b432..8c4a8ba1 100644
--- a/miasm/jitter/bn.h
+++ b/miasm/jitter/bn.h
@@ -35,7 +35,7 @@ Code slightly modified to support ast generation calculus style from Expr.
 #include <assert.h>
 
 
-/* This macro defines the word size in bytes of the array that constitues the big-number data structure. */
+/* This macro defines the word size in bytes of the array that constitutes the big-number data structure. */
 #ifndef WORD_SIZE
   #define WORD_SIZE 4
 #endif
diff --git a/miasm/jitter/codegen.py b/miasm/jitter/codegen.py
index abbf65d2..0b5b7961 100644
--- a/miasm/jitter/codegen.py
+++ b/miasm/jitter/codegen.py
@@ -6,8 +6,8 @@ from builtins import zip
 
 from future.utils import viewitems, viewvalues
 
-from miasm.expression.expression import Expr, ExprId, ExprLoc, ExprInt, \
-    ExprMem, ExprCond, LocKey
+from miasm.expression.expression import ExprId, ExprLoc, ExprInt, \
+    ExprMem, ExprCond, LocKey, is_expr
 from miasm.ir.ir import IRBlock, AssignBlock
 
 from miasm.ir.translators.C import TranslatorC
@@ -123,7 +123,7 @@ class CGen(object):
 
     def dst_to_c(self, src):
         """Translate Expr @src into C code"""
-        if not isinstance(src, Expr):
+        if not is_expr(src):
             src = ExprInt(src, self.PC.size)
         return self.id_to_c(src)
 
@@ -413,7 +413,7 @@ class CGen(object):
         @dst: potential instruction destination"""
 
         out = []
-        if isinstance(dst, Expr):
+        if is_expr(dst):
             out += self.gen_post_code(attrib, "DST_value")
             out.append('BlockDst->address = DST_value;')
             out += self.gen_post_instr_checks(attrib)
diff --git a/miasm/jitter/csts.py b/miasm/jitter/csts.py
index 6d40fe0d..3829ed98 100644
--- a/miasm/jitter/csts.py
+++ b/miasm/jitter/csts.py
@@ -9,6 +9,7 @@ EXCEPT_CODE_AUTOMOD = (1 << 0)
 EXCEPT_SOFT_BP = (1 << 1)
 EXCEPT_INT_XX = (1 << 2)
 EXCEPT_SPR_ACCESS = (1 << 3)
+EXCEPT_SYSCALL = (1 << 4)
 EXCEPT_BREAKPOINT_MEMORY = (1 << 10)
 # Deprecated
 EXCEPT_BREAKPOINT_INTERN = EXCEPT_BREAKPOINT_MEMORY
diff --git a/miasm/jitter/emulatedsymbexec.py b/miasm/jitter/emulatedsymbexec.py
index aacfba9f..844e7d5f 100644
--- a/miasm/jitter/emulatedsymbexec.py
+++ b/miasm/jitter/emulatedsymbexec.py
@@ -94,10 +94,10 @@ class EmulatedSymbExec(SymbolicExecutionEngine):
         data = self.expr_simp(data)
         if not isinstance(data, m2_expr.ExprInt):
             raise RuntimeError("A simplification is missing: %s" % data)
-        to_write = data.arg.arg
+        to_write = int(data)
 
         # Format information
-        addr = dest.ptr.arg.arg
+        addr = int(dest.ptr)
         size = data.size // 8
         content = hex(to_write).replace("0x", "").replace("L", "")
         content = "0" * (size * 2 - len(content)) + content
@@ -120,7 +120,7 @@ class EmulatedSymbExec(SymbolicExecutionEngine):
                     if not isinstance(value, m2_expr.ExprInt):
                         raise ValueError("A simplification is missing: %s" % value)
 
-                    setattr(self.cpu, symbol.name, value.arg.arg)
+                    setattr(self.cpu, symbol.name, int(value))
             else:
                 raise NotImplementedError("Type not handled: %s" % symbol)
 
@@ -140,7 +140,7 @@ class EmulatedSymbExec(SymbolicExecutionEngine):
     # CPU specific simplifications
     def _simp_handle_segm(self, e_s, expr):
         """Handle 'segm' operation"""
-        if not expr.is_op_segm():
+        if not m2_expr.is_op_segm(expr):
             return expr
         if not expr.args[0].is_int():
             return expr
diff --git a/miasm/jitter/jitcore.py b/miasm/jitter/jitcore.py
index ebda656f..cc531cf5 100644
--- a/miasm/jitter/jitcore.py
+++ b/miasm/jitter/jitcore.py
@@ -104,7 +104,7 @@ class JitCore(object):
             cur_block.ad_max = cur_block.lines[-1].offset + cur_block.lines[-1].l
         else:
             # 1 byte block for unknown mnemonic
-            offset = ir_arch.loc_db.get_location_offset(cur_block.loc_key)
+            offset = self.ir_arch.loc_db.get_location_offset(cur_block.loc_key)
             cur_block.ad_min = offset
             cur_block.ad_max = offset+1
 
@@ -198,10 +198,7 @@ class JitCore(object):
         """
 
         mem_range = interval()
-
-        for block in blocks:
-            mem_range += interval([(block.ad_min, block.ad_max - 1)])
-
+        mem_range = interval([(block.ad_min, block.ad_max - 1) for block in blocks])
         return mem_range
 
     def __updt_jitcode_mem_range(self, vm):
@@ -235,12 +232,6 @@ class JitCore(object):
                 # Modified blocks
                 modified_blocks.add(block)
 
-        # Generate interval to delete
-        del_interval = self.blocks_to_memrange(modified_blocks)
-
-        # Remove interval from monitored interval list
-        self.blocks_mem_interval -= del_interval
-
         # Remove modified blocks
         for block in modified_blocks:
             try:
@@ -259,6 +250,9 @@ class JitCore(object):
             # Remove label -> block link
             del(self.loc_key_to_block[block.loc_key])
 
+        # Re generate blocks intervals
+        self.blocks_mem_interval = self.blocks_to_memrange(self.loc_key_to_block.values())
+
         return modified_blocks
 
     def updt_automod_code_range(self, vm, mem_range):
diff --git a/miasm/jitter/jitcore_cc_base.py b/miasm/jitter/jitcore_cc_base.py
index 995c458b..afb2876c 100644
--- a/miasm/jitter/jitcore_cc_base.py
+++ b/miasm/jitter/jitcore_cc_base.py
@@ -1,5 +1,6 @@
 #-*- coding:utf-8 -*-
 
+import glob
 import os
 import tempfile
 import platform
@@ -76,6 +77,12 @@ class JitCore_Cc_Base(JitCore):
         ext = sysconfig.get_config_var('EXT_SUFFIX')
         if ext is None:
             ext = ".so" if not is_win else ".lib"
+        if is_win:
+            # sysconfig.get_config_var('EXT_SUFFIX') is .pyd on Windows and need to be forced to .lib
+            # Additionally windows built libraries may have a name like VmMngr.cp38-win_amd64.lib
+            ext_files = glob.glob(os.path.join(lib_dir, "VmMngr.*lib"))
+            if len(ext_files) == 1:
+                ext = os.path.basename(ext_files[0]).replace("VmMngr", "")
 
         libs = [
             os.path.join(lib_dir, "VmMngr" + ext),
diff --git a/miasm/jitter/jitcore_gcc.py b/miasm/jitter/jitcore_gcc.py
index 1520cf38..7ffef69e 100644
--- a/miasm/jitter/jitcore_gcc.py
+++ b/miasm/jitter/jitcore_gcc.py
@@ -1,5 +1,6 @@
 #-*- coding:utf-8 -*-
 
+import sys
 import os
 import tempfile
 import ctypes
@@ -70,7 +71,7 @@ class JitCore_Gcc(JitCore_Cc_Base):
                         get_python_inc(),
                         "..",
                         "libs",
-                        "python27.lib"
+                        "python%d%d.lib" % (sys.version_info.major, sys.version_info.minor)
                     )
                 )
                 cl = [
diff --git a/miasm/jitter/jitcore_llvm.py b/miasm/jitter/jitcore_llvm.py
index 46e93282..df7d5950 100644
--- a/miasm/jitter/jitcore_llvm.py
+++ b/miasm/jitter/jitcore_llvm.py
@@ -1,5 +1,6 @@
 from __future__ import print_function
 import os
+import glob
 import importlib
 import tempfile
 import sysconfig
@@ -9,6 +10,9 @@ import miasm.jitter.jitcore as jitcore
 from miasm.jitter import Jitllvm
 import platform
 
+import llvmlite
+llvmlite.binding.load_library_permanently(Jitllvm.__file__)
+
 is_win = platform.system() == "Windows"
 
 class JitCore_LLVM(jitcore.JitCore):
@@ -56,10 +60,16 @@ class JitCore_LLVM(jitcore.JitCore):
 
         # Get architecture dependent Jitcore library (if any)
         lib_dir = os.path.dirname(os.path.realpath(__file__))
-        lib_dir = os.path.join(lib_dir, 'arch')
         ext = sysconfig.get_config_var('EXT_SUFFIX')
         if ext is None:
             ext = ".so" if not is_win else ".pyd"
+        if is_win:
+            # sysconfig.get_config_var('EXT_SUFFIX') is .pyd on Windows and need to be forced to .lib
+            # Additionally windows built libraries may have a name like VmMngr.cp38-win_amd64.lib
+            ext_files = glob.glob(os.path.join(lib_dir, "VmMngr.*pyd"))
+            if len(ext_files) == 1:
+                ext = os.path.basename(ext_files[0]).replace("VmMngr", "")
+        lib_dir = os.path.join(lib_dir, 'arch')
         try:
             jit_lib = os.path.join(
                 lib_dir, self.arch_dependent_libs[self.ir_arch.arch.name] + ext
diff --git a/miasm/jitter/jitload.py b/miasm/jitter/jitload.py
index 68f9c40d..85d5636f 100644
--- a/miasm/jitter/jitload.py
+++ b/miasm/jitter/jitload.py
@@ -393,13 +393,16 @@ class Jitter(object):
         self.pc = pc
         self.run = True
 
-    def continue_run(self, step=False):
+    def continue_run(self, step=False, trace=False):
         """PRE: init_run.
         Continue the run of the current session until iterator returns or run is
         set to False.
         If step is True, run only one time.
+        If trace is True, activate trace log option until execution stops
         Return the iterator value"""
 
+        if trace:
+            self.set_trace_log()
         while self.run:
             try:
                 return next(self.run_iterator)
@@ -409,8 +412,9 @@ class Jitter(object):
             self.run_iterator = self.runiter_once(self.pc)
 
             if step is True:
-                return None
-
+                break
+        if trace:
+            self.set_trace_log(False, False, False)
         return None
 
 
@@ -422,6 +426,18 @@ class Jitter(object):
         self.init_run(addr)
         return self.continue_run()
 
+    def run_until(self, addr, trace=False):
+        """PRE: init_run.
+        Continue the run of the current session until iterator returns, run is
+        set to False or addr is reached.
+        If trace is True, activate trace log option until execution stops
+        Return the iterator value"""
+
+        def stop_exec(jitter):
+            jitter.remove_breakpoints_by_callback(stop_exec)
+            return False
+        self.add_breakpoint(addr, stop_exec)
+        return self.continue_run(trace=trace)
 
     def init_stack(self):
         self.vm.add_memory_page(
diff --git a/miasm/jitter/loader/pe.py b/miasm/jitter/loader/pe.py
index 961bfd93..73cb1367 100644
--- a/miasm/jitter/loader/pe.py
+++ b/miasm/jitter/loader/pe.py
@@ -171,7 +171,7 @@ def get_export_name_addr_list(e):
     return out
 
 
-def vm_load_pe(vm, fdata, align_s=True, load_hdr=True, name="", **kargs):
+def vm_load_pe(vm, fdata, align_s=True, load_hdr=True, name="", winobjs=None, **kargs):
     """Load a PE in memory (@vm) from a data buffer @fdata
     @vm: VmMngr instance
     @fdata: data buffer to parse
@@ -207,6 +207,9 @@ def vm_load_pe(vm, fdata, align_s=True, load_hdr=True, name="", **kargs):
                 pe.content[:hdr_len] +
                 max(0, (min_len - hdr_len)) * b"\x00"
             )
+
+            if winobjs:
+                winobjs.allocated_pages[pe.NThdr.ImageBase] = (pe.NThdr.ImageBase, len(pe_hdr))
             vm.add_memory_page(
                 pe.NThdr.ImageBase,
                 PAGE_READ | PAGE_WRITE,
@@ -237,8 +240,12 @@ def vm_load_pe(vm, fdata, align_s=True, load_hdr=True, name="", **kargs):
             attrib = PAGE_READ
             if section.flags & 0x80000000:
                 attrib |= PAGE_WRITE
+
+            section_addr = pe.rva2virt(section.addr)
+            if winobjs:
+                winobjs.allocated_pages[section_addr] = (section_addr, len(data))
             vm.add_memory_page(
-                pe.rva2virt(section.addr),
+                section_addr,
                 attrib,
                 data,
                 "%r: %r" % (name, section.name)
diff --git a/miasm/jitter/vm_mngr.c b/miasm/jitter/vm_mngr.c
index 0c8a0586..d0e49213 100644
--- a/miasm/jitter/vm_mngr.c
+++ b/miasm/jitter/vm_mngr.c
@@ -551,6 +551,46 @@ int vm_read_mem(vm_mngr_t* vm_mngr, uint64_t addr, char** buffer_ptr, size_t siz
        return 0;
 }
 
+
+/*
+   Try to read @size bytes from vm mmemory
+   Return the number of bytes consecutively read
+*/
+uint64_t vm_read_mem_ret_buf(vm_mngr_t* vm_mngr, uint64_t addr, size_t size, char *buffer)
+{
+	size_t len;
+	uint64_t addr_diff;
+	uint64_t size_out;
+	size_t addr_diff_st;
+
+	struct memory_page_node * mpn;
+
+	size_out = 0;
+	/* read is multiple page wide */
+	while (size){
+		mpn = get_memory_page_from_address(vm_mngr, addr, 0);
+		if (!mpn){
+			return size_out;
+		}
+
+		addr_diff = addr - mpn->ad;
+		if (addr_diff > SIZE_MAX) {
+			fprintf(stderr, "Size too big\n");
+			exit(EXIT_FAILURE);
+		}
+		addr_diff_st = (size_t) addr_diff;
+		len = MIN(size, mpn->size - addr_diff_st);
+		memcpy(buffer, (char*)mpn->ad_hp + (addr_diff_st), len);
+		buffer += len;
+		size_out += len;
+		addr += len;
+		size -= len;
+	}
+
+	return size_out;
+}
+
+
 int vm_write_mem(vm_mngr_t* vm_mngr, uint64_t addr, char *buffer, size_t size)
 {
        size_t len;