Example #1
0
 def _size2mask(self, size):
     """Return a C string corresponding to the size2mask operation, with support for
     @size <= 128"""
     mask = size2mask(size)
     if size > 64:
         # Avoid "integer constant is too large for its type" error
         return "(0x%x | ((uint128_t) 0x%x << 64))" % (
             mask & 0xFFFFFFFFFFFFFFFF,
             (mask >> 64) & 0xFFFFFFFFFFFFFFFF,
         )
     return "0x%x" % mask
Example #2
0
File: C.py Project: guedou/miasm
 def _size2mask(self, size):
     """Return a C string corresponding to the size2mask operation, with support for
     @size <= 128"""
     mask = size2mask(size)
     if size > 64:
         # Avoid "integer constant is too large for its type" error
         return "(0x%x | ((uint128_t) 0x%x << 64))" % (
             mask & 0xFFFFFFFFFFFFFFFF,
             (mask >> 64) & 0xFFFFFFFFFFFFFFFF,
         )
     return "0x%x" % mask
Example #3
0
 def signExtend(self, size):
     """Sign extend to size
     @size: int
     """
     # assert self.size <= size
     if self.size == size:
         return self
     ad_size = size - self.size
     return ExprCompose(
         self,
         ExprCond(self.msb(), ExprInt(size2mask(ad_size), ad_size),
                  ExprInt(0, ad_size)))
Example #4
0
 def signExtend(self, size):
     """Sign extend to size
     @size: int
     """
     assert self.size <= size
     if self.size == size:
         return self
     ad_size = size - self.size
     return ExprCompose(self,
                        ExprCond(self.msb(),
                                 ExprInt(size2mask(ad_size), ad_size),
                                 ExprInt(0, ad_size)))
def simp_ext(_, expr):
    if expr.op.startswith('zeroExt_'):
        arg = expr.args[0]
        if expr.size == arg.size:
            return arg
        return ExprCompose(arg, ExprInt(0, expr.size - arg.size))

    if expr.op.startswith("signExt_"):
        arg = expr.args[0]
        add_size = expr.size - arg.size
        new_expr = ExprCompose(
            arg,
            ExprCond(arg.msb(), ExprInt(size2mask(add_size), add_size),
                     ExprInt(0, add_size)))
        return new_expr
    return expr
def simp_ext(_, expr):
    if expr.op.startswith('zeroExt_'):
        arg = expr.args[0]
        if expr.size == arg.size:
            return arg
        return ExprCompose(arg, ExprInt(0, expr.size - arg.size))

    if expr.op.startswith("signExt_"):
        arg = expr.args[0]
        add_size = expr.size - arg.size
        new_expr = ExprCompose(
            arg,
            ExprCond(
                arg.msb(),
                ExprInt(size2mask(add_size), add_size),
                ExprInt(0, add_size)
            )
        )
        return new_expr
    return expr
Example #7
0
 def _size2mask(self, size):
     """Return a C string corresponding to the size2mask operation, with support for
     @size <= 64"""
     assert size <= 64
     mask = size2mask(size)
     return "0x%x" % mask
