about summary refs log tree commit diff stats
path: root/miasm2/jitter/loader
diff options
context:
space:
mode:
Diffstat (limited to 'miasm2/jitter/loader')
-rw-r--r--miasm2/jitter/loader/elf.py20
-rw-r--r--miasm2/jitter/loader/pe.py83
-rw-r--r--miasm2/jitter/loader/utils.py31
3 files changed, 85 insertions, 49 deletions
diff --git a/miasm2/jitter/loader/elf.py b/miasm2/jitter/loader/elf.py
index 17041372..1044fe73 100644
--- a/miasm2/jitter/loader/elf.py
+++ b/miasm2/jitter/loader/elf.py
@@ -1,6 +1,8 @@
 import struct
 from collections import defaultdict
 
+from future.utils import viewitems
+
 from elfesteem import cstruct
 from elfesteem import *
 import elfesteem.elf as elf_csts
@@ -23,7 +25,7 @@ def get_import_address_elf(e):
     for sh in e.sh:
         if not hasattr(sh, 'rel'):
             continue
-        for k, v in sh.rel.items():
+        for k, v in viewitems(sh.rel):
             import2addr[('xxx', k)].add(v.offset)
     return import2addr
 
@@ -32,7 +34,7 @@ def preload_elf(vm, e, runtime_lib, patch_vm_imp=True, loc_db=None):
     # XXX quick hack
     fa = get_import_address_elf(e)
     dyn_funcs = {}
-    for (libname, libfunc), ads in fa.items():
+    for (libname, libfunc), ads in viewitems(fa):
         # Quick hack - if a symbol is already known, do not stub it
         if loc_db and loc_db.get_name_location(libfunc) is not None:
             continue
@@ -66,7 +68,7 @@ def fill_loc_db_with_symbols(elf, loc_db, base_addr=0):
     symbol_sections = []
     for section_header in elf.sh:
         if hasattr(section_header, 'symbols'):
-            for name, sym in section_header.symbols.iteritems():
+            for name, sym in viewitems(section_header.symbols):
                 if not name or sym.value == 0:
                     continue
                 name = loc_db.find_free_name(name)
