about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorCamille Mougey <commial@gmail.com>2014-12-09 17:11:27 +0100
committerCamille Mougey <commial@gmail.com>2014-12-09 17:11:27 +0100
commit3d309ba48a816dc3a634e90b40c5214c3f16dc09 (patch)
tree2871452552519201a754080e5fe96610ba4d6edc
parent80eadc44c0d287ba01919f05143a1c7dda745d34 (diff)
parent3d42eb7ae4ff21f143dcc6bb4ba52695119ebe1e (diff)
downloadmiasm-3d309ba48a816dc3a634e90b40c5214c3f16dc09.tar.gz
miasm-3d309ba48a816dc3a634e90b40c5214c3f16dc09.zip
Merge pull request #15 from serpilliere/fixes
Multiple Fix / Arm SMULL
-rw-r--r--miasm2/analysis/sandbox.py11
-rw-r--r--miasm2/arch/arm/arch.py20
-rw-r--r--miasm2/jitter/loader/elf.py5
-rw-r--r--miasm2/jitter/loader/pe.py115
-rw-r--r--miasm2/jitter/loader/utils.py110
-rw-r--r--test/arch/arm/arch.py5
6 files changed, 149 insertions, 117 deletions
diff --git a/miasm2/analysis/sandbox.py b/miasm2/analysis/sandbox.py
index d5435223..8676f373 100644
--- a/miasm2/analysis/sandbox.py
+++ b/miasm2/analysis/sandbox.py
@@ -159,12 +159,12 @@ class OS_Win(OS):
                ]
 
     def __init__(self, custom_methods, *args, **kwargs):
-        from miasm2.jitter.loader.pe import vm_load_pe, preload_pe
+        from miasm2.jitter.loader.pe import vm_load_pe, preload_pe, libimp_pe
 
         super(OS_Win, self).__init__(custom_methods, *args, **kwargs)
 
         # Import manager
-        libs = libimp()
+        libs = libimp_pe()
         self.libs = libs
         win_api_x86_32.winobjs.runtime_dll = libs
 
@@ -220,12 +220,12 @@ class OS_Win(OS):
 class OS_Linux(OS):
 
     def __init__(self, custom_methods, *args, **kwargs):
-        from miasm2.jitter.loader.elf import vm_load_elf, preload_elf
+        from miasm2.jitter.loader.elf import vm_load_elf, preload_elf, libimp_elf
 
         super(OS_Linux, self).__init__(custom_methods, *args, **kwargs)
 
         # Import manager
-        libs = libimp()
+        libs = libimp_elf()
         self.libs = libs
 
         elf = vm_load_elf(self.jitter.vm, self.fname)
@@ -237,10 +237,11 @@ class OS_Linux(OS):
 
 class OS_Linux_str(OS):
     def __init__(self, custom_methods, *args, **kwargs):
+        from miasm2.jitter.loader.elf import libimp_elf
         super(OS_Linux_str, self).__init__(custom_methods, *args, **kwargs)
 
         # Import manager
-        libs = libimp()
+        libs = libimp_elf()
         self.libs = libs
 
         data = open(self.fname).read()
diff --git a/miasm2/arch/arm/arch.py b/miasm2/arch/arm/arch.py
index 47016d6b..73b198ba 100644
--- a/miasm2/arch/arm/arch.py
+++ b/miasm2/arch/arm/arch.py
@@ -1142,6 +1142,8 @@ class arm_rlist(m_arg):
         for i in xrange(0x10):
             if 1 << i & v:
                 out.append(gpregs.expr[i])
+        if not out:
+            return False
         e = ExprOp('reglist', *out)
         if self.parent.sbit.value == 1:
             e = ExprOp('sbit', e)
@@ -1286,6 +1288,16 @@ offs_blx = bs(l=24, cls=(arm_offs_blx,), fname="offs")
 
 fix_cond = bs("1111", fname="cond")
 
+class mul_part_x(bs_mod_name):
+    prio = 5
+    mn_mod = ['B', 'T']
+
+class mul_part_y(bs_mod_name):
+    prio = 6
+    mn_mod = ['B', 'T']
+
+mul_x = mul_part_x(l=1, fname='x', mn_mod=['B', 'T'])
+mul_y = mul_part_y(l=1, fname='y', mn_mod=['B', 'T'])
 
 class arm_immed(m_arg):
     parser = deref