Example #8
0
    def from_ExprOp(self, expr):
        if len(expr.args) == 1:
            if expr.op == 'parity':
                arg = expr.args[0]
                out = self.from_expr(arg)
                if arg.size <= self.NATIVE_INT_MAX_SIZE:
                    out = "(%s&%s)" % (out, self._size2mask(arg.size))
                else:
                    out = 'bignum_mask(%s, 8)' % (out, 8)
                    out = 'bignum_to_uint64(%s)' % out
                out = 'parity(%s)' % out
                return out

            elif expr.op.startswith("zeroExt_"):
                arg = expr.args[0]
                if expr.size == arg.size:
                    return arg
                return self.from_expr(
                    ExprCompose(arg, ExprInt(0, expr.size - arg.size)))

            elif expr.op.startswith("signExt_"):
                arg = expr.args[0]
                if expr.size == arg.size:
                    return arg
                add_size = expr.size - arg.size
                new_expr = ExprCompose(
                    arg,
                    ExprCond(arg.msb(), ExprInt(size2mask(add_size), add_size),
                             ExprInt(0, add_size)))
                return self.from_expr(new_expr)

            elif expr.op in ['cntleadzeros', 'cnttrailzeros']:
                arg = expr.args[0]
                out = self.from_expr(arg)
                if arg.size <= self.NATIVE_INT_MAX_SIZE:
                    out = "%s(0x%x, %s)" % (expr.op, expr.args[0].size, out)
                else:
                    out = "bignum_%s(%s, %d)" % (expr.op, out, arg.size)
                return out

            elif expr.op == '!':
                arg = expr.args[0]
                out = self.from_expr(arg)
                if expr.size <= self.NATIVE_INT_MAX_SIZE:
                    out = "(~ %s)&%s" % (out, self._size2mask(arg.size))
                else:
                    out = "bignum_not(%s)" % out
                    out = "bignum_mask(%s, expr.size)" % out
                return out

            elif expr.op in [
                    "ftan",
                    "frndint",
                    "f2xm1",
                    "fsin",
                    "fsqrt",
                    "fabs",
                    "fcos",
                    "fchs",
            ]:
                return "fpu_%s%d(%s)" % (
                    expr.op,
                    expr.size,
                    self.from_expr(expr.args[0]),
                )
            elif (expr.op.startswith("access_") or expr.op.startswith("load_")
                  or expr.op.startswith("fxam_c")):
                arg = expr.args[0]
                out = self.from_expr(arg)
                out = "%s(%s)" % (expr.op, out)
                return out

            elif expr.op == "-":
                arg = expr.args[0]
                out = self.from_expr(arg)
                if arg.size <= self.NATIVE_INT_MAX_SIZE:
                    out = "(%s(%s))" % (expr.op, out)
                    out = "(%s&%s)" % (out, self._size2mask(arg.size))
                else:
                    out = "bignum_sub(bignum_from_uint64(0), %s)" % out
                    out = "bignum_mask(%s, %d)" % (out, expr.size)
                return out

            elif expr.op.startswith("fpround_"):
                return "%s_fp%d(%s)" % (
                    expr.op,
                    expr.size,
                    self.from_expr(expr.args[0]),
                )
            elif expr.op == "sint_to_fp":
                size = expr.size
                arg = expr.args[0]
                if size not in [32, 64]:
                    raise RuntimeError("Unsupported size for sint_to_fp: %r" %
                                       size)
                return "%s_%d(%s)" % (expr.op, size, self.from_expr(arg))
            elif expr.op.startswith("fp_to_sint"):
                dest_size = expr.size
                arg_size = expr.args[0].size
                if (arg_size, dest_size) in [
                    (32, 32),
                    (64, 64),
                    (64, 32),
                ]:
                    func = "fp%d_to_sint%d" % (arg_size, dest_size)
                else:
                    raise RuntimeError(
                        "Unsupported size for fp_to_sint: %r to %r" %
                        (arg_size, dest_size))
                return "%s(%s)" % (func, self.from_expr(expr.args[0]))
            elif expr.op.startswith("fpconvert_fp"):
                dest_size = expr.size
                arg_size = expr.args[0].size
                if (arg_size, dest_size) in [(32, 64), (64, 32)]:
                    func = "fp%d_to_fp%d" % (arg_size, dest_size)
                else:
                    raise RuntimeError(
                        "Unsupported size for fpconvert: %r to %r" %
                        (arg_size, dest_size))
                return "%s(%s)" % (func, self.from_expr(expr.args[0]))
            else:
                raise NotImplementedError('Unknown op: %r' % expr.op)

        elif len(expr.args) == 2:
            if expr.op == TOK_EQUAL:
                return '(((%s&%s) == (%s&%s))?1:0)' % (
                    self.from_expr(expr.args[0]),
                    self._size2mask(expr.args[0].size),
                    self.from_expr(expr.args[1]),
                    self._size2mask(expr.args[1].size),
                )
            elif expr.op in self.dct_shift:
                arg0 = self.from_expr(expr.args[0])
                arg1 = self.from_expr(expr.args[1])
                if expr.size <= self.NATIVE_INT_MAX_SIZE:
                    out = 'SHIFT_%s(%d, %s, %s)' % (self.dct_shift[
                        expr.op].upper(), expr.args[0].size, arg0, arg1)
                else:
                    op = {"<<": "lshift", ">>": "rshift", "a>>": "a_rshift"}
                    out = "bignum_%s(%s, bignum_to_uint64(%s))" % (op[expr.op],
                                                                   arg0, arg1)
                    out = "bignum_mask(%s, %d)" % (out, expr.size)
                return out

            elif expr.is_associative():
                args = [self.from_expr(arg) for arg in expr.args]
                if expr.size <= self.NATIVE_INT_MAX_SIZE:
                    out = (" %s " % expr.op).join(args)
                    out = "((%s)&%s)" % (out, self._size2mask(expr.size))
                else:
                    op_to_bn_func = {
                        "+": "add",
                        "*": "mul",
                        "|": "or",
                        "^": "xor",
                        "&": "and",
                    }
                    args = list(expr.args)
                    out = self.from_expr(args.pop())
                    while args:
                        out = 'bignum_mask(bignum_%s(%s, %s), %d)' % (
                            op_to_bn_func[expr.op], out,
                            self.from_expr(args.pop()), expr.size)
                return out

            elif expr.op in ['-']:
                return '(((%s&%s) %s (%s&%s))&%s)' % (
                    self.from_expr(expr.args[0]),
                    self._size2mask(expr.args[0].size), str(
                        expr.op), self.from_expr(
                            expr.args[1]), self._size2mask(expr.args[1].size),
                    self._size2mask(expr.args[0].size))
            elif expr.op in self.dct_rot:
                arg0 = self.from_expr(expr.args[0])
                arg1 = self.from_expr(expr.args[1])
                if expr.size <= self.NATIVE_INT_MAX_SIZE:
                    out = '(%s(%s, %s, %s) &%s)' % (
                        self.dct_rot[expr.op],
                        expr.args[0].size,
                        arg0,
                        arg1,
                        self._size2mask(expr.args[0].size),
                    )
                else:
                    op = {">>>": "ror", "<<<": "rol"}
                    out = "bignum_%s(%s, %d, bignum_to_uint64(%s))" % (
                        op[expr.op], arg0, expr.size, arg1)
                    out = "bignum_mask(%s, %d)" % (out, expr.size)
                return out

            elif expr.op == 'x86_cpuid':
                return "%s(%s, %s)" % (expr.op, self.from_expr(
                    expr.args[0]), self.from_expr(expr.args[1]))
            elif expr.op.startswith("fcom"):
                arg0 = self.from_expr(expr.args[0])
                arg1 = self.from_expr(expr.args[1])
                if not expr.args[0].size <= self.NATIVE_INT_MAX_SIZE:
                    raise ValueError(
                        "Bad semantic: fpu do operations do not support such size"
                    )
                out = "fpu_%s(%s, %s)" % (expr.op, arg0, arg1)
                return out

            elif expr.op in [
                    "fadd", "fsub", "fdiv", 'fmul', "fscale", "fprem", "fyl2x",
                    "fpatan"
            ]:
                arg0 = self.from_expr(expr.args[0])
                arg1 = self.from_expr(expr.args[1])
                if not expr.args[0].size <= self.NATIVE_INT_MAX_SIZE:
                    raise ValueError(
                        "Bad semantic: fpu do operations do not support such size"
                    )
                out = "fpu_%s%d(%s, %s)" % (expr.op, expr.size, arg0, arg1)
                return out

            elif expr.op == "segm":
                return "segm2addr(jitcpu, %s, %s)" % (self.from_expr(
                    expr.args[0]), self.from_expr(expr.args[1]))

            elif expr.op in ['udiv', 'umod']:
                arg0 = self.from_expr(expr.args[0])
                arg1 = self.from_expr(expr.args[1])

                if expr.size <= self.NATIVE_INT_MAX_SIZE:
                    out = '%s%d(%s, %s)' % (expr.op, expr.args[0].size, arg0,
                                            arg1)
                else:
                    out = "bignum_%s(%s, %s)" % (expr.op, arg0, arg1)
                    out = "bignum_mask(%s, %d)" % (out, expr.size)
                return out

            elif expr.op in ['sdiv', 'smod']:
                arg0 = self.from_expr(expr.args[0])
                arg1 = self.from_expr(expr.args[1])

                if expr.size <= self.NATIVE_INT_MAX_SIZE:
                    out = '%s%d(%s, %s)' % (expr.op, expr.args[0].size, arg0,
                                            arg1)
                else:
                    out = "bignum_%s(%s, %s, %d)" % (expr.op, arg0, arg1,
                                                     expr.size)
                    out = "bignum_mask(%s, %d)" % (out, expr.size)
                return out

            elif expr.op in ["bcdadd", "bcdadd_cf"]:
                return "%s_%d(%s, %s)" % (expr.op, expr.args[0].size,
                                          self.from_expr(expr.args[0]),
                                          self.from_expr(expr.args[1]))
            else:
                raise NotImplementedError('Unknown op: %r' % expr.op)

        elif len(expr.args) >= 3 and expr.is_associative():  # ?????
            oper = [
                '(%s&%s)' % (
                    self.from_expr(arg),
                    self._size2mask(arg.size),
                ) for arg in expr.args
            ]
            oper = str(expr.op).join(oper)
            return "((%s)&%s)" % (oper, self._size2mask(expr.args[0].size))
        else:
            raise NotImplementedError('Unknown op: %s' % expr.op)
