about summary refs log tree commit diff stats
path: root/miasm/core
diff options
context:
space:
mode:
Diffstat (limited to 'miasm/core')
-rw-r--r--miasm/core/asmblock.py6
-rw-r--r--miasm/core/locationdb.py7
-rw-r--r--miasm/core/modint.py256
-rw-r--r--miasm/core/objc.py4
-rw-r--r--miasm/core/types.py2
-rw-r--r--miasm/core/utils.py3
6 files changed, 264 insertions, 14 deletions
diff --git a/miasm/core/asmblock.py b/miasm/core/asmblock.py
index f412de86..975f93c5 100644
--- a/miasm/core/asmblock.py
+++ b/miasm/core/asmblock.py
@@ -12,7 +12,6 @@ from future.utils import viewitems, viewvalues
 from miasm.expression.expression import ExprId, ExprInt, get_expr_locs
 from miasm.expression.expression import LocKey
 from miasm.expression.simplifications import expr_simp
-from miasm.expression.modint import moduint, modint
 from miasm.core.utils import Disasm_Exception, pck
 from miasm.core.graph import DiGraph, DiGraphSimplifier, MatchGraphJoker
 from miasm.core.interval import interval
@@ -26,10 +25,6 @@ log_asmblock.addHandler(console_handler)
 log_asmblock.setLevel(logging.WARNING)
 
 
-def is_int(a):
-    return isinstance(a, (modint, moduint, int_types))
-
-
 class AsmRaw(object):
 
     def __init__(self, raw=b""):
@@ -1168,6 +1163,7 @@ def asm_resolve_final(mnemo, asmcfg, loc_db, dst_interval=None):
             instruction_interval = interval([(offset, offset + instr.l - 1)])
             if not (instruction_interval & output_interval).empty:
                 raise RuntimeError("overlapping bytes %X" % int(offset))
+            output_interval = output_interval.union(instruction_interval)
             instr.offset = offset
             offset += instr.l
     return patches
diff --git a/miasm/core/locationdb.py b/miasm/core/locationdb.py
index dd336752..f950b48f 100644
--- a/miasm/core/locationdb.py
+++ b/miasm/core/locationdb.py
@@ -6,11 +6,6 @@ from future.utils import viewitems, viewvalues
 
 from miasm.core.utils import printable, force_bytes
 from miasm.expression.expression import LocKey, ExprLoc
-from miasm.expression.modint import moduint, modint
-
-
-def is_int(a):
-    return isinstance(a, (int_types, moduint, modint))
 
 
 class LocationDB(object):
@@ -246,7 +241,7 @@ class LocationDB(object):
 
         name = force_bytes(name)
         # Deprecation handling