@@ -275,10 +277,14 @@ def vm_load_elf(vm, fdata, name="", base_addr=0, loc_db=None, apply_reloc=False,
         # -2: Trick to avoid merging 2 consecutive pages
         i += [(a_addr, b_addr - 2)]
     for a, b in i.intervals:
-        vm.add_memory_page(a, PAGE_READ | PAGE_WRITE, "\x00" * (b + 2 - a),
-                           repr(name))
-
-    for r_vaddr, data in all_data.items():
+        vm.add_memory_page(
+            a,
+            PAGE_READ | PAGE_WRITE,
+            b"\x00" * (b + 2 - a),
+            repr(name)
+        )
+
+    for r_vaddr, data in viewitems(all_data):
         vm.set_mem(r_vaddr, data)
 
     if loc_db is not None:
diff --git a/miasm2/jitter/loader/pe.py b/miasm2/jitter/loader/pe.py
index 176e0065..a8e6ec0d 100644
--- a/miasm2/jitter/loader/pe.py
+++ b/miasm2/jitter/loader/pe.py
@@ -1,8 +1,11 @@
+from builtins import map
 import os
 import struct
 import logging
 from collections import defaultdict
 
+from future.utils import viewitems, viewvalues
+
 from elfesteem import pe
 from elfesteem import cstruct
 from elfesteem import *
@@ -45,7 +48,8 @@ def get_import_address_pe(e):
                 funcname = imp
             # l = "    %2d %-16s" % (ii, repr(funcname))
             import2addr[(libname, funcname)].add(
-                e.rva2virt(s.firstthunk + e._wsize * ii / 8))
+                e.rva2virt(s.firstthunk + (e._wsize * ii) // 8)
+            )
     return import2addr
 
 
@@ -53,7 +57,7 @@ def preload_pe(vm, e, runtime_lib, patch_vm_imp=True):
     fa = get_import_address_pe(e)
     dyn_funcs = {}
     # log.debug('imported funcs: %s' % fa)
-    for (libname, libfunc), ads in fa.items():
+    for (libname, libfunc), ads in viewitems(fa):
         for ad in ads:
             ad_base_lib = runtime_lib.lib_get_add_base(libname)
             ad_libfunc = runtime_lib.lib_get_add_func(ad_base_lib, libfunc, ad)
@@ -81,7 +85,7 @@ def is_redirected_export(pe_obj, addr):
     addr_rva = pe_obj.virt2rva(addr)
     if not (export_dir.rva <= addr_rva < export_dir.rva + export_dir.size):
         return False
-    addr_end = pe_obj.virt.find('\x00', addr)
+    addr_end = pe_obj.virt.find(b'\x00', addr)
     data = pe_obj.virt.get(addr, addr_end)
 
     dllname, func_info = data.split('.', 1)
@@ -150,10 +154,16 @@ def vm_load_pe(vm, fdata, align_s=True, load_hdr=True, name="", **kargs):
             min_len = min(pe.SHList[0].addr, 0x1000)
 
             # Get and pad the pe_hdr
-            pe_hdr = pe.content[:hdr_len] + max(
-                0, (min_len - hdr_len)) * "\x00"
-            vm.add_memory_page(pe.NThdr.ImageBase, PAGE_READ | PAGE_WRITE,
-                               pe_hdr, "%r: PE Header" % name)
+            pe_hdr = (
+                pe.content[:hdr_len] +
+                max(0, (min_len - hdr_len)) * b"\x00"
+            )
+            vm.add_memory_page(
+                pe.NThdr.ImageBase,
+                PAGE_READ | PAGE_WRITE,
+                pe_hdr,
+                "%r: PE Header" % name
+            )
 
         # Align sections size
         if align_s:
@@ -173,13 +183,17 @@ def vm_load_pe(vm, fdata, align_s=True, load_hdr=True, name="", **kargs):
 
         # Pad sections with null bytes and map them
         for section in pe.SHList:
-            data = str(section.data)
-            data += "\x00" * (section.size - len(data))
+            data = bytes(section.data)
+            data += b"\x00" * (section.size - len(data))
             attrib = PAGE_READ
             if section.flags & 0x80000000:
                 attrib |= PAGE_WRITE
-            vm.add_memory_page(pe.rva2virt(section.addr), attrib, data,
-                               "%r: %r" % (name, section.name))
+            vm.add_memory_page(
+                pe.rva2virt(section.addr),
+                attrib,
+                data,
+                "%r: %r" % (name, section.name)
+            )
 
         return pe
 
@@ -209,15 +223,17 @@ def vm_load_pe(vm, fdata, align_s=True, load_hdr=True, name="", **kargs):
               (max_addr - min_addr))
 
     # Create only one big section containing the whole PE
-    vm.add_memory_page(min_addr,
-                       PAGE_READ | PAGE_WRITE,
-                       (max_addr - min_addr) * "\x00")
+    vm.add_memory_page(
+        min_addr,
+        PAGE_READ | PAGE_WRITE,
+        (max_addr - min_addr) * b"\x00"
+    )
 
     # Copy each sections content in memory
     for section in pe.SHList:
         log.debug('Map 0x%x bytes to 0x%x', len(section.data),
                   pe.rva2virt(section.addr))
-        vm.set_mem(pe.rva2virt(section.addr), str(section.data))
+        vm.set_mem(pe.rva2virt(section.addr), bytes(section.data))
 
     return pe
 
@@ -256,7 +272,7 @@ def vm_load_pe_libs(vm, libs_name, libs, lib_path_base, **kargs):
 
 def vm_fix_imports_pe_libs(lib_imgs, libs, lib_path_base,
                            patch_vm_imp=True, **kargs):
-    for e in lib_imgs.values():
+    for e in viewvalues(lib_imgs):
         preload_pe(e, libs, patch_vm_imp)
 
 