Example #9
0
    def from_ExprOp(self, expr):
        if len(expr.args) == 1:
            if expr.op == 'parity':
                return "parity(%s&0x%x)" % (self.from_expr(expr.args[0]),
                                            size2mask(expr.args[0].size))
            elif expr.op in ['cntleadzeros', 'cnttrailzeros']:
                return "%s(0x%x, %s)" % (expr.op,
                                             expr.args[0].size,
                                             self.from_expr(expr.args[0]))
            elif expr.op == '!':
                return "(~ %s)&0x%x" % (self.from_expr(expr.args[0]),
                                        size2mask(expr.args[0].size))
            elif (expr.op.startswith("double_to_") or
                  expr.op.endswith("_to_double")   or
                  expr.op.startswith("access_")    or
                  expr.op.startswith("load_")      or
                  expr.op.startswith("fxam_c")     or
                  expr.op in ["-", "ftan", "frndint", "f2xm1",
                              "fsin", "fsqrt", "fabs", "fcos", "fchs"]):
                return "%s(%s)" % (expr.op, self.from_expr(expr.args[0]))
            else:
                raise NotImplementedError('Unknown op: %r' % expr.op)

        elif len(expr.args) == 2:
            if expr.op == "==":
                return '(((%s&0x%x) == (%s&0x%x))?1:0)' % (
                    self.from_expr(expr.args[0]), size2mask(expr.args[0].size),
                    self.from_expr(expr.args[1]), size2mask(expr.args[1].size))
            elif expr.op in self.dct_shift:
                return 'SHIFT_%s(%d, %s, %s)' % (self.dct_shift[expr.op].upper(),
                                                 expr.args[0].size,
                                                 self.from_expr(expr.args[0]),
                                                 self.from_expr(expr.args[1]))
            elif expr.is_associative() or expr.op in ["%", "/"]:
                oper = ['(%s&0x%x)' % (self.from_expr(arg), size2mask(arg.size))
                        for arg in expr.args]
                oper = str(expr.op).join(oper)
                return "((%s)&0x%x)" % (oper, size2mask(expr.args[0].size))
            elif expr.op in ['-']:
                return '(((%s&0x%x) %s (%s&0x%x))&0x%x)' % (
                    self.from_expr(expr.args[0]), size2mask(expr.args[0].size),
                    str(expr.op),
                    self.from_expr(expr.args[1]), size2mask(expr.args[1].size),
                    size2mask(expr.args[0].size))
            elif expr.op in self.dct_rot:
                return '(%s(%s, %s, %s) &0x%x)' % (self.dct_rot[expr.op],
                                                   expr.args[0].size,
                                                   self.from_expr(expr.args[0]),
                                                   self.from_expr(expr.args[1]),
                                                   size2mask(expr.args[0].size))
            elif expr.op == 'x86_cpuid':
                return "%s(%s, %s)" % (expr.op,
                                       self.from_expr(expr.args[0]),
                                       self.from_expr(expr.args[1]))
            elif (expr.op.startswith("fcom")  or
                  expr.op in ["fadd", "fsub", "fdiv", 'fmul', "fscale",
                              "fprem", "fprem_lsb", "fyl2x", "fpatan"]):
                return "fpu_%s(%s, %s)" % (expr.op,
                                           self.from_expr(expr.args[0]),
                                           self.from_expr(expr.args[1]))
            elif expr.op == "segm":
                return "segm2addr(jitcpu, %s, %s)" % (
                    self.from_expr(expr.args[0]), self.from_expr(expr.args[1]))
            elif expr.op in ['udiv', 'umod', 'idiv', 'imod']:
                return '%s%d(%s, %s)' % (expr.op,
                                         expr.args[0].size,
                                         self.from_expr(expr.args[0]),
                                         self.from_expr(expr.args[1]))
            elif expr.op in ["bcdadd", "bcdadd_cf"]:
                return "%s_%d(%s, %s)" % (expr.op, expr.args[0].size,
                                          self.from_expr(expr.args[0]),
                                          self.from_expr(expr.args[1]))
            else:
                raise NotImplementedError('Unknown op: %r' % expr.op)

        elif len(expr.args) >= 3 and expr.is_associative():  # ?????
            oper = ['(%s&0x%x)' % (self.from_expr(arg), size2mask(arg.size))
                    for arg in expr.args]
            oper = str(expr.op).join(oper)
            return "((%s)&0x%x)" % (oper, size2mask(expr.args[0].size))

        else:
            raise NotImplementedError('Unknown op: %s' % expr.op)