@@ -1453,6 +1465,8 @@ armop("data_mov",
 armop("data_test", [bs('00'), immop, bs_data_test_name, dumscc, rn, dumr, op2])
 armop("b", [bs('101'), lnk, offs])
 
+armop("smul", [bs('00010110'), rd, bs('0000'), rs, bs('1'), mul_y, mul_x, bs('0'), rm], [rd, rm, rs])
+
 # TODO TEST
 #armop("und", [bs('011'), imm20, bs('1'), imm4])
 armop("transfer", [bs('01'), immop, ppi, updown, trb, wback_no_t,
@@ -1751,6 +1765,8 @@ class armt_rlist(m_arg):
         for i in xrange(0x10):
             if 1 << i & v:
                 out.append(gpregs.expr[i])
+        if not out:
+            return False
         e = ExprOp('reglist', *out)
         self.expr = e
         return True
@@ -1791,6 +1807,8 @@ class armt_rlist_pclr(armt_rlist):
                 out += [regs_expr[14]]
             else:
                 out += [regs_expr[15]]
+        if not out:
+            return False
         e = ExprOp('reglist', *out)
         self.expr = e
         return True
@@ -2006,6 +2024,8 @@ class armt_gpreg_rm_shift_off(arm_reg):
 
     def decode(self, v):
         v = v & self.lmask
+        if v >= len(gpregs_nosppc.expr):
+            return False
         r = gpregs_nosppc.expr[v]
 
         i = int(self.parent.imm5_3.value) << 2
diff --git a/miasm2/jitter/loader/elf.py b/miasm2/jitter/loader/elf.py
index 9a81c4f7..528ff4f5 100644
--- a/miasm2/jitter/loader/elf.py
+++ b/miasm2/jitter/loader/elf.py
@@ -5,7 +5,7 @@ from elfesteem import pe
 from elfesteem import cstruct
 from elfesteem import *
 from miasm2.jitter.csts import *
-from utils import canon_libname_libfunc
+from utils import canon_libname_libfunc, libimp
 from miasm2.core.interval import interval
 
 import logging
@@ -78,3 +78,6 @@ def vm_load_elf(vm, fname, **kargs):
     for r_vaddr, data in all_data.items():
         vm.set_mem(r_vaddr, data)
     return e
+
+class libimp_elf(libimp):
+    pass
diff --git a/miasm2/jitter/loader/pe.py b/miasm2/jitter/loader/pe.py
index c0053f35..f492cba3 100644
--- a/miasm2/jitter/loader/pe.py
+++ b/miasm2/jitter/loader/pe.py
@@ -5,7 +5,7 @@ from elfesteem import pe
 from elfesteem import cstruct
 from elfesteem import *
 from miasm2.jitter.csts import *
-from utils import canon_libname_libfunc
+from utils import canon_libname_libfunc, libimp
 
 import logging
 
@@ -255,3 +255,116 @@ def vm2pe(myjit, fname, libs=None, e_orig=None,
     # generation
     open(fname, 'w').write(str(mye))
     return mye
+
+
+class libimp_pe(libimp):
+
+    def add_export_lib(self, e, name):
+        self.all_exported_lib.append(e)
+        # will add real lib addresses to database
+        if name in self.name2off:
+            ad = self.name2off[name]
+        else:
+            log.debug('new lib %s' % name)
+            ad = e.NThdr.ImageBase
+            libad = ad
+            self.name2off[name] = ad
+            self.libbase2lastad[ad] = ad + 0x1
+            self.lib_imp2ad[ad] = {}
+            self.lib_imp2dstad[ad] = {}
+            self.libbase_ad += 0x1000
+
+            ads = get_export_name_addr_list(e)
+            todo = ads
+            # done = []
+            while todo:
+                # for imp_ord_or_name, ad in ads:
+                imp_ord_or_name, ad = todo.pop()
+
+                # if export is a redirection, search redirected dll
+                # and get function real addr
+                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
+                    if exp_dname == name:
+                        libad_tmp = self.name2off[exp_dname]
+                        if not exp_fname in self.lib_imp2ad[libad_tmp]:
+                            # schedule func
+                            todo = [(imp_ord_or_name, ad)] + todo
+                            continue
+                    elif not exp_dname in self.name2off:
+                        raise ValueError('load %r first' % exp_dname)
+                    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()])
+                c_name = canon_libname_libfunc(
+                    name_inv[libad], imp_ord_or_name)
+                self.fad2cname[ad] = c_name
+                self.fad2info[ad] = libad, imp_ord_or_name
+
+    def gen_new_lib(self, target_pe, filter=lambda _: True):
+        """Gen a new DirImport description
+        @target_pe: PE instance
+        @filter: (boolean f(address)) restrict addresses to keep
+        """
+
+        new_lib = []
+        for lib_name, ad in self.name2off.items():
+            # 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():
+                out_ads.update({addr:func_name for addr in dst_addresses})
+
+            # Filter available addresses according to @filter
+            all_ads = [addr for addr in out_ads.keys() if filter(addr)]
+            log.debug('ads: %s' % map(hex, all_ads))
+            if not all_ads:
+                continue
+
+            # Keep non-NULL elements
+            all_ads.sort()
+            for i, x in enumerate(all_ads):
+                if x not in [0,  None]:
+                    break
+            all_ads = all_ads[i:]
+
+            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] + 4 == all_ads[i + 1]:
+                    i += 1
+                # 'i + 1' is IAT's length
+
+                # Effectively build an IMAGE_IMPORT_DESCRIPTOR
+                funcs = [out_ads[addr] for addr in all_ads[:i + 1]]
+                try:
+                    rva = target_pe.virt2rva(othunk)
+                except pe.InvalidOffset:
+                    pass
+                else:
+                    new_lib.append(({"name": lib_name,
+                                     "firstthunk": rva},
+                                    funcs)
+                                   )
+
+                # Update elements to handle
+                all_ads = all_ads[i + 1:]
+
+        return new_lib
diff --git a/miasm2/jitter/loader/utils.py b/miasm2/jitter/loader/utils.py
index de269f83..9305e713 100644
--- a/miasm2/jitter/loader/utils.py
+++ b/miasm2/jitter/loader/utils.py
@@ -84,114 +84,4 @@ class libimp:
                     return False
         return True
 
-    def add_export_lib(self, e, name):
-        self.all_exported_lib.append(e)
-        # will add real lib addresses to database
-        if name in self.name2off:
-            ad = self.name2off[name]
-        else:
-            log.debug('new lib %s' % name)
-            ad = e.NThdr.ImageBase
-            libad = ad
-            self.name2off[name] = ad
-            self.libbase2lastad[ad] = ad + 0x1
-            self.lib_imp2ad[ad] = {}
-            self.lib_imp2dstad[ad] = {}
-            self.libbase_ad += 0x1000
-
-            ads = get_export_name_addr_list(e)
-            todo = ads
-            # done = []
-            while todo:
-                # for imp_ord_or_name, ad in ads:
-                imp_ord_or_name, ad = todo.pop()
-
-                # if export is a redirection, search redirected dll
-                # and get function real addr
-                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
-                    if exp_dname == name:
-                        libad_tmp = self.name2off[exp_dname]
-                        if not exp_fname in self.lib_imp2ad[libad_tmp]:
-                            # schedule func
-                            todo = [(imp_ord_or_name, ad)] + todo
-                            continue
-                    elif not exp_dname in self.name2off:
-                        raise ValueError('load %r first' % exp_dname)
-                    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()])
-                c_name = canon_libname_libfunc(
-                    name_inv[libad], imp_ord_or_name)
-                self.fad2cname[ad] = c_name
-                self.fad2info[ad] = libad, imp_ord_or_name
-
-    def gen_new_lib(self, target_pe, filter=lambda _: True):
-        """Gen a new DirImport description
-        @target_pe: PE instance
-        @filter: (boolean f(address)) restrict addresses to keep
-        """
-
-        new_lib = []
-        for lib_name, ad in self.name2off.items():
-            # 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():
-                out_ads.update({addr:func_name for addr in dst_addresses})
-
-            # Filter available addresses according to @filter
-            all_ads = [addr for addr in out_ads.keys() if filter(addr)]
-            log.debug('ads: %s' % map(hex, all_ads))
-            if not all_ads:
-                continue
-
-            # Keep non-NULL elements
-            all_ads.sort()
-            for i, x in enumerate(all_ads):
-                if x not in [0,  None]:
-                    break
-            all_ads = all_ads[i:]
-
-            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] + 4 == all_ads[i + 1]:
-                    i += 1
-                # 'i + 1' is IAT's length
-
-                # Effectively build an IMAGE_IMPORT_DESCRIPTOR
-                funcs = [out_ads[addr] for addr in all_ads[:i + 1]]
-                try:
-                    rva = target_pe.virt2rva(othunk)
-                except pe.InvalidOffset:
-                    pass
-                else:
-                    new_lib.append(({"name": lib_name,
-                                     "firstthunk": rva},
-                                    funcs)
-                                   )
-
-                # Update elements to handle
-                all_ads = all_ads[i + 1:]
-
-        return new_lib
-
 
diff --git a/test/arch/arm/arch.py b/test/arch/arm/arch.py
index a66ba4cf..533b2052 100644
--- a/test/arch/arm/arch.py
+++ b/test/arch/arm/arch.py
@@ -196,6 +196,11 @@ reg_tests_arm = [
     ("C03E6440    SMLAL      R2, R0, R1, R0",
      "9120E0E0"),
 
+    ("00003904    SMULBB     R0, R0, R1",
+     "800160E1"),
+    ("00003904    SMULBT     R0, R0, R1",
+     "C00160E1"),
+
     ("C00CFA40    BLX        R12",
      "3CFF2FE1"),
     ("C010DE1C    BLX        0x1ECCEA",