diff options
Diffstat (limited to 'miasm2/jitter/loader')
| -rw-r--r-- | miasm2/jitter/loader/elf.py | 20 | ||||
| -rw-r--r-- | miasm2/jitter/loader/pe.py | 83 | ||||
| -rw-r--r-- | miasm2/jitter/loader/utils.py | 31 |
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 |