about summary refs log tree commit diff stats
path: root/src/miasm/jitter/loader/utils.py
diff options
context:
space:
mode:
authorTheofilos Augoustis <theofilos.augoustis@gmail.com>2025-10-14 09:09:29 +0000
committerTheofilos Augoustis <theofilos.augoustis@gmail.com>2025-10-14 09:09:29 +0000
commit579cf1d03fb932083e6317967d1613d5c2587fb6 (patch)
tree629f039935382a2a7391bce9253f6c9968159049 /src/miasm/jitter/loader/utils.py
parent51c15d3ea2e16d4fc5f0f01a3b9befc66b1f982e (diff)
downloadfocaccia-miasm-ta/nix.tar.gz
focaccia-miasm-ta/nix.zip
Convert to src-layout ta/nix
Diffstat (limited to 'src/miasm/jitter/loader/utils.py')
-rw-r--r--src/miasm/jitter/loader/utils.py100
1 files changed, 100 insertions, 0 deletions
diff --git a/src/miasm/jitter/loader/utils.py b/src/miasm/jitter/loader/utils.py
new file mode 100644
index 00000000..7f913d76
--- /dev/null
+++ b/src/miasm/jitter/loader/utils.py
@@ -0,0 +1,100 @@
+from builtins import int as int_types
+import logging
+
+from future.utils import viewitems, viewvalues
+from past.builtins import basestring
+
+log = logging.getLogger('loader_common')
+hnd = logging.StreamHandler()
+hnd.setFormatter(logging.Formatter("[%(levelname)-8s]: %(message)s"))
+log.addHandler(hnd)
+log.setLevel(logging.INFO)
+
+
+def canon_libname_libfunc(libname, libfunc):
+    assert isinstance(libname, basestring)
+    assert isinstance(libfunc, basestring) or isinstance(libfunc, int_types)
+    dn = libname.split('.')[0]
+    if isinstance(libfunc, int_types):
+        return str(dn), libfunc
+    else:
+        return "%s_%s" % (dn, libfunc)
+
+
+class libimp(object):
+
+    def __init__(self, lib_base_ad=0x71111000, **kargs):
+        self.name2off = {}
+        self.libbase2lastad = {}
+        self.libbase_ad = lib_base_ad
+        self.lib_imp2ad = {}
+        self.lib_imp2dstad = {}
+        self.fad2cname = {}
+        self.cname2addr = {}
+        self.fad2info = {}
+        self.all_exported_lib = []
+        self.fake_libs = set()
+
+    def lib_get_add_base(self, name):
+        assert isinstance(name, basestring)
+        name = name.lower().strip(' ')
+        if not "." in name:
+            log.warning('warning adding .dll to modulename')
+            name += '.dll'
+            log.warning(name)
+
+        if name in self.name2off:
+            ad = self.name2off[name]
+        else:
+            ad = self.libbase_ad
+            log.warning("Create dummy entry for %r", name)
+            self.fake_libs.add(name)
+            self.name2off[name] = ad
+            self.libbase2lastad[ad] = ad + 0x4
+            self.lib_imp2ad[ad] = {}
+            self.lib_imp2dstad[ad] = {}
+            self.libbase_ad += 0x1000
+        return ad
+
+    def lib_get_add_func(self, libad, imp_ord_or_name, dst_ad=None):
+        if not libad in viewvalues(self.name2off):
+            raise ValueError('unknown lib base!', hex(libad))
+
+        # test if not ordinatl
+        # if imp_ord_or_name >0x10000:
+        #    imp_ord_or_name = vm_get_str(imp_ord_or_name, 0x100)
+        #    imp_ord_or_name = imp_ord_or_name[:imp_ord_or_name.find('\x00')]
+
+        #[!] can have multiple dst ad
+        if not imp_ord_or_name in self.lib_imp2dstad[libad]:
+            self.lib_imp2dstad[libad][imp_ord_or_name] = set()
+        if dst_ad is not None:
+            self.lib_imp2dstad[libad][imp_ord_or_name].add(dst_ad)
+
+        if imp_ord_or_name in self.lib_imp2ad[libad]:
+            return self.lib_imp2ad[libad][imp_ord_or_name]
+        log.debug('new imp %s %s' % (imp_ord_or_name, dst_ad))
+        ad = self.libbase2lastad[libad]
+        self.libbase2lastad[libad] += 0x10  # arbitrary
+        self.lib_imp2ad[libad][imp_ord_or_name] = ad
+
+        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
+        self.fad2info[ad] = libad, imp_ord_or_name
+        return ad
+
+    def check_dst_ad(self):
+        for ad in self.lib_imp2dstad:
+            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
+                if x + 4 != all_ads[i + 1]:
+                    return False
+        return True
+
+