Example #10
0
File: C.py Project: CaineQT/miasm
    def from_ExprOp(self, expr):
        if len(expr.args) == 1:
            if expr.op == 'parity':
                return "parity(%s&0x%x)" % (self.from_expr(expr.args[0]),
                                            size2mask(expr.args[0].size))
            elif expr.op in ['bsr', 'bsf']:
                return "x86_%s(%s, 0x%x)" % (expr.op,
                                             self.from_expr(expr.args[0]),
                                             expr.args[0].size)
            elif expr.op == '!':
                return "(~ %s)&0x%x" % (self.from_expr(expr.args[0]),
                                        size2mask(expr.args[0].size))
            elif expr.op in ["hex2bcd", "bcd2hex"]:
                return "%s_%d(%s)" % (expr.op, expr.args[0].size,
                                      self.from_expr(expr.args[0]))
            elif (expr.op.startswith("double_to_") or
                  expr.op.endswith("_to_double")   or
                  expr.op.startswith("access_")    or
                  expr.op.startswith("load_")      or
                  expr.op in ["-", "ftan", "frndint", "f2xm1",
                              "fsin", "fsqrt", "fabs", "fcos"]):
                return "%s(%s)" % (expr.op, self.from_expr(expr.args[0]))
            else:
                raise NotImplementedError('Unknown op: %r' % expr.op)

        elif len(expr.args) == 2:
            if expr.op == "==":
                return '(((%s&0x%x) == (%s&0x%x))?1:0)' % (
                    self.from_expr(expr.args[0]), size2mask(expr.args[0].size),
                    self.from_expr(expr.args[1]), size2mask(expr.args[1].size))
            elif expr.op in self.dct_shift:
                return 'shift_%s_%.2d(%s , %s)' % (self.dct_shift[expr.op],
                                                   expr.args[0].size,
                                                   self.from_expr(expr.args[0]),
                                                   self.from_expr(expr.args[1]))
            elif expr.is_associative() or expr.op in ["%", "/"]:
                oper = ['(%s&0x%x)' % (self.from_expr(arg), size2mask(arg.size))
                        for arg in expr.args]
                oper = str(expr.op).join(oper)
                return "((%s)&0x%x)" % (oper, size2mask(expr.args[0].size))
            elif expr.op in ['-']:
                return '(((%s&0x%x) %s (%s&0x%x))&0x%x)' % (
                    self.from_expr(expr.args[0]), size2mask(expr.args[0].size),
                    str(expr.op),
                    self.from_expr(expr.args[1]), size2mask(expr.args[1].size),
                    size2mask(expr.args[0].size))
            elif expr.op in self.dct_rot:
                return '(%s(%s, %s, %s) &0x%x)' % (self.dct_rot[expr.op],
                                                   expr.args[0].size,
                                                   self.from_expr(expr.args[0]),
                                                   self.from_expr(expr.args[1]),
                                                   size2mask(expr.args[0].size))
            elif (expr.op.startswith('cpuid') or
                  expr.op.startswith("fcom")  or
                  expr.op in ["fadd", "fsub", "fdiv", 'fmul', "fscale"]):
                return "%s(%s, %s)" % (expr.op, self.from_expr(expr.args[0]),
                                       self.from_expr(expr.args[1]))
            elif expr.op == "segm":
                return "segm2addr(jitcpu, %s, %s)" % (
                    self.from_expr(expr.args[0]), self.from_expr(expr.args[1]))
            elif expr.op in ['udiv', 'umod', 'idiv', 'imod']:
                return '%s%d((vm_cpu_t*)jitcpu->cpu, %s, %s)' % (expr.op,
                                                                 expr.args[0].size,
                                                                 self.from_expr(expr.args[0]),
                                                                 self.from_expr(expr.args[1]))
            elif expr.op in ["bcdadd", "bcdadd_cf"]:
                return "%s_%d(%s, %s)" % (expr.op, expr.args[0].size,
                                          self.from_expr(expr.args[0]),
                                          self.from_expr(expr.args[1]))
            else:
                raise NotImplementedError('Unknown op: %r' % expr.op)

        elif len(expr.args) == 3 and expr.op in self.dct_div:
            return '(%s(%s, %s, %s, %s) &0x%x)' % (self.dct_div[expr.op],
                                                   expr.args[0].size,
                                                   self.from_expr(expr.args[0]),
                                                   self.from_expr(expr.args[1]),
                                                   self.from_expr(expr.args[2]),
                                                   size2mask(expr.args[0].size))

        elif len(expr.args) >= 3 and expr.is_associative():  # ?????
            oper = ['(%s&0x%x)' % (self.from_expr(arg), size2mask(arg.size))
                    for arg in expr.args]
            oper = str(expr.op).join(oper)
            return "((%s)&0x%x)" % (oper, size2mask(expr.args[0].size))

        else:
            raise NotImplementedError('Unknown op: %s' % expr.op)
