about summary refs log tree commit diff stats
path: root/miasm2/jitter
diff options
context:
space:
mode:
Diffstat (limited to 'miasm2/jitter')
-rw-r--r--miasm2/jitter/csts.py2
-rw-r--r--miasm2/jitter/jitload.py7
-rw-r--r--miasm2/jitter/loader/elf.py20
-rw-r--r--miasm2/jitter/loader/pe.py137
-rw-r--r--miasm2/jitter/loader/utils.py8
-rw-r--r--miasm2/jitter/vm_mngr.c346
-rw-r--r--miasm2/jitter/vm_mngr.h58
-rw-r--r--miasm2/jitter/vm_mngr_py.c64
8 files changed, 209 insertions, 433 deletions
diff --git a/miasm2/jitter/csts.py b/miasm2/jitter/csts.py
index e4b315e1..b71e9463 100644
--- a/miasm2/jitter/csts.py
+++ b/miasm2/jitter/csts.py
@@ -11,6 +11,8 @@ EXCEPT_INT_XX = (1 << 2)
 EXCEPT_BREAKPOINT_INTERN = (1 << 10)
 
 EXCEPT_ACCESS_VIOL = ((1 << 14) | EXCEPT_DO_NOT_UPDATE_PC)
+EXCEPT_DIV_BY_ZERO = ((1 << 16) | EXCEPT_DO_NOT_UPDATE_PC)
+EXCEPT_PRIV_INSN = ((1 << 17) | EXCEPT_DO_NOT_UPDATE_PC)
 # VM Mngr constants
 
 PAGE_READ = 1
diff --git a/miasm2/jitter/jitload.py b/miasm2/jitter/jitload.py
index a035445b..2335cc3c 100644
--- a/miasm2/jitter/jitload.py
+++ b/miasm2/jitter/jitload.py
@@ -144,12 +144,11 @@ class CallbackHandlerBitflag(CallbackHandler):
         Iterator on other results"""
 
         res = True
-        for b in self.callbacks:
-
-            if b & bitflag != 0:
+        for bitflag_expected in self.callbacks:
+            if bitflag_expected & bitflag == bitflag_expected:
                 # If the flag matched
                 for res in super(CallbackHandlerBitflag,
-                                 self).call_callbacks(b, *args):
+                                 self).call_callbacks(bitflag_expected, *args):
                     if res is not True:
                         yield res
 
diff --git a/miasm2/jitter/loader/elf.py b/miasm2/jitter/loader/elf.py
index b3946000..08df632a 100644
--- a/miasm2/jitter/loader/elf.py
+++ b/miasm2/jitter/loader/elf.py
@@ -17,6 +17,7 @@ hnd.setFormatter(logging.Formatter("[%(levelname)s]: %(message)s"))
 log.addHandler(hnd)
 log.setLevel(logging.CRITICAL)
 
+
 def get_import_address_elf(e):
     import2addr = defaultdict(set)
     for sh in e.sh:
@@ -46,21 +47,21 @@ def preload_elf(vm, e, runtime_lib, patch_vm_imp=True):
     return runtime_lib, dyn_funcs
 
 
-
 def vm_load_elf(vm, fdata, **kargs):
     """
     Very dirty elf loader
     TODO XXX: implement real loader
     """
-    #log.setLevel(logging.DEBUG)
+    # log.setLevel(logging.DEBUG)
     e = elf_init.ELF(fdata, **kargs)
     i = interval()
     all_data = {}
     for p in e.ph.phlist:
-        if p.ph.type != 1:
+        if p.ph.type != elf_csts.PT_LOAD:
             continue
-        log.debug('0x%x 0x%x 0x%x 0x%x', p.ph.vaddr, p.ph.memsz, p.ph.offset,
-                  p.ph.filesz)
+        log.debug(
+            '0x%x 0x%x 0x%x 0x%x 0x%x', p.ph.vaddr, p.ph.memsz, p.ph.offset,
+                  p.ph.filesz, p.ph.type)
         data_o = e._content[p.ph.offset:p.ph.offset + p.ph.filesz]
         addr_o = p.ph.vaddr
         a_addr = addr_o & ~0xFFF
@@ -68,16 +69,16 @@ def vm_load_elf(vm, fdata, **kargs):
         b_addr = (b_addr + 0xFFF) & ~0xFFF
         all_data[addr_o] = data_o
         # -2: Trick to avoid merging 2 consecutive pages
-        i += [(a_addr, b_addr-2)]
+        i += [(a_addr, b_addr - 2)]
     for a, b in i.intervals:
-        #print hex(a), hex(b)
-        vm.add_memory_page(a, PAGE_READ | PAGE_WRITE, "\x00"*(b+2-a))
-
+        # print hex(a), hex(b)
+        vm.add_memory_page(a, PAGE_READ | PAGE_WRITE, "\x00" * (b + 2 - a))
 
     for r_vaddr, data in all_data.items():
         vm.set_mem(r_vaddr, data)
     return e
 
+
 class libimp_elf(libimp):
     pass
 
@@ -94,6 +95,7 @@ ELF_machine = {(elf_csts.EM_ARM, 32, elf_csts.ELFDATA2LSB): "arml",
                (elf_csts.EM_SH, 32, elf_csts.ELFDATA2LSB): "sh4",
                }
 
+
 def guess_arch(elf):
     """Return the architecture specified by the ELF container @elf.
     If unknown, return None"""
diff --git a/miasm2/jitter/loader/pe.py b/miasm2/jitter/loader/pe.py
index 1e876b4e..1c811101 100644
--- a/miasm2/jitter/loader/pe.py
+++ b/miasm2/jitter/loader/pe.py
@@ -10,12 +10,24 @@ from elfesteem import *
 from miasm2.jitter.csts import *
 from miasm2.jitter.loader.utils import canon_libname_libfunc, libimp
 
-
 log = logging.getLogger('loader_pe')
 hnd = logging.StreamHandler()
 hnd.setFormatter(logging.Formatter("[%(levelname)s]: %(message)s"))
 log.addHandler(hnd)
-log.setLevel(logging.CRITICAL)
+log.setLevel(logging.INFO)
+
+
+def get_pe_dependencies(pe_obj):
+    """Return dependency set
+    @pe_obj: pe object"""
+
+    if pe_obj.DirImport.impdesc is None:
+        return set()
+    out = set()
+    for dependency in pe_obj.DirImport.impdesc:
+        libname = dependency.dlldescname.name.lower()
+        out.add(libname)
+    return out
 
 
 def get_import_address_pe(e):
@@ -58,7 +70,7 @@ def is_redirected_export(e, ad):
     # test is ad points to code or dll name
     out = ''
     for i in xrange(0x200):
-        c = e.virt(ad + i)
+        c = e.virt.get(ad + i)
         if c == "\x00":
             break
         out += c
@@ -101,6 +113,7 @@ def vm_load_pe(vm, fdata, align_s=True, load_hdr=True, **kargs):
     If all sections are aligned, they will be mapped on several different pages
     Otherwise, a big page is created, containing all sections
     """