-        if is_int(name):
+        if isinstance(name, int_types):
             assert offset is None or offset == name
             warnings.warn("Deprecated API: use 'add_location(offset=)' instead."
                           " An additional 'name=' can be provided to also "
diff --git a/miasm/core/modint.py b/miasm/core/modint.py
new file mode 100644
index 00000000..2ecefed1
--- /dev/null
+++ b/miasm/core/modint.py
@@ -0,0 +1,256 @@
+#-*- coding:utf-8 -*-
+
+from builtins import range
+from functools import total_ordering
+
+@total_ordering
+class moduint(object):
+
+    def __init__(self, arg):
+        self.arg = int(arg) % self.__class__.limit
+        assert(self.arg >= 0 and self.arg < self.__class__.limit)
+
+    def __repr__(self):
+        return self.__class__.__name__ + '(' + hex(self.arg) + ')'
+
+    def __hash__(self):
+        return hash(self.arg)
+
+    @classmethod
+    def maxcast(cls, c2):
+        c2 = c2.__class__
+        if cls.size > c2.size:
+            return cls
+        else:
+            return c2
+
+    def __eq__(self, y):
+        if isinstance(y, moduint):
+            return self.arg == y.arg
+        return self.arg == y
+
+    def __ne__(self, y):
+        # required Python 2.7.14
+        return not self == y
+
+    def __lt__(self, y):
+        if isinstance(y, moduint):
+            return self.arg < y.arg
+        return self.arg < y
+
+    def __add__(self, y):
+        if isinstance(y, moduint):
+            cls = self.maxcast(y)
+            return cls(self.arg + y.arg)
+        else:
+            return self.__class__(self.arg + y)
+
+    def __and__(self, y):
+        if isinstance(y, moduint):
+            cls = self.maxcast(y)
+            return cls(self.arg & y.arg)
+        else:
+            return self.__class__(self.arg & y)
+
+    def __div__(self, y):
+        # Python: 8 / -7 == -2 (C-like: -1)
+        # int(float) trick cannot be used, due to information loss
+        den = int(y)
+        num = int(self)
+        result_sign = 1 if (den * num) >= 0 else -1
+        cls = self.__class__
+        if isinstance(y, moduint):
+            cls = self.maxcast(y)
+        return (abs(num) // abs(den)) * result_sign
+
+    def __floordiv__(self, y):
+        return self.__div__(y)
+
+    def __int__(self):
+        return int(self.arg)
+
+    def __long__(self):
+        return int(self.arg)
+
+    def __index__(self):
+        return int(self.arg)
+
+    def __invert__(self):
+        return self.__class__(~self.arg)
+
+    def __lshift__(self, y):
+        if isinstance(y, moduint):
+            cls = self.maxcast(y)
+            return cls(self.arg << y.arg)
+        else:
+            return self.__class__(self.arg << y)
+
+    def __mod__(self, y):
+        # See __div__ for implementation choice
+        cls = self.__class__
+        if isinstance(y, moduint):
+            cls = self.maxcast(y)
+        return cls(self.arg - y * (self // y))
+
+    def __mul__(self, y):
+        if isinstance(y, moduint):
+            cls = self.maxcast(y)
+            return cls(self.arg * y.arg)
+        else:
+            return self.__class__(self.arg * y)
+
+    def __neg__(self):
+        return self.__class__(-self.arg)
+
+    def __or__(self, y):
+        if isinstance(y, moduint):
+            cls = self.maxcast(y)
+            return cls(self.arg | y.arg)
+        else:
+            return self.__class__(self.arg | y)
+
+    def __radd__(self, y):
+        return self.__add__(y)
+
+    def __rand__(self, y):
+        return self.__and__(y)
+
+    def __rdiv__(self, y):
+        if isinstance(y, moduint):
+            cls = self.maxcast(y)
+            return cls(y.arg // self.arg)
+        else:
+            return self.__class__(y // self.arg)
+
+    def __rfloordiv__(self, y):
+        return self.__rdiv__(y)
+
+    def __rlshift__(self, y):
+        if isinstance(y, moduint):
+            cls = self.maxcast(y)
+            return cls(y.arg << self.arg)
+        else:
+            return self.__class__(y << self.arg)
+
+    def __rmod__(self, y):
+        if isinstance(y, moduint):
+            cls = self.maxcast(y)
+            return cls(y.arg % self.arg)
+        else:
+            return self.__class__(y % self.arg)
+
+    def __rmul__(self, y):
+        return self.__mul__(y)
+
+    def __ror__(self, y):
+        return self.__or__(y)
+
+    def __rrshift__(self, y):
+        if isinstance(y, moduint):
+            cls = self.maxcast(y)
+            return cls(y.arg >> self.arg)
+        else:
+            return self.__class__(y >> self.arg)
+
+    def __rshift__(self, y):
+        if isinstance(y, moduint):
+            cls = self.maxcast(y)
+            return cls(self.arg >> y.arg)
+        else:
+            return self.__class__(self.arg >> y)
+
+    def __rsub__(self, y):
+        if isinstance(y, moduint):
+            cls = self.maxcast(y)
+            return cls(y.arg - self.arg)
+        else:
+            return self.__class__(y - self.arg)
+
+    def __rxor__(self, y):
+        return self.__xor__(y)
+
+    def __sub__(self, y):
+        if isinstance(y, moduint):
+            cls = self.maxcast(y)
+            return cls(self.arg - y.arg)
+        else:
+            return self.__class__(self.arg - y)
+
+    def __xor__(self, y):
+        if isinstance(y, moduint):
+            cls = self.maxcast(y)
+            return cls(self.arg ^ y.arg)
+        else:
+            return self.__class__(self.arg ^ y)
+
+    def __hex__(self):
+        return hex(self.arg)
+
+    def __abs__(self):
+        return abs(self.arg)
+
+    def __rpow__(self, v):
+        return v ** self.arg
+
+    def __pow__(self, v):
+        return self.__class__(self.arg ** v)
+
+
+class modint(moduint):
+
+    def __init__(self, arg):
+        if isinstance(arg, moduint):
+            arg = arg.arg
+        a = arg % self.__class__.limit
+        if a >= self.__class__.limit // 2:
+            a -= self.__class__.limit
+        self.arg = a
+        assert(
+            self.arg >= -self.__class__.limit // 2 and
+            self.arg < self.__class__.limit
+        )
+
+
+def is_modint(a):
+    return isinstance(a, moduint)
+
+
+mod_size2uint = {}
+mod_size2int = {}
+
+mod_uint2size = {}
+mod_int2size = {}
+
+def define_int(size):
+    """Build the 'modint' instance corresponding to size @size"""
+    global mod_size2int, mod_int2size
+
+    name = 'int%d' % size
+    cls = type(name, (modint,), {"size": size, "limit": 1 << size})
+    globals()[name] = cls
+    mod_size2int[size] = cls
+    mod_int2size[cls] = size
+    return cls
+
+def define_uint(size):
+    """Build the 'moduint' instance corresponding to size @size"""
+    global mod_size2uint, mod_uint2size
+
+    name = 'uint%d' % size
+    cls = type(name, (moduint,), {"size": size, "limit": 1 << size})
+    globals()[name] = cls
+    mod_size2uint[size] = cls
+    mod_uint2size[cls] = size
+    return cls
+
+def define_common_int():
+    "Define common int"
+    common_int = range(1, 257)
+
+    for i in common_int:
+        define_int(i)
+
+    for i in common_int:
+        define_uint(i)
+
+define_common_int()
diff --git a/miasm/core/objc.py b/miasm/core/objc.py
index 117e3b7d..87d19dde 100644
--- a/miasm/core/objc.py
+++ b/miasm/core/objc.py
@@ -14,8 +14,8 @@ from functools import total_ordering
 
 from miasm.core.utils import cmp_elts
 from miasm.expression.expression_reduce import ExprReducer
-from miasm.expression.expression import ExprInt, ExprId, ExprOp, ExprMem, \
-    is_op_segm
+from miasm.expression.expression import ExprInt, ExprId, ExprOp, ExprMem
+from miasm.arch.x86.arch import is_op_segm
 
 from miasm.core.ctypesmngr import CTypeUnion, CTypeStruct, CTypeId, CTypePtr,\
     CTypeArray, CTypeOp, CTypeSizeof, CTypeEnum, CTypeFunc, CTypeEllipsis
diff --git a/miasm/core/types.py b/miasm/core/types.py
index 466d136d..4f99627d 100644
--- a/miasm/core/types.py
+++ b/miasm/core/types.py
@@ -994,7 +994,7 @@ class BitField(Union):
         for name, bits in bit_list:
             fields.append((name, Bits(self._num, bits, offset)))
             offset += bits
-        if offset > self._num.size == 8:
+        if offset > self._num.size * 8:
             raise ValueError("sum of bit lengths is > to the backing num size")
         super(BitField, self).__init__(fields)
 
diff --git a/miasm/core/utils.py b/miasm/core/utils.py
index da7050f7..cfe96de4 100644
--- a/miasm/core/utils.py
+++ b/miasm/core/utils.py
@@ -133,6 +133,9 @@ def decode_hex(value):
 def encode_hex(value):
     return _ENCODE_HEX(value)[0]
 
+def size2mask(size):
+    """Return the bit mask of size @size"""
+    return (1 << size) - 1
 
 def hexdump(src, length=16):
     lines = []