Example #11
0
    def from_ExprOp(self, expr):
        if len(expr.args) == 1:
            if expr.op == 'parity':
                return "parity(%s&0x%x)" % (self.from_expr(
                    expr.args[0]), size2mask(expr.args[0].size))
            elif expr.op in ['bsr', 'bsf']:
                return "x86_%s(%s, 0x%x)" % (
                    expr.op, self.from_expr(expr.args[0]), expr.args[0].size)
            elif expr.op == '!':
                return "(~ %s)&0x%x" % (self.from_expr(
                    expr.args[0]), size2mask(expr.args[0].size))
            elif expr.op in ["hex2bcd", "bcd2hex"]:
                return "%s_%d(%s)" % (expr.op, expr.args[0].size,
                                      self.from_expr(expr.args[0]))
            elif (expr.op.startswith("double_to_")
                  or expr.op.endswith("_to_double")
                  or expr.op.startswith("access_")
                  or expr.op.startswith("load_") or expr.op in [
                      "-", "ftan", "frndint", "f2xm1", "fsin", "fsqrt", "fabs",
                      "fcos"
                  ]):
                return "%s(%s)" % (expr.op, self.from_expr(expr.args[0]))
            else:
                raise NotImplementedError('Unknown op: %r' % expr.op)

        elif len(expr.args) == 2:
            if expr.op == "==":
                return '(((%s&0x%x) == (%s&0x%x))?1:0)' % (
                    self.from_expr(expr.args[0]), size2mask(expr.args[0].size),
                    self.from_expr(expr.args[1]), size2mask(expr.args[1].size))
            elif expr.op in self.dct_shift:
                return 'shift_%s_%.2d(%s , %s)' % (
                    self.dct_shift[expr.op], expr.args[0].size,
                    self.from_expr(expr.args[0]), self.from_expr(expr.args[1]))
            elif expr.is_associative() or expr.op in ["%", "/"]:
                oper = [
                    '(%s&0x%x)' % (self.from_expr(arg), size2mask(arg.size))
                    for arg in expr.args
                ]
                oper = str(expr.op).join(oper)
                return "((%s)&0x%x)" % (oper, size2mask(expr.args[0].size))
            elif expr.op in ['-']:
                return '(((%s&0x%x) %s (%s&0x%x))&0x%x)' % (
                    self.from_expr(expr.args[0]), size2mask(expr.args[0].size),
                    str(expr.op), self.from_expr(expr.args[1]),
                    size2mask(expr.args[1].size), size2mask(expr.args[0].size))
            elif expr.op in self.dct_rot:
                return '(%s(%s, %s, %s) &0x%x)' % (
                    self.dct_rot[expr.op], expr.args[0].size,
                    self.from_expr(expr.args[0]), self.from_expr(
                        expr.args[1]), size2mask(expr.args[0].size))
            elif (expr.op.startswith('cpuid') or expr.op.startswith("fcom")
                  or expr.op in ["fadd", "fsub", "fdiv", 'fmul', "fscale"]):
                return "%s(%s, %s)" % (expr.op, self.from_expr(
                    expr.args[0]), self.from_expr(expr.args[1]))
            elif expr.op == "segm":
                return "segm2addr(vmcpu, %s, %s)" % (self.from_expr(
                    expr.args[0]), self.from_expr(expr.args[1]))
            elif expr.op in ['udiv', 'umod', 'idiv', 'imod']:
                return '%s%d(vmcpu, %s, %s)' % (expr.op, expr.args[0].size,
                                                self.from_expr(expr.args[0]),
                                                self.from_expr(expr.args[1]))
            elif expr.op in ["bcdadd", "bcdadd_cf"]:
                return "%s_%d(%s, %s)" % (expr.op, expr.args[0].size,
                                          self.from_expr(expr.args[0]),
                                          self.from_expr(expr.args[1]))
            else:
                raise NotImplementedError('Unknown op: %r' % expr.op)

        elif len(expr.args) == 3 and expr.op in self.dct_div:
            return '(%s(%s, %s, %s, %s) &0x%x)' % (
                self.dct_div[expr.op], expr.args[0].size,
                self.from_expr(expr.args[0]), self.from_expr(expr.args[1]),
                self.from_expr(expr.args[2]), size2mask(expr.args[0].size))

        elif len(expr.args) >= 3 and expr.is_associative():  # ?????
            oper = [
                '(%s&0x%x)' % (self.from_expr(arg), size2mask(arg.size))
                for arg in expr.args
            ]
            oper = str(expr.op).join(oper)
            return "((%s)&0x%x)" % (oper, size2mask(expr.args[0].size))

        else:
            raise NotImplementedError('Unknown op: %s' % expr.op)
