diff options
Diffstat (limited to 'miasm/core')
| -rw-r--r-- | miasm/core/asmblock.py | 6 | ||||
| -rw-r--r-- | miasm/core/locationdb.py | 7 | ||||
| -rw-r--r-- | miasm/core/modint.py | 256 | ||||
| -rw-r--r-- | miasm/core/objc.py | 4 | ||||
| -rw-r--r-- | miasm/core/types.py | 2 | ||||
| -rw-r--r-- | miasm/core/utils.py | 3 |
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 = [] |