+
     # Parse and build a PE instance
     pe = pe_init.PE(fdata, **kargs)
 
@@ -199,6 +212,9 @@ def vm_load_pe_lib(vm, fname_in, libs, lib_path_base, **kargs):
     Return the corresponding PE instance
     Extra arguments are passed to vm_load_pe
     """
+
+    log.info('Loading module %r', fname_in)
+
     fname = os.path.join(lib_path_base, fname_in)
     with open(fname) as fstream:
         pe = vm_load_pe(vm, fstream.read(), **kargs)
@@ -206,7 +222,7 @@ def vm_load_pe_lib(vm, fname_in, libs, lib_path_base, **kargs):
     return pe
 
 
-def vm_load_pe_libs(vm, libs_name, libs, lib_path_base="win_dll", **kargs):
+def vm_load_pe_libs(vm, libs_name, libs, lib_path_base, **kargs):
     """Call vm_load_pe_lib on each @libs_name filename
     @vm: VmMngr instance
     @libs_name: list of str
@@ -219,7 +235,7 @@ def vm_load_pe_libs(vm, libs_name, libs, lib_path_base="win_dll", **kargs):
             for fname in libs_name}
 
 
-def vm_fix_imports_pe_libs(lib_imgs, libs, lib_path_base="win_dll",
+def vm_fix_imports_pe_libs(lib_imgs, libs, lib_path_base,
                            patch_vm_imp=True, **kargs):
     for e in lib_imgs.values():
         preload_pe(e, libs, patch_vm_imp)
@@ -228,7 +244,7 @@ def vm_fix_imports_pe_libs(lib_imgs, libs, lib_path_base="win_dll",
 def vm2pe(myjit, fname, libs=None, e_orig=None,
           min_addr=None, max_addr=None,
           min_section_offset=0x1000, img_base=None,
-          added_funcs=None):
+          added_funcs=None, **kwargs):
     if e_orig:
         size = e_orig._wsize
     else:
@@ -274,7 +290,9 @@ def vm2pe(myjit, fname, libs=None, e_orig=None,
                 libbase, dllname = libs.fad2info[funcaddr]
                 libs.lib_get_add_func(libbase, dllname, addr)
 
-        new_dll = libs.gen_new_lib(mye, mye.virt.is_addr_in)
+        filter_import = kwargs.get(
+            'filter_import', lambda _, ad: mye.virt.is_addr_in(ad))
+        new_dll = libs.gen_new_lib(mye, filter_import)
     else:
         new_dll = {}
 
@@ -305,11 +323,26 @@ def vm2pe(myjit, fname, libs=None, e_orig=None,
 
 class libimp_pe(libimp):
 
+    def __init__(self, *args, **kwargs):
+        super(libimp_pe, self).__init__(*args, **kwargs)
+        # dependency -> redirector
+        self.created_redirected_imports = {}
+
     def add_export_lib(self, e, name):
+        if name in self.created_redirected_imports:
+            log.error("%r has previously been created due to redirect\
+            imports due to %r. Change the loading order.",
+                      name, self.created_redirected_imports[name])
+            raise RuntimeError('Bad import: loading previously created import')
+
         self.all_exported_lib.append(e)
         # will add real lib addresses to database
         if name in self.name2off:
             ad = self.name2off[name]
+            if e is not None and name in self.fake_libs:
+                log.error(
+                    "You are trying to load %r but it has been faked previously. Try loading this module earlier.", name)
+                raise RuntimeError("Bad import")
         else:
             log.debug('new lib %s', name)
             ad = e.NThdr.ImageBase
@@ -332,8 +365,6 @@ class libimp_pe(libimp):
                 ret = is_redirected_export(e, ad)
                 if ret:
                     exp_dname, exp_fname = ret
-                    # log.debug('export redirection %s' % imp_ord_or_name)
-                    # log.debug('source %s %s' % (exp_dname, exp_fname))
                     exp_dname = exp_dname + '.dll'
                     exp_dname = exp_dname.lower()
                     # if dll auto refes in redirection
@@ -343,17 +374,21 @@ class libimp_pe(libimp):
                             # schedule func
                             todo = [(imp_ord_or_name, ad)] + todo
                             continue
-                    elif not exp_dname in self.name2off:
-                        raise ValueError('load %r first' % exp_dname)
+                    else:
+                        # import redirected lib from non loaded dll
+                        if not exp_dname in self.name2off:
+                            self.created_redirected_imports.setdefault(
+                                exp_dname, set()).add(name)
+
+                        # Ensure import entry is created
+                        new_lib_base = self.lib_get_add_base(exp_dname)
+                        # Ensure function entry is created
+                        _ = self.lib_get_add_func(new_lib_base, exp_fname)
+
                     c_name = canon_libname_libfunc(exp_dname, exp_fname)
                     libad_tmp = self.name2off[exp_dname]
                     ad = self.lib_imp2ad[libad_tmp][exp_fname]
-                    # log.debug('%s' % hex(ad))
-                # if not imp_ord_or_name in self.lib_imp2dstad[libad]:
-                #    self.lib_imp2dstad[libad][imp_ord_or_name] = set()
-                # self.lib_imp2dstad[libad][imp_ord_or_name].add(dst_ad)
 
-                # log.debug('new imp %s %s' % (imp_ord_or_name, hex(ad)))
                 self.lib_imp2ad[libad][imp_ord_or_name] = ad
 
                 name_inv = dict([(x[1], x[0]) for x in self.name2off.items()])
@@ -362,10 +397,10 @@ class libimp_pe(libimp):
                 self.fad2cname[ad] = c_name
                 self.fad2info[ad] = libad, imp_ord_or_name
 
-    def gen_new_lib(self, target_pe, flt=lambda _: True):
+    def gen_new_lib(self, target_pe, filter_import=lambda peobj, ad: True, **kwargs):
         """Gen a new DirImport description
         @target_pe: PE instance
-        @flt: (boolean f(address)) restrict addresses to keep
+        @filter_import: (boolean f(pe, address)) restrict addresses to keep
         """
 
         new_lib = []
@@ -377,8 +412,9 @@ class libimp_pe(libimp):
             for func_name, dst_addresses in self.lib_imp2dstad[ad].items():
                 out_ads.update({addr: func_name for addr in dst_addresses})
 
-            # Filter available addresses according to @flt
-            all_ads = [addr for addr in out_ads.keys() if flt(addr)]
+            # Filter available addresses according to @filter_import
+            all_ads = [
+                addr for addr in out_ads.keys() if filter_import(target_pe, addr)]
             log.debug('ads: %s', map(hex, all_ads))
             if not all_ads:
                 continue
@@ -416,6 +452,67 @@ class libimp_pe(libimp):
 
         return new_lib
 
+
+def vm_load_pe_and_dependencies(vm, fname, name2module, runtime_lib,
+                                lib_path_base, **kwargs):
+    """Load a binary and all its dependencies. Returns a dictionnary containing
+    the association between binaries names and it's pe object
+
+    @vm: virtual memory manager instance
+    @fname: full path of the binary
+    @name2module: dict containing association between name and pe
+    object. Updated.
+    @runtime_lib: libimp instance
+    @lib_path_base: directory of the libraries containing dependencies
+
+    """
+
+    todo = [(fname, fname, 0)]
+    dependencies = []
+    weight2name = {}
+    done = set()
+
+    # Walk dependencies recursively
+    while todo:
+        name, fname, weight = todo.pop()
+        if name in done:
+            continue
+        done.add(name)
+        weight2name.setdefault(weight, set()).add(name)
+        if name in name2module:
+            pe_obj = name2module[name]
+        else:
+            try:
+                with open(fname) as fstream:
+                    log.info('Loading module name %r', fname)
+                    pe_obj = vm_load_pe(vm, fstream.read(), **kwargs)
+            except IOError:
+                log.error('Cannot open %s' % fname)
+                name2module[name] = None
+                continue
+            name2module[name] = pe_obj
+
+        new_dependencies = get_pe_dependencies(pe_obj)
+        todo += [(name, os.path.join(lib_path_base, name), weight - 1)
+                 for name in new_dependencies]
+
+    ordered_modules = sorted(weight2name.items())
+    for _, modules in ordered_modules:
+        for name in modules:
+            pe_obj = name2module[name]
+            if pe_obj is None:
+                continue
+            # Fix imports
+            if pe_obj.DirExport:
+                runtime_lib.add_export_lib(pe_obj, name)
+
+    for pe_obj in name2module.itervalues():
+        if pe_obj is None:
+            continue
+        preload_pe(vm, pe_obj, runtime_lib, patch_vm_imp=True)
+
+    return name2module
+
 # machine -> arch
 PE_machine = {0x14c: "x86_32",
               0x8664: "x86_64",
diff --git a/miasm2/jitter/loader/utils.py b/miasm2/jitter/loader/utils.py
index a6a19cb3..83d1a796 100644
--- a/miasm2/jitter/loader/utils.py
+++ b/miasm2/jitter/loader/utils.py
@@ -4,7 +4,7 @@ log = logging.getLogger('loader_common')
 hnd = logging.StreamHandler()
 hnd.setFormatter(logging.Formatter("[%(levelname)s]: %(message)s"))
 log.addHandler(hnd)
-log.setLevel(logging.CRITICAL)
+log.setLevel(logging.INFO)
 
 
 def canon_libname_libfunc(libname, libfunc):
@@ -15,7 +15,7 @@ def canon_libname_libfunc(libname, libfunc):
         return str(dn), libfunc
 
 
-class libimp:
+class libimp(object):
 
     def __init__(self, lib_base_ad=0x71111000, **kargs):
         self.name2off = {}
@@ -26,6 +26,7 @@ class libimp:
         self.fad2cname = {}
         self.fad2info = {}
         self.all_exported_lib = []
+        self.fake_libs = set()
 
     def lib_get_add_base(self, name):
         name = name.lower().strip(' ')
@@ -38,7 +39,8 @@ class libimp:
             ad = self.name2off[name]
         else:
             ad = self.libbase_ad
-            log.debug('new lib %s 0x%x', name, ad)
+            log.warning("Create dummy entry for %r", name)
+            self.fake_libs.add(name)
             self.name2off[name] = ad
             self.libbase2lastad[ad] = ad + 0x1
             self.lib_imp2ad[ad] = {}
diff --git a/miasm2/jitter/vm_mngr.c b/miasm2/jitter/vm_mngr.c
index 3597ae4f..b86bee1a 100644
--- a/miasm2/jitter/vm_mngr.c
+++ b/miasm2/jitter/vm_mngr.c
@@ -32,13 +32,6 @@
 
 
 
-/*
-struct memory_page_list_head memory_page_pool;
-struct code_bloc_list_head code_bloc_pool;
-
-struct memory_breakpoint_info_head memory_breakpoint_pool;
-*/
-
 /****************memory manager**************/
 
 
@@ -83,68 +76,50 @@ void print_val(uint64_t base, uint64_t addr)
 	fprintf(stderr, "addr 0x%"PRIX64" val 0x%"PRIX64"\n", addr-base, *ptr);
 }
 
-
-int is_mem_mapped(vm_mngr_t* vm_mngr, uint64_t ad)
+inline int midpoint(int imin, int imax)
 {
-	struct memory_page_node * mpn;
-	/*
-	mpn = memory_page_pool_tab[ad>>MEMORY_PAGE_POOL_MASK_BIT];
-	if ( mpn && (mpn->ad <= ad) && (ad < mpn->ad + mpn->size))
-		return 1;
-	*/
-	LIST_FOREACH(mpn, &vm_mngr->memory_page_pool, next){
-		if ((mpn->ad <= ad)  && (ad <mpn->ad + mpn->size))
-			return 1;
-	}
-
-	return 0;
+	return (imin + imax) / 2;
 }
 
 
-/* return the address base of the memory page
-   containing addr
-*/
-uint64_t get_mem_base_addr(vm_mngr_t* vm_mngr, uint64_t ad, uint64_t *addr_base)
+int find_page_node(struct memory_page_node * array, uint64_t key, int imin, int imax)
 {
-	struct memory_page_node * mpn;
-	/*
-	mpn = memory_page_pool_tab[ad>>MEMORY_PAGE_POOL_MASK_BIT];
-	if ( mpn && (mpn->ad <= ad) && (ad < mpn->ad + mpn->size)){
-		*addr_base = mpn->ad;
-		return 1;
-	}
-	*/
-	LIST_FOREACH(mpn, &vm_mngr->memory_page_pool, next){
-		if ((mpn->ad <= ad)  && (ad <mpn->ad + mpn->size)) {
-			*addr_base = mpn->ad;
-			return 1;
-		}
+	// continue searching while [imin,imax] is not empty
+	while (imin <= imax) {
+		// calculate the midpoint for roughly equal partition
+		int imid = midpoint(imin, imax);
+		if(array[imid].ad <= key && key < array[imid].ad + array[imid].size)
+			// key found at index imid
+			return imid;
+		// determine which subarray to search
+		else if (array[imid].ad < key)
+			// change min index to search upper subarray
+			imin = imid + 1;
+		else
+			// change max index to search lower subarray
+			imax = imid - 1;
 	}
-	return 0;
+	// key was not found
+	return -1;
 }
 
 struct memory_page_node * get_memory_page_from_address(vm_mngr_t* vm_mngr, uint64_t ad)
 {
 	struct memory_page_node * mpn;
-#if 0
-	mpn = memory_page_pool_tab[ad>>MEMORY_PAGE_POOL_MASK_BIT];
-	if ( mpn && (mpn->ad <= ad) && (ad < mpn->ad + mpn->size))
-		return mpn;
-
-	fprintf(stderr, "WARNING: address 0x%"PRIX64" is not mapped in virtual memory:\n", ad);
-	vm_mngr->exception_flags |= EXCEPT_ACCESS_VIOL;
-
-	return NULL;
-#else
+	int i;
 
-	LIST_FOREACH(mpn, &vm_mngr->memory_page_pool, next){
+	i = find_page_node(vm_mngr->memory_pages_array,
+			   ad,
+			   0,
+			   vm_mngr->memory_pages_number);
+	if (i >= 0) {
+		mpn = &vm_mngr->memory_pages_array[i];
 		if ((mpn->ad <= ad) && (ad < mpn->ad + mpn->size))
 			return mpn;
 	}
 	fprintf(stderr, "WARNING: address 0x%"PRIX64" is not mapped in virtual memory:\n", ad);
 	vm_mngr->exception_flags |= EXCEPT_ACCESS_VIOL;
 	return NULL;
-#endif
 }
 
 
@@ -168,7 +143,7 @@ static uint64_t memory_page_read(vm_mngr_t* vm_mngr, unsigned int my_size, uint6
 		return 0;
 	}
 
-	/* check read breakpoint*/
+	/* check read breakpoint */
 	LIST_FOREACH(b, &vm_mngr->memory_breakpoint_pool, next){
 		if ((b->access & BREAKPOINT_READ) == 0)
 			continue;
@@ -566,28 +541,7 @@ int shift_right_arith(unsigned int size, int a, unsigned int b)
 		    exit(0);
     }
 }
-/*
-int shift_right_arith_08(int a, unsigned int b)
-{
-	char i8_a;
-	i8_a = a;
-	return (i8_a >> b)&0xff;
-}
 
-int shift_right_arith_16(int a, unsigned int b)
-{
-	short i16_a;
-	i16_a = a;
-	return (i16_a >> b)&0xffff;
-}
-
-int shift_right_arith_32(int a, unsigned int b)
-{
-	int i32_a;
-	i32_a = a;
-	return (i32_a >> b)&0xffffffff;
-}
-*/
 uint64_t shift_right_logic(uint64_t size,
 			   uint64_t a, uint64_t b)
 {
@@ -609,28 +563,6 @@ uint64_t shift_right_logic(uint64_t size,
 		    exit(0);
     }
 }
-/*
-int shift_right_logic_08(unsigned int a, unsigned int b)
-{
-	unsigned char u8_a;
-	u8_a = a;
-	return (u8_a >> b)&0xff;
-}
-
-int shift_right_logic_16(unsigned int a, unsigned int b)
-{
-	unsigned short u16_a;
-	u16_a = a;
-	return (u16_a >> b)&0xffff;
-}
-
-int shift_right_logic_32(unsigned int a, unsigned int b)
-{
-	unsigned int u32_a;
-	u32_a = a;
-	return (u32_a >> b)&0xffffffff;
-}
-*/
 
 uint64_t shift_left_logic(uint64_t size, uint64_t a, uint64_t b)
 {
@@ -648,22 +580,6 @@ uint64_t shift_left_logic(uint64_t size, uint64_t a, uint64_t b)
 		    exit(0);
     }
 }
-/*
-int shift_left_logic_O8(unsigned int a, unsigned int b)
-{
-	return (a<<b)&0xff;
-}
-
-int shift_left_logic_16(unsigned int a, unsigned int b)
-{
-	return (a<<b)&0xffff;
-}
-
-int shift_left_logic_32(unsigned int a, unsigned int b)
-{
-	return (a<<b)&0xffffffff;
-}
-*/
 
 unsigned int mul_lo_op(unsigned int size, unsigned int a, unsigned int b)
 {
@@ -748,39 +664,6 @@ unsigned int umul16_hi(unsigned short a, unsigned short b)
 	return (c>>16) & 0xffff;
 }
 
-
-
-
-unsigned int div_op(unsigned int size, unsigned int a, unsigned int b, unsigned int c)
-{
-    int64_t num;
-    if (c == 0)
-    {
-	    //vmmngr.exception_flags |= EXCEPT_INT_DIV_BY_ZERO;
-	    return 0;
-    }
-    num = ((int64_t)a << size) + b;
-    num/=(int64_t)c;
-    return num;
-}
-
-
-unsigned int rem_op(unsigned int size, unsigned int a, unsigned int b, unsigned int c)
-{
-    int64_t num;
-
-    if (c == 0)
-    {
-	    //vmmngr.exception_flags |= EXCEPT_INT_DIV_BY_ZERO;
-	    return 0;
-    }
-
-    num = ((int64_t)a << size) + b;
-    num = (int64_t)num-c*(num/c);
-    return num;
-}
-
-
 uint64_t rot_left(uint64_t size, uint64_t a, uint64_t b)
 {
     uint64_t tmp;
@@ -1450,10 +1333,9 @@ void dump_code_bloc_pool(vm_mngr_t* vm_mngr)
 
 void init_memory_page_pool(vm_mngr_t* vm_mngr)
 {
-	unsigned int i;
-	LIST_INIT(&vm_mngr->memory_page_pool);
-	for (i=0;i<MAX_MEMORY_PAGE_POOL_TAB; i++)
-		vm_mngr->memory_page_pool_tab[i] = NULL;
+
+	vm_mngr->memory_pages_number = 0;
+	vm_mngr->memory_pages_array = NULL;
 }
 
 void init_code_bloc_pool(vm_mngr_t* vm_mngr)
@@ -1471,18 +1353,8 @@ void init_memory_breakpoint(vm_mngr_t* vm_mngr)
 
 void reset_memory_page_pool(vm_mngr_t* vm_mngr)
 {
-	struct memory_page_node * mpn;
-	unsigned int i;
-
-	while (!LIST_EMPTY(&vm_mngr->memory_page_pool)) {
-		mpn = LIST_FIRST(&vm_mngr->memory_page_pool);
-		LIST_REMOVE(mpn, next);
-		free(mpn->ad_hp);
-		free(mpn);
-	}
-	for (i=0;i<MAX_MEMORY_PAGE_POOL_TAB; i++)
-		vm_mngr->memory_page_pool_tab[i] = NULL;
-
+	free(vm_mngr->memory_pages_array);
+	vm_mngr->memory_pages_number = 0;
 }
 
 
@@ -1513,21 +1385,14 @@ void reset_memory_breakpoint(vm_mngr_t* vm_mngr)
 
 }
 
-
+/* We don't use dichotomy here for the insertion */
 int is_mpn_in_tab(vm_mngr_t* vm_mngr, struct memory_page_node* mpn_a)
 {
 	struct memory_page_node * mpn;
+	int i;
 
-	/*
-	for (i=mpn_a->ad >> MEMORY_PAGE_POOL_MASK_BIT;
-	     i<(mpn_a->ad + mpn_a->size + PAGE_SIZE - 1)>>MEMORY_PAGE_POOL_MASK_BIT;
-	     i++){
-		if (memory_page_pool_tab[i] !=NULL){
-			return 1;
-		}
-	}
-	*/
-	LIST_FOREACH(mpn, &vm_mngr->memory_page_pool, next){
+	for (i=0;i<vm_mngr->memory_pages_number; i++) {
+		mpn = &vm_mngr->memory_pages_array[i];
 		if (mpn->ad >= mpn_a->ad + mpn_a->size)
 			continue;
 		if (mpn->ad + mpn->size  <= mpn_a->ad)
@@ -1544,54 +1409,41 @@ int is_mpn_in_tab(vm_mngr_t* vm_mngr, struct memory_page_node* mpn_a)
 	return 0;
 }
 
-void insert_mpn_in_tab(struct memory_page_node* mpn_a)
-{
-	/*
-	for (i=mpn_a->ad >> MEMORY_PAGE_POOL_MASK_BIT;
-	     i<(mpn_a->ad + mpn_a->size + PAGE_SIZE - 1)>>MEMORY_PAGE_POOL_MASK_BIT;
-	     i++){
-		if (memory_page_pool_tab[i] !=NULL){
-			fprintf(stderr, "known page in tab\n");
-			exit(1);
-		}
-		memory_page_pool_tab[i] = mpn_a;
-	}
-	*/
-
-}
 
+/* We don't use dichotomy here for the insertion */
 void add_memory_page(vm_mngr_t* vm_mngr, struct memory_page_node* mpn_a)
 {
 	struct memory_page_node * mpn;
-	struct memory_page_node * lmpn;
+	int i;
 
-	if (LIST_EMPTY(&vm_mngr->memory_page_pool)){
-		LIST_INSERT_HEAD(&vm_mngr->memory_page_pool, mpn_a, next);
-		insert_mpn_in_tab(mpn_a);
-		return;
-	}
-	LIST_FOREACH(mpn, &vm_mngr->memory_page_pool, next){
-		lmpn = mpn;
+	for (i=0; i < vm_mngr->memory_pages_number; i++) {
+		mpn = &vm_mngr->memory_pages_array[i];
 		if (mpn->ad < mpn_a->ad)
 			continue;
-		LIST_INSERT_BEFORE(mpn, mpn_a, next);
-		insert_mpn_in_tab(mpn_a);
-		return;
+		break;
 	}
-	LIST_INSERT_AFTER(lmpn, mpn_a, next);
-	insert_mpn_in_tab(mpn_a);
+	vm_mngr->memory_pages_array = realloc(vm_mngr->memory_pages_array,
+					      sizeof(struct memory_page_node) *
+					      (vm_mngr->memory_pages_number+1));
+
+	memmove(&vm_mngr->memory_pages_array[i+1],
+		&vm_mngr->memory_pages_array[i],
+		sizeof(struct memory_page_node) * (vm_mngr->memory_pages_number - i)
+		);
+
+	vm_mngr->memory_pages_array[i] = *mpn_a;
+	vm_mngr->memory_pages_number ++;
 
 }
 
-/*
-   Return a char* representing the repr of vm_mngr_t object
-*/
+/* Return a char* representing the repr of vm_mngr_t object */
 char* dump(vm_mngr_t* vm_mngr)
 {
 	char buf[100];
 	int length;
 	int total_len = 0;
 	char *buf_final;
+	int i;
 	struct memory_page_node * mpn;
 
 	buf_final = malloc(1);
@@ -1600,8 +1452,9 @@ char* dump(vm_mngr_t* vm_mngr)
 		exit(0);
 	}
 	buf_final[0] = '\x00';
-	LIST_FOREACH(mpn, &vm_mngr->memory_page_pool, next){
 
+	for (i=0; i< vm_mngr->memory_pages_number; i++) {
+		mpn = &vm_mngr->memory_pages_array[i];
 		length = snprintf(buf, sizeof(buf),
 				  "ad 0x%"PRIX64" size 0x%"PRIX64" %c%c%c\n",
 				  (uint64_t)mpn->ad,
@@ -1664,59 +1517,6 @@ void remove_memory_breakpoint(vm_mngr_t* vm_mngr, uint64_t ad, unsigned int acce
 }
 
 
-
-
-
-
-
-unsigned int get_memory_page_next(vm_mngr_t* vm_mngr, unsigned int n_ad)
-{
-	struct memory_page_node * mpn;
-	uint64_t ad = 0;
-
-	LIST_FOREACH(mpn, &vm_mngr->memory_page_pool, next){
-		if (mpn->ad < n_ad)
-			continue;
-
-		if (ad == 0 || mpn->ad <ad)
-			ad = mpn->ad;
-	}
-	return ad;
-}
-
-
-#if 0
-unsigned int get_memory_page_from_min_ad(unsigned int size)
-{
-	struct memory_page_node * mpn;
-	unsigned int c_ad ;
-	unsigned int min_ad = min_page_ad;
-	int end = 0;
-	/* first, find free min ad */
-	while (!end){
-		end = 1;
-		LIST_FOREACH(mpn, &memory_page_pool, next){
-			c_ad = (mpn->ad + mpn->size+0x1000)&0xfffff000;
-			if (c_ad <= min_ad)
-				continue;
-			if (mpn->ad <= min_ad){
-				min_ad = c_ad;
-				end = 0;
-				break;
-			}
-			if (mpn->ad - min_ad < size){
-				min_ad = c_ad;
-				end = 0;
-				break;
-			}
-		}
-	}
-	return min_ad;
- }
-#endif
-
-
-
 /********************************************/
 
 void hexdump(char* m, unsigned int l)
@@ -1759,40 +1559,6 @@ void hexdump(char* m, unsigned int l)
 }
 
 
-
-
-unsigned int access_segment(unsigned int d)
-{
-	// XXX TODO
-	printf("access segment %X\n", d);
-	return 0;
-}
-unsigned int access_segment_ok(unsigned int d)
-{
-	// XXX TODO
-	printf("access segment ok %X\n", d);
-	return 0;
-}
-
-unsigned int load_segment_limit(unsigned int d)
-{
-	// XXX TODO
-	printf("load segment limit %X\n", d);
-	return 0;
-}
-unsigned int load_segment_limit_ok(unsigned int d)
-{
-	// XXX TODO
-	printf("load segment limit ok %X\n", d);
-	return 0;
-}
-
-unsigned int load_tr_segment_selector(unsigned int d)
-{
-	// XXX TODO
-	return 0;
-}
-
 // Return vm_mngr's exception flag value
 uint64_t get_exception_flag(vm_mngr_t* vm_mngr)
 {
diff --git a/miasm2/jitter/vm_mngr.h b/miasm2/jitter/vm_mngr.h
index f5895e12..02b5de73 100644
--- a/miasm2/jitter/vm_mngr.h
+++ b/miasm2/jitter/vm_mngr.h
@@ -49,7 +49,6 @@
 
 
 
-LIST_HEAD(memory_page_list_head, memory_page_node);
 LIST_HEAD(code_bloc_list_head, code_bloc_node);
 LIST_HEAD(memory_breakpoint_info_head, memory_breakpoint_info);
 
@@ -65,13 +64,23 @@ LIST_HEAD(memory_breakpoint_info_head, memory_breakpoint_info);
 #define VM_BIG_ENDIAN 1
 #define VM_LITTLE_ENDIAN 2
 
+
+struct memory_page_node {
+	uint64_t ad;
+	uint64_t size;
+	uint64_t access;
+	void* ad_hp;
+};
+
+
+
 typedef struct {
 	int sex;
-	struct memory_page_list_head memory_page_pool;
 	struct code_bloc_list_head code_bloc_pool;
 	struct memory_breakpoint_info_head memory_breakpoint_pool;
 
-	struct memory_page_node *memory_page_pool_tab[MAX_MEMORY_PAGE_POOL_TAB];
+	int memory_pages_number;
+	struct memory_page_node* memory_pages_array;
 
 	unsigned int *code_addr_tab;
 	unsigned int code_bloc_pool_ad_min;
@@ -93,16 +102,6 @@ typedef struct {
 
 //extern vm_mngr_t vmmngr;
 
-struct memory_page_node {
-	uint64_t ad;
-	uint64_t size;
-	uint64_t access;
-	void* ad_hp;
-	LIST_ENTRY(memory_page_node)   next;
-};
-
-
-
 struct code_bloc_node {
 	uint64_t ad_start;
 	uint64_t ad_stop;
@@ -183,11 +182,6 @@ int shift_right_arith(unsigned int size, int a, unsigned int b);
 
 uint64_t shift_right_logic(uint64_t size, uint64_t a, uint64_t b);
 uint64_t shift_left_logic(uint64_t size, uint64_t a, uint64_t b);
-/*
-int shift_left_logic_08(unsigned int a, unsigned int b);
-int shift_left_logic_16(unsigned int a, unsigned int b);
-int shift_left_logic_32(unsigned int a, unsigned int b);
-*/
 unsigned int mul_lo_op(unsigned int size, unsigned int a, unsigned int b);
 unsigned int mul_hi_op(unsigned int size, unsigned int a, unsigned int b);
 unsigned int imul_lo_op_08(char a, char b);
@@ -202,8 +196,6 @@ 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);
 uint64_t rot_left(uint64_t size, uint64_t a, uint64_t b);
 uint64_t rot_right(uint64_t size, uint64_t a, uint64_t b);
 unsigned int rcl_rez_op(unsigned int size, unsigned int a, unsigned int b, unsigned int cf);
@@ -261,21 +253,6 @@ unsigned int rcl_rez_op(unsigned int size, unsigned int a, unsigned int b, unsig
 	    }
 
 
-//PyObject* _vm_push_uint32_t(PyObject *item);
-//PyObject* _vm_pop_uint32_t(void);
-////PyObject* _vm_put_str(PyObject *item);
-//PyObject* _vm_set_mem(PyObject *item, PyObject *item_str);
-//PyObject* _vm_set_mem_access(PyObject *addr, PyObject *access);
-//PyObject* _vm_get_str(PyObject *item, PyObject *item_len);
-//PyObject* _vm_add_memory_page(PyObject *item, PyObject *access, PyObject *item_str);
-//PyObject* _vm_add_code_bloc(PyObject *item1, PyObject *item2);//, PyObject *item3);
-//PyObject* _call_pyfunc_from_globals(char* funcname);
-//PyObject* _call_pyfunc_from_eip(void);
-//
-//PyObject* call_pyfunc_from_globals(char* funcname);
-//
-//PyObject* _vm_get_gpreg(void);
-
 void hexdump(char* m, unsigned int l);
 
 struct code_bloc_node * create_code_bloc_node(uint64_t ad_start, uint64_t ad_stop);
@@ -302,20 +279,12 @@ void check_write_code_bloc(vm_mngr_t* vm_mngr, uint64_t my_size, uint64_t addr);
 
 char* dump(vm_mngr_t* vm_mngr);
 void dump_memory_breakpoint_pool(vm_mngr_t* vm_mngr);
-//PyObject* _vm_get_all_memory(void);
 PyObject* addr2BlocObj(vm_mngr_t* vm_mngr, uint64_t addr);
 
 
 
 
 /********************************************/
-
-//PyObject* _vm_get_cpu_state(void);
-//PyObject*  _vm_set_cpu_state(PyObject * s_cpustate);
-
-
-//void memory_page_write(unsigned int my_size, uint64_t ad, unsigned int src);
-//unsigned int memory_page_read(unsigned int my_size, uint64_t ad);
 unsigned int get_memory_page_max_address(void);
 unsigned int get_memory_page_max_user_address(void);
 
@@ -351,11 +320,8 @@ void func_loadlib_fake(void);
 void func_getproc_fake(void);
 
 
-//PyObject* _vm_exec_bloc(PyObject* my_eip, PyObject* known_blocs);
-
 unsigned int cpuid(unsigned int a, unsigned int reg_num);
 double int2double(unsigned int m);
-//PyObject* _vm_exec_blocs(PyObject* my_eip);
 
 double fadd(double a, double b);
 double fsub(double a, double b);
diff --git a/miasm2/jitter/vm_mngr_py.c b/miasm2/jitter/vm_mngr_py.c
index bb0a6207..0a22c397 100644
--- a/miasm2/jitter/vm_mngr_py.c
+++ b/miasm2/jitter/vm_mngr_py.c
@@ -66,44 +66,6 @@ PyObject* _vm_get_exception(unsigned int xcpt)
 		RAISE(PyExc_TypeError,"arg must be int");		\
 	}								\
 
-
-PyObject* vm_is_mem_mapped(VmMngr* self, PyObject* item)
-{
-	PyObject *addr;
-	uint64_t page_addr;
-	uint32_t ret;
-	if (!PyArg_ParseTuple(item, "O", &addr))
-		return NULL;
-
-	PyGetInt(addr, page_addr);
-
-	ret = is_mem_mapped(&self->vm_mngr, page_addr);
-	return PyInt_FromLong((long)ret);
-}
-
-
-
-PyObject* vm_get_mem_base_addr(VmMngr* self, PyObject* item)
-{
-	PyObject *addr;
-
-	uint64_t page_addr;
-	uint64_t addr_base;
-	unsigned int ret;
-
-	if (!PyArg_ParseTuple(item, "O", &addr))
-		return NULL;
-
-	PyGetInt(addr, page_addr);
-
-	ret = get_mem_base_addr(&self->vm_mngr, page_addr, &addr_base);
-	if (ret == 0){
-		Py_INCREF(Py_None);
-		return Py_None;
-	}
-	return PyLong_FromUnsignedLongLong((uint64_t)addr_base);
-}
-
 static void sig_alarm(int signo)
 {
 	global_vmmngr->vm_mngr.exception_flags |= BREAK_SIGALARM;
@@ -145,10 +107,6 @@ PyObject* vm_add_memory_page(VmMngr* self, PyObject* args)
 	buf_size = PyString_Size(item_str);
 	PyString_AsStringAndSize(item_str, &buf_data, &length);
 
-	/*
-	fprintf(stderr, "add page %"PRIX64" %"PRIX64" %"PRIX64"\n",
-		page_addr, buf_size, page_access);
-	*/
 	mpn = create_memory_page_node(page_addr, buf_size, page_access);
 	if (mpn == NULL)
 		RAISE(PyExc_TypeError,"cannot create page");
@@ -378,11 +336,13 @@ PyObject* vm_get_all_memory(VmMngr* self, PyObject* args)
 	struct memory_page_node * mpn;
 	PyObject *dict;
 	PyObject *dict2;
+	int i;
 
 
 	dict =  PyDict_New();
 
-	LIST_FOREACH(mpn, &self->vm_mngr.memory_page_pool, next){
+	for (i=0;i<self->vm_mngr.memory_pages_number; i++) {
+		mpn = &self->vm_mngr.memory_pages_array[i];
 
 		dict2 =  PyDict_New();
 
@@ -491,24 +451,6 @@ vm_set_little_endian(VmMngr *self, PyObject *value, void *closure)
 }
 
 
-
-/*
-PyObject* add_jitbloc(VmMngr* self, PyObject* args)
-{
-	PyObject* jitobj;
-
-	if (!PyArg_ParseTuple(args, "O", &addr2obj))
-		return NULL;
-
-	Py_INCREF(Py_None);
-	return Py_None;
-
-}
-*/
-
-
-
-
 static void
 VmMngr_dealloc(VmMngr* self)
 {