Example #12
0
File: C.py Project: commial/miasm
 def _size2mask(self, size):
     """Return a C string corresponding to the size2mask operation, with support for
     @size <= 64"""
     assert size <= 64
     mask = size2mask(size)
     return "0x%x" % mask
Example #13
0
File: C.py Project: commial/miasm
    def from_ExprOp(self, expr):
        if len(expr.args) == 1:
            if expr.op == 'parity':
                arg = expr.args[0]
                out = self.from_expr(arg)
                if arg.size <= self.NATIVE_INT_MAX_SIZE:
                    out = "(%s&%s)" % (out, self._size2mask(arg.size))
                else:
                    out = 'bignum_mask(%s, 8)' % (out, 8)
                    out = 'bignum_to_uint64(%s)' % out
                out = 'parity(%s)' % out
                return out

            elif expr.op.startswith("zeroExt_"):
                arg = expr.args[0]
                if expr.size == arg.size:
                    return arg
                return self.from_expr(ExprCompose(arg, ExprInt(0, expr.size - arg.size)))

            elif expr.op.startswith("signExt_"):
                arg = expr.args[0]
                if expr.size == arg.size:
                    return arg
                add_size = expr.size - arg.size
                new_expr = ExprCompose(
                    arg,
                    ExprCond(
                        arg.msb(),
                        ExprInt(size2mask(add_size), add_size),
                        ExprInt(0, add_size)
                    )
                )
                return self.from_expr(new_expr)


            elif expr.op in ['cntleadzeros', 'cnttrailzeros']:
                arg = expr.args[0]
                out = self.from_expr(arg)
                if arg.size <= self.NATIVE_INT_MAX_SIZE:
                    out = "%s(0x%x, %s)" % (expr.op, expr.args[0].size, out)
                else:
                    out = "bignum_%s(%s, %d)" % (expr.op, out, arg.size)
                return out

            elif expr.op == '!':
                arg = expr.args[0]
                out = self.from_expr(arg)
                if expr.size <= self.NATIVE_INT_MAX_SIZE:
                    out = "(~ %s)&%s" % (out, self._size2mask(arg.size))
                else:
                    out = "bignum_not(%s)" % out
                    out = "bignum_mask(%s, expr.size)" % out
                return out

            elif expr.op in [
                    "ftan", "frndint", "f2xm1", "fsin", "fsqrt", "fabs", "fcos",
                    "fchs",
            ]:
                return "fpu_%s%d(%s)" % (
                    expr.op,
                    expr.size,
                    self.from_expr(expr.args[0]),
                )
            elif (expr.op.startswith("access_")    or
                  expr.op.startswith("load_")      or
                  expr.op.startswith("fxam_c")):
                arg = expr.args[0]
                out = self.from_expr(arg)
                out = "%s(%s)" % (expr.op, out)
                return out

            elif expr.op == "-":
                arg = expr.args[0]
                out = self.from_expr(arg)
                if arg.size <= self.NATIVE_INT_MAX_SIZE:
                    out = "(%s(%s))" % (expr.op, out)
                    out = "(%s&%s)" % (out, self._size2mask(arg.size))
                else:
                    out = "bignum_sub(bignum_from_uint64(0), %s)" % out
                    out = "bignum_mask(%s, %d)"% (out, expr.size)
                return out

            elif expr.op.startswith("fpround_"):
                return "%s_fp%d(%s)" % (
                    expr.op,
                    expr.size,
                    self.from_expr(expr.args[0]),
                )
            elif expr.op == "sint_to_fp":
                size = expr.size
                arg = expr.args[0]
                if size not in [32, 64]:
                    raise RuntimeError(
                        "Unsupported size for sint_to_fp: %r" % size
                    )
                return "%s_%d(%s)" % (expr.op, size, self.from_expr(arg))
            elif expr.op.startswith("fp_to_sint"):
                dest_size = expr.size
                arg_size = expr.args[0].size
                if (arg_size, dest_size) in [
                        (32, 32), (64, 64), (64, 32),
                ]:
                    func = "fp%d_to_sint%d" % (arg_size, dest_size)
                else:
                    raise RuntimeError(
                        "Unsupported size for fp_to_sint: %r to %r" % (
                            arg_size,
                            dest_size
                        ))
                return "%s(%s)" % (func, self.from_expr(expr.args[0]))
            elif expr.op.startswith("fpconvert_fp"):
                dest_size = expr.size
                arg_size = expr.args[0].size
                if (arg_size, dest_size) in [
                        (32, 64), (64, 32)
                ]:
                    func = "fp%d_to_fp%d" % (arg_size, dest_size)
                else:
                    raise RuntimeError(
                        "Unsupported size for fpconvert: %r to %r" % (arg_size,
                                                                      dest_size)
                    )
                return "%s(%s)" % (func, self.from_expr(expr.args[0]))
            else:
                raise NotImplementedError('Unknown op: %r' % expr.op)

        elif len(expr.args) == 2:
            if expr.op == TOK_EQUAL:
                return '(((%s&%s) == (%s&%s))?1:0)' % (
                    self.from_expr(expr.args[0]),
                    self._size2mask(expr.args[0].size),
                    self.from_expr(expr.args[1]),
                    self._size2mask(expr.args[1].size),
                )
            elif expr.op in self.dct_shift:
                arg0 = self.from_expr(expr.args[0])
                arg1 = self.from_expr(expr.args[1])
                if expr.size <= self.NATIVE_INT_MAX_SIZE:
                    out = 'SHIFT_%s(%d, %s, %s)' % (
                        self.dct_shift[expr.op].upper(),
                        expr.args[0].size,
                        arg0,
                        arg1
                    )
                else:
                    op = {
                        "<<": "lshift",
                        ">>": "rshift",
                        "a>>": "a_rshift"
                    }
                    out = "bignum_%s(%s, bignum_to_uint64(%s))" % (
                        op[expr.op], arg0, arg1
                    )
                    out = "bignum_mask(%s, %d)"% (out, expr.size)
                return out

            elif expr.is_associative():
                args = [self.from_expr(arg)
                        for arg in expr.args]
                if expr.size <= self.NATIVE_INT_MAX_SIZE:
                    out = (" %s " % expr.op).join(args)
                    out = "((%s)&%s)" % (out, self._size2mask(expr.size))
                else:
                    op_to_bn_func = {
                    "+": "add",
                    "*": "mul",
                    "|": "or",
                    "^": "xor",
                    "&": "and",
                    }
                    args = list(expr.args)
                    out = self.from_expr(args.pop())
                    while args:
                        out = 'bignum_mask(bignum_%s(%s, %s), %d)' % (
                            op_to_bn_func[expr.op],
                            out,
                            self.from_expr(args.pop()),
                            expr.size
                    )
                return out

            elif expr.op in ['-']:
                return '(((%s&%s) %s (%s&%s))&%s)' % (
                    self.from_expr(expr.args[0]),
                    self._size2mask(expr.args[0].size),
                    str(expr.op),
                    self.from_expr(expr.args[1]),
                    self._size2mask(expr.args[1].size),
                    self._size2mask(expr.args[0].size)
                )
            elif expr.op in self.dct_rot:
                arg0 = self.from_expr(expr.args[0])
                arg1 = self.from_expr(expr.args[1])
                if expr.size <= self.NATIVE_INT_MAX_SIZE:
                    out = '(%s(%s, %s, %s) &%s)' % (
                        self.dct_rot[expr.op],
                        expr.args[0].size,
                        arg0,
                        arg1,
                        self._size2mask(expr.args[0].size),
                    )
                else:
                    op = {
                        ">>>": "ror",
                        "<<<": "rol"
                    }
                    out = "bignum_%s(%s, %d, bignum_to_uint64(%s))" % (
                        op[expr.op], arg0, expr.size, arg1
                    )
                    out = "bignum_mask(%s, %d)"% (out, expr.size)
                return out

            elif expr.op == 'x86_cpuid':
                return "%s(%s, %s)" % (expr.op,
                                       self.from_expr(expr.args[0]),
                                       self.from_expr(expr.args[1]))
            elif expr.op.startswith("fcom"):
                arg0 = self.from_expr(expr.args[0])
                arg1 = self.from_expr(expr.args[1])
                if not expr.args[0].size <= self.NATIVE_INT_MAX_SIZE:
                    raise ValueError("Bad semantic: fpu do operations do not support such size")
                out = "fpu_%s(%s, %s)" % (expr.op, arg0, arg1)
                return out

            elif expr.op in ["fadd", "fsub", "fdiv", 'fmul', "fscale",
                             "fprem", "fyl2x", "fpatan"]:
                arg0 = self.from_expr(expr.args[0])
                arg1 = self.from_expr(expr.args[1])
                if not expr.args[0].size <= self.NATIVE_INT_MAX_SIZE:
                    raise ValueError("Bad semantic: fpu do operations do not support such size")
                out = "fpu_%s%d(%s, %s)" % (expr.op, expr.size, arg0, arg1)
                return out

            elif expr.op == "segm":
                return "segm2addr(jitcpu, %s, %s)" % (
                    self.from_expr(expr.args[0]),
                    self.from_expr(expr.args[1])
                )

            elif expr.op in ['udiv', 'umod']:
                arg0 = self.from_expr(expr.args[0])
                arg1 = self.from_expr(expr.args[1])

                if expr.size <= self.NATIVE_INT_MAX_SIZE:
                    out = '%s%d(%s, %s)' % (
                        expr.op,
                        expr.args[0].size,
                        arg0,
                        arg1
                    )
                else:
                    out = "bignum_%s(%s, %s)" % (
                        expr.op,
                        arg0,
                        arg1
                    )
                    out = "bignum_mask(%s, %d)"% (out, expr.size)
                return out



            elif expr.op in ['idiv', 'imod']:
                arg0 = self.from_expr(expr.args[0])
                arg1 = self.from_expr(expr.args[1])

                if expr.size <= self.NATIVE_INT_MAX_SIZE:
                    out = '%s%d(%s, %s)' % (
                        expr.op,
                        expr.args[0].size,
                        arg0,
                        arg1
                    )
                else:
                    out = "bignum_%s(%s, %s, %d)" % (
                        expr.op,
                        arg0,
                        arg1,
                        expr.size
                    )
                    out = "bignum_mask(%s, %d)"% (out, expr.size)
                return out

            elif expr.op in ["bcdadd", "bcdadd_cf"]:
                return "%s_%d(%s, %s)" % (
                    expr.op, expr.args[0].size,
                    self.from_expr(expr.args[0]),
                    self.from_expr(expr.args[1])
                )
            else:
                raise NotImplementedError('Unknown op: %r' % expr.op)

        elif len(expr.args) >= 3 and expr.is_associative():  # ?????
            oper = ['(%s&%s)' % (
                self.from_expr(arg),
                self._size2mask(arg.size),
            )
                    for arg in expr.args]
            oper = str(expr.op).join(oper)
            return "((%s)&%s)" % (
                oper,
                self._size2mask(expr.args[0].size)
            )
        else:
            raise NotImplementedError('Unknown op: %s' % expr.op)