@@ -281,7 +297,7 @@ def vm2pe(myjit, fname, libs=None, e_orig=None,
 
     mye.NThdr.ImageBase = img_base
     all_mem = myjit.vm.get_all_memory()
-    addrs = all_mem.keys()
+    addrs = list(all_mem)
     addrs.sort()
     mye.Opthdr.AddressOfEntryPoint = mye.virt2rva(myjit.pc)
     first = True
@@ -303,8 +319,6 @@ def vm2pe(myjit, fname, libs=None, e_orig=None,
         first = False
     if libs:
         if added_funcs is not None:
-            # name_inv = dict([(x[1], x[0]) for x in libs.name2off.items()])
-
             for addr, funcaddr in added_funcs:
                 libbase, dllname = libs.fad2info[funcaddr]
                 libs.lib_get_add_func(libbase, dllname, addr)
@@ -323,7 +337,7 @@ def vm2pe(myjit, fname, libs=None, e_orig=None,
     log.debug('%r', mye.SHList)
     if e_orig:
         # resource
-        xx = str(mye)
+        xx = bytes(mye)
         mye.content = xx
         ad = e_orig.NThdr.optentries[pe.DIRECTORY_ENTRY_RESOURCE].rva
         size = e_orig.NThdr.optentries[pe.DIRECTORY_ENTRY_RESOURCE].size
@@ -333,10 +347,13 @@ def vm2pe(myjit, fname, libs=None, e_orig=None,
             mye.NThdr.optentries[pe.DIRECTORY_ENTRY_RESOURCE].size = size
             mye.DirRes = pe.DirRes.unpack(mye.img_rva, ad, mye)
             log.debug('%r', mye.DirRes)
-            s_res = mye.SHList.add_section(name="myres", rawsize=len(mye.DirRes))
+            s_res = mye.SHList.add_section(
+                name="myres",
+                rawsize=len(mye.DirRes)
+            )
             mye.DirRes.set_rva(s_res.addr)
     # generation
-    open(fname, 'wb').write(str(mye))
+    open(fname, 'wb').write(bytes(mye))
     return mye
 
 
@@ -408,7 +425,9 @@ class libimp_pe(libimp):
                     ad = self.lib_imp2ad[libad_tmp][exp_fname]
 
                 self.lib_imp2ad[libad][imp_ord_or_name] = ad
-                name_inv = dict([(x[1], x[0]) for x in self.name2off.items()])
+                name_inv = dict(
+                    (value, key) for key, value in viewitems(self.name2off)
+                )
                 c_name = canon_libname_libfunc(
                     name_inv[libad], imp_ord_or_name)
                 self.fad2cname[ad] = c_name
@@ -423,34 +442,36 @@ class libimp_pe(libimp):
         """
 
         new_lib = []
-        for lib_name, ad in self.name2off.items():
+        for lib_name, ad in viewitems(self.name2off):
             # Build an IMAGE_IMPORT_DESCRIPTOR
 
             # Get fixed addresses
             out_ads = dict()  # addr -> func_name
-            for func_name, dst_addresses in self.lib_imp2dstad[ad].items():
+            for func_name, dst_addresses in viewitems(self.lib_imp2dstad[ad]):
                 out_ads.update({addr: func_name for addr in dst_addresses})
 
             # Filter available addresses according to @filter_import
             all_ads = [
-                addr for addr in out_ads.keys() if filter_import(target_pe, addr)]
+                addr for addr in list(out_ads) if filter_import(target_pe, addr)
+            ]
+
             if not all_ads:
                 continue
 
             # Keep non-NULL elements
-            all_ads.sort()
+            all_ads.sort(key=str)
             for i, x in enumerate(all_ads):
                 if x not in [0,  None]:
                     break
             all_ads = all_ads[i:]
-            log.debug('ads: %s', map(hex, all_ads))
+            log.debug('ads: %s', list(map(hex, all_ads)))
 
             while all_ads:
                 # Find libname's Import Address Table
                 othunk = all_ads[0]
                 i = 0
                 while (i + 1 < len(all_ads) and
-                       all_ads[i] + target_pe._wsize / 8 == all_ads[i + 1]):
+                       all_ads[i] + target_pe._wsize // 8 == all_ads[i + 1]):
                     i += 1
                 # 'i + 1' is IAT's length
 
@@ -515,7 +536,7 @@ def vm_load_pe_and_dependencies(vm, fname, name2module, runtime_lib,
         todo += [(name, os.path.join(lib_path_base, name), weight - 1)
                  for name in new_dependencies]
 
-    ordered_modules = sorted(weight2name.items())
+    ordered_modules = sorted(viewitems(weight2name))
     for _, modules in ordered_modules:
         for name in modules:
             pe_obj = name2module[name]
@@ -525,7 +546,7 @@ def vm_load_pe_and_dependencies(vm, fname, name2module, runtime_lib,
             if pe_obj.DirExport:
                 runtime_lib.add_export_lib(pe_obj, name)
 
-    for pe_obj in name2module.itervalues():
+    for pe_obj in viewvalues(name2module):
         if pe_obj is None:
             continue
         preload_pe(vm, pe_obj, runtime_lib, patch_vm_imp=True)
diff --git a/miasm2/jitter/loader/utils.py b/miasm2/jitter/loader/utils.py
index a3a0ecd1..80e19310 100644
--- a/miasm2/jitter/loader/utils.py
+++ b/miasm2/jitter/loader/utils.py
@@ -1,5 +1,10 @@
+from builtins import int as int_types
 import logging
 
+from future.utils import viewitems, viewvalues
+
+from miasm2.core.utils import force_bytes
+
 log = logging.getLogger('loader_common')
 hnd = logging.StreamHandler()
 hnd.setFormatter(logging.Formatter("[%(levelname)s]: %(message)s"))
@@ -8,11 +13,13 @@ log.setLevel(logging.INFO)
 
 
 def canon_libname_libfunc(libname, libfunc):
-    dn = libname.split('.')[0]
-    if type(libfunc) == str:
-        return "%s_%s" % (dn, libfunc)
-    else:
+    libname = force_bytes(libname)
+    dn = libname.split(b'.')[0]
+    if isinstance(libfunc, int_types):
         return str(dn), libfunc
+    else:
+        libfunc = force_bytes(libfunc)
+        return b"%s_%s" % (dn, libfunc)
 
 
 class libimp(object):
@@ -30,10 +37,11 @@ class libimp(object):
         self.fake_libs = set()
 
     def lib_get_add_base(self, name):
-        name = name.lower().strip(' ')
-        if not "." in name:
+        name = force_bytes(name)
+        name = name.lower().strip(b' ')
+        if not b"." in name:
             log.debug('warning adding .dll to modulename')
-            name += '.dll'
+            name += b'.dll'
             log.debug(name)
 
         if name in self.name2off:
@@ -50,7 +58,7 @@ class libimp(object):
         return ad
 
     def lib_get_add_func(self, libad, imp_ord_or_name, dst_ad=None):
-        if not libad in self.name2off.values():
+        if not libad in viewvalues(self.name2off):
             raise ValueError('unknown lib base!', hex(libad))
 
         # test if not ordinatl
@@ -70,7 +78,9 @@ class libimp(object):
         self.libbase2lastad[libad] += 0x10  # arbitrary
         self.lib_imp2ad[libad][imp_ord_or_name] = ad
 
-        name_inv = dict([(x[1], x[0]) for x in self.name2off.items()])
+        name_inv = dict(
+            (value, key) for key, value in viewitems(self.name2off)
+        )
         c_name = canon_libname_libfunc(name_inv[libad], imp_ord_or_name)
         self.fad2cname[ad] = c_name
         self.cname2addr[c_name] = ad
@@ -79,8 +89,7 @@ class libimp(object):
 
     def check_dst_ad(self):
         for ad in self.lib_imp2dstad:
-            all_ads = self.lib_imp2dstad[ad].values()
-            all_ads.sort()
+            all_ads = sorted(viewvalues(self.lib_imp2dstad[ad]))
             for i, x in enumerate(all_ads[:-1]):
                 if x is None or all_ads[i + 1] is None:
                     return False