Example #14
0
 def __get_int(self):
     "Return self integer representation"
     return int(self.__arg & size2mask(self.__size))
Example #15
0
 def __get_int(self):
     "Return self integer representation"
     return int(self.__arg & size2mask(self.__size))
Example #16
0
    def from_ExprOp(self, expr):
        if len(expr.args) == 1:
            if expr.op == "parity":
                return "parity(%s&0x%x)" % (self.from_expr(expr.args[0]), size2mask(expr.args[0].size))
            elif expr.op in ["bsr", "bsf"]:
                return "x86_%s(%s, 0x%x)" % (expr.op, self.from_expr(expr.args[0]), expr.args[0].size)
            elif expr.op == "!":
                return "(~ %s)&0x%x" % (self.from_expr(expr.args[0]), size2mask(expr.args[0].size))
            elif expr.op in ["hex2bcd", "bcd2hex"]:
                return "%s_%d(%s)" % (expr.op, expr.args[0].size, self.from_expr(expr.args[0]))
            elif (
                expr.op.startswith("double_to_")
                or expr.op.endswith("_to_double")
                or expr.op.startswith("access_")
                or expr.op.startswith("load_")
                or expr.op.startswith("fxam_c")
                or expr.op in ["-", "ftan", "frndint", "f2xm1", "fsin", "fsqrt", "fabs", "fcos", "fchs"]
            ):
                return "%s(%s)" % (expr.op, self.from_expr(expr.args[0]))
            else:
                raise NotImplementedError("Unknown op: %r" % expr.op)

        elif len(expr.args) == 2:
            if expr.op == "==":
                return "(((%s&0x%x) == (%s&0x%x))?1:0)" % (
                    self.from_expr(expr.args[0]),
                    size2mask(expr.args[0].size),
                    self.from_expr(expr.args[1]),
                    size2mask(expr.args[1].size),
                )
            elif expr.op in self.dct_shift:
                return "shift_%s_%.2d(%s , %s)" % (
                    self.dct_shift[expr.op],
                    expr.args[0].size,
                    self.from_expr(expr.args[0]),
                    self.from_expr(expr.args[1]),
                )
            elif expr.is_associative() or expr.op in ["%", "/"]:
                oper = ["(%s&0x%x)" % (self.from_expr(arg), size2mask(arg.size)) for arg in expr.args]
                oper = str(expr.op).join(oper)
                return "((%s)&0x%x)" % (oper, size2mask(expr.args[0].size))
            elif expr.op in ["-"]:
                return "(((%s&0x%x) %s (%s&0x%x))&0x%x)" % (
                    self.from_expr(expr.args[0]),
                    size2mask(expr.args[0].size),
                    str(expr.op),
                    self.from_expr(expr.args[1]),
                    size2mask(expr.args[1].size),
                    size2mask(expr.args[0].size),
                )
            elif expr.op in self.dct_rot:
                return "(%s(%s, %s, %s) &0x%x)" % (
                    self.dct_rot[expr.op],
                    expr.args[0].size,
                    self.from_expr(expr.args[0]),
                    self.from_expr(expr.args[1]),
                    size2mask(expr.args[0].size),
                )
            elif (
                expr.op.startswith("cpuid")
                or expr.op.startswith("fcom")
                or expr.op in ["fadd", "fsub", "fdiv", "fmul", "fscale", "fprem", "fprem_lsb", "fyl2x", "fpatan"]
            ):
                return "%s(%s, %s)" % (expr.op, self.from_expr(expr.args[0]), self.from_expr(expr.args[1]))
            elif expr.op == "segm":
                return "segm2addr(jitcpu, %s, %s)" % (self.from_expr(expr.args[0]), self.from_expr(expr.args[1]))
            elif expr.op in ["udiv", "umod", "idiv", "imod"]:
                return "%s%d((vm_cpu_t*)jitcpu->cpu, %s, %s)" % (
                    expr.op,
                    expr.args[0].size,
                    self.from_expr(expr.args[0]),
                    self.from_expr(expr.args[1]),
                )
            elif expr.op in ["bcdadd", "bcdadd_cf"]:
                return "%s_%d(%s, %s)" % (
                    expr.op,
                    expr.args[0].size,
                    self.from_expr(expr.args[0]),
                    self.from_expr(expr.args[1]),
                )
            else:
                raise NotImplementedError("Unknown op: %r" % expr.op)

        elif len(expr.args) == 3 and expr.op in self.dct_rotc:
            return "(%s(%s, %s, %s, %s) &0x%x)" % (
                self.dct_rotc[expr.op],
                expr.args[0].size,
                self.from_expr(expr.args[0]),
                self.from_expr(expr.args[1]),
                self.from_expr(expr.args[2]),
                size2mask(expr.args[0].size),
            )

        elif len(expr.args) >= 3 and expr.is_associative():  # ?????
            oper = ["(%s&0x%x)" % (self.from_expr(arg), size2mask(arg.size)) for arg in expr.args]
            oper = str(expr.op).join(oper)
            return "((%s)&0x%x)" % (oper, size2mask(expr.args[0].size))

        else:
            raise NotImplementedError("Unknown op: %s" % expr.op)