예제 #1
0
파일: identify.py 프로젝트: whb224117/arybo
def __identify(app, in_name):
    # TODO: identify number of independant inputs
    NL = app.nl().vector()
    M = app.matrix()
    nbits_in = M.ncols()
    nbits_out = M.nlines()
    if nbits_in != nbits_out:
        raise ValueError("do not yet support application with a different\
                number of input and output bits!")
    mba = MBA(nbits_in)
    var_in = mba.var(in_name)

    if NL != Vector(len(NL)):
        return _identify_nonaffine(app, var_in)
    C = EX.ExprCst(mba.from_vec(app.cst()).to_cst(), nbits_out)
    if M == Matrix(nbits_out, nbits_in):
        # This is just a constant
        return C

    ret = EX.ExprBV(var_in)
    matrix_empty = 0
    # Find empty columns in the matrix.
    for j in range(nbits_in):
        is_zero = reduce(operator.and_, (M.at(i, j) == imm(0)
                                         for i in range(nbits_out)), True)
        if is_zero:
            matrix_empty |= 1 << j
    matrix_and_mask = (~matrix_empty) % (2**nbits_out)
    if matrix_empty != 0:
        ret = EX.ExprAnd(ret, EX.ExprCst(matrix_and_mask, nbits_out))
    if mba.from_vec(M * var_in.vec) ^ (var_in & matrix_empty) == var_in:
        # This is a XOR
        return EX.ExprXor(ret, C)
    raise ValueError("unable to identify an expression")
예제 #2
0
    def test_unary(self):
        self.exprEqual(EX.ExprNot(self.x4_expr), ~self.x4)

        self.exprEqual(EX.ExprBroadcast(EX.ExprCst(1, 4), 0, 4),
                       self.mba4.from_cst(0xf))

        self.exprEqual(EX.ExprBroadcast(EX.ExprCst(1, 4), 1, 4),
                       self.mba4.from_cst(0))
예제 #3
0
 def visit_Ror(self, e):
     n = e.Y
     if not isinstance(n, EX.ExprCst):
         raise ValueError("only ror with a known constant is supported")
     n = n.n
     arg = self.visit(e.X)
     if n == 0:
         return arg
     nbits = arg.nbits
     return EX.ExprXor(EX.ExprShl(arg, EX.ExprCst(nbits - n, nbits)),
                       EX.ExprLShr(arg, EX.ExprCst(n, nbits)))
예제 #4
0
파일: llvm.py 프로젝트: whb224117/arybo
    def test_cond(self):
        e = EX.ExprCond(EX.ExprCmpEq(self.ex, EX.ExprCst(10, 8)), self.ex, self.ey)
        M,cfunc = self.get_c_func(e, self.args)
        for i in range(256):
            vref = 0xff if i != 10 else 10
            self.assertEqual(cfunc(i, 0xff), vref)
        self.engine.remove_module(M)

        e = EX.ExprCond(EX.ExprCmpGte(self.ex, EX.ExprCst(10, 8), is_signed=True), self.ex, self.ey)
        M,cfunc = self.get_c_func(e, self.args)
        for i in range(-128,128):
            vref = i if i >= 10 else 0xff
            self.assertEqual(cfunc(i, 0xff), vref)
        self.engine.remove_module(M)
예제 #5
0
    def test_cmp(self):
        e = EX.ExprCond(EX.ExprCmpEq(self.x8_expr, EX.ExprCst(10, 8)),
                        self.y8_expr, self.z8_expr)

        e = EX.eval_expr(e)
        for i in range(256):
            eref = self.z8 if i != 10 else self.y8
            self.assertEqual(e.eval({self.x8: i}), eref.vec)
예제 #6
0
    def test_logical(self):
        ops = ((EX.ExprLShr, operator.rshift), (EX.ExprShl, operator.lshift),
               (EX.ExprRol, lambda x, n: x.rol(n)), (EX.ExprRor,
                                                     lambda x, n: x.ror(n)))

        for op in ops:
            for s in range(5):
                self.exprEqual(op[0](self.x4_expr, EX.ExprCst(s, 4)),
                               op[1](self.x4, s))
예제 #7
0
    def test_binaryops(self):
        ops = (
            (EX.ExprAdd, operator.add),
            (EX.ExprSub, operator.sub),
            (EX.ExprMul, operator.mul),
        )

        args_expr = (self.x4_expr, self.y4_expr, self.z4_expr)
        args = (self.x4, self.y4, self.z4)

        for op in ops:
            self.exprEqual(reduce(op[0], args_expr), reduce(op[1], args))

        E0 = EX.ExprAdd(self.x8_expr, self.x8_expr)
        self.exprEqual(EX.ExprAdd(E0, E0), self.x8 << 2)

        for i in range(1, 16):
            self.exprEqual(EX.ExprDiv(self.x4_expr, EX.ExprCst(i, 4)),
                           self.x4.udiv(i))
예제 #8
0
    def test_rotate_binop(self):
        E0 = EX.ExprRor(EX.ExprAdd(self.x4_expr, self.y4_expr),
                        EX.ExprCst(1, 4))
        self.exprEqual(E0, (self.x4 + self.y4).ror(1))

        E0 = EX.ExprRor(EX.ExprSub(self.x4_expr, self.y4_expr),
                        EX.ExprCst(1, 4))
        self.exprEqual(E0, (self.x4 - self.y4).ror(1))

        E0 = EX.ExprRor(EX.ExprMul(self.x4_expr, self.y4_expr),
                        EX.ExprCst(1, 4))
        self.exprEqual(E0, (self.x4 * self.y4).ror(1))

        E0 = EX.ExprRol(EX.ExprAdd(self.x4_expr, self.y4_expr),
                        EX.ExprCst(1, 4))
        self.exprEqual(E0, (self.x4 + self.y4).rol(1))

        E0 = EX.ExprRol(EX.ExprSub(self.x4_expr, self.y4_expr),
                        EX.ExprCst(1, 4))
        self.exprEqual(E0, (self.x4 - self.y4).rol(1))

        E0 = EX.ExprRol(EX.ExprMul(self.x4_expr, self.y4_expr),
                        EX.ExprCst(1, 4))
        self.exprEqual(E0, (self.x4 * self.y4).rol(1))
예제 #9
0
def tritonast2arybo(e, use_exprs=True, use_esf=False, context=None):
    ''' Convert a subset of Triton's AST into Arybo's representation

    Args:
        e: Triton AST
        use_esf: use ESFs when creating the final expression
        context: dictionnary that associates Triton expression ID to arybo expressions

    Returns:
        An :class:`arybo.lib.MBAVariable` object
    '''

    children_ = e.getChilds()
    children = (tritonast2arybo(c, use_exprs, use_esf, context)
                for c in children_)
    reversed_children = (tritonast2arybo(c, use_exprs, use_esf, context)
                         for c in reversed(children_))

    Ty = e.getKind()
    if Ty == TAstN.ZX:
        n = next(children)
        v = next(children)
        n += v.nbits
        if n == v.nbits:
            return v
        return v.zext(n)
    if Ty == TAstN.SX:
        n = next(children)
        v = next(children)
        n += v.nbits
        if n == v.nbits:
            return v
        return v.sext(n)
    if Ty == TAstN.DECIMAL:
        return e.getValue()
    if Ty == TAstN.BV:
        cst = next(children)
        nbits = next(children)
        if use_exprs:
            return EX.ExprCst(cst, nbits)
        else:
            return _get_mba(nbits, use_esf).from_cst(cst)
    if Ty == TAstN.EXTRACT:
        last = next(children)
        first = next(children)
        v = next(children)
        return v[first:last + 1]
    if Ty == TAstN.CONCAT:
        if use_exprs:
            return EX.ExprConcat(*list(reversed_children))
        else:
            return flatten(reversed_children)
    if Ty == TAstN.VARIABLE:
        name = e.getValue()
        ret = _get_mba(e.getBitvectorSize(), use_esf).var(name)
        if use_exprs:
            ret = EX.ExprBV(ret)
        return ret
    if Ty == TAstN.REFERENCE:
        if context is None:
            raise ValueError(
                "reference node without context can't be resolved")
        id_ = e.getValue()
        ret = context.get(id_, None)
        if ret is None:
            raise ValueError("expression id %d not found in context" % id_)
        return ret
    if Ty == TAstN.LET:
        # Alias
        # djo: "c'est pas utilise osef"
        raise ValueError("unsupported LET operation")

    # Logical/arithmetic shifts
    shifts = {
        TAstN.BVLSHR: operator.rshift,
        TAstN.BVSHL: operator.lshift,
    }
    shift = shifts.get(Ty, None)
    if not shift is None:
        v = next(children)
        n = next(children)
        return shift(v, n)
    # We need to separate rotate shifts from the others because the triton API
    # is different for this one... (no comment)
    rshifts = {
        TAstN.BVROL: lambda x, n: x.rol(n),
        TAstN.BVROR: lambda x, n: x.ror(n)
    }
    rshift = rshifts.get(Ty, None)
    if not rshift is None:
        # Notice the order here compared to above...
        n = next(children)
        v = next(children)
        return rshift(v, n)

    # Unary op
    unops = {
        TAstN.BVNOT: lambda x: ~x,
        TAstN.LNOT: lambda x: ~x,
        TAstN.BVNEG: operator.neg
    }
    unop = unops.get(Ty, None)
    if unop != None:
        return unop(next(children))

    binops = {
        TAstN.BVADD: operator.add,
        TAstN.BVSUB: operator.sub,
        TAstN.BVAND: operator.and_,
        TAstN.BVOR: operator.or_,
        TAstN.BVXOR: operator.xor,
        TAstN.BVMUL: operator.mul,
        TAstN.BVNAND: lambda x, y: ~(x & y),
        TAstN.BVNOR: lambda x, y: ~(x | y),
        TAstN.BVXNOR: lambda x, y: ~(x ^ y),
        TAstN.BVUDIV: lambda x, y: x.udiv(y),
        TAstN.BVSDIV: lambda x, y: x.sdiv(y),
        TAstN.LAND: operator.and_,
        TAstN.LOR: operator.or_
    }
    binop = binops.get(Ty, None)
    if binop != None:
        return reduce(binop, children)

    # Logical op
    lops = {
        TAstN.EQUAL: lambda x, y: EX.ExprCmpEq(x, y),
        TAstN.DISTINCT: lambda x, y: EX.ExprCmpNeq(x, y),
        TAstN.BVUGE: lambda x, y: EX.ExprCmpGte(x, y, False),
        TAstN.BVUGT: lambda x, y: EX.ExprCmpGt(x, y, False),
        TAstN.BVULE: lambda x, y: EX.ExprCmpLte(x, y, False),
        TAstN.BVULT: lambda x, y: EX.ExprCmpLt(x, y, False),
        TAstN.BVSGE: lambda x, y: EX.ExprCmpGte(x, y, True),
        TAstN.BVSGT: lambda x, y: EX.ExprCmpGt(x, y, True),
        TAstN.BVSLE: lambda x, y: EX.ExprCmpLte(x, y, True),
        TAstN.BVSLT: lambda x, y: EX.ExprCmpLt(x, y, True)
    }
    lop = lops.get(Ty, None)
    if lop != None:
        return reduce(lop, children)

    # Conditional
    if Ty != TAstN.ITE:
        raise ValueError("unsupported node type %s" % str(Ty))
    return EX.ExprCond(next(children), next(children), next(children))
예제 #10
0
 def test_leaves(self):
     self.exprEqual(self.x4_expr, self.x4)
     self.exprEqual(EX.ExprCst(0xff, 4), self.mba4.from_cst(0xff))
예제 #11
0
    def test_extract_contract(self):
        self.exprEqual(EX.ExprSlice(self.x8_expr, slice(0, 4)), self.x4)

        self.exprEqual(EX.ExprConcat(EX.ExprCst(0xf, 4), EX.ExprCst(0, 4)),
                       self.mba8.from_cst(0x0f))
예제 #12
0
    def test_zx_sx(self):
        self.exprEqual(EX.ExprZX(EX.ExprCst(0xf, 4), 8),
                       self.mba8.from_cst(0x0f))

        self.exprEqual(EX.ExprSX(EX.ExprCst(0x8, 4), 8),
                       self.mba8.from_cst(0xf8))
예제 #13
0
파일: llvm.py 프로젝트: whb224117/arybo
 def test_shifts(self):
     for op in (EX.ExprShl,EX.ExprLShr,EX.ExprRor,EX.ExprRol):
         for n in range(8):
             e = op(self.ex, EX.ExprCst(n, 8))
             self.check_expr(e, [self.x])
예제 #14
0
파일: identify.py 프로젝트: whb224117/arybo
 def test_identify_xor_and(self):
     e = (self.x&0x7F)^0xAA
     self.check(e, EX.ExprXor(EX.ExprAnd(self.ex, EX.ExprCst(0x7F, 8)), EX.ExprCst(0xAA,8)))
예제 #15
0
파일: identify.py 프로젝트: whb224117/arybo
 def test_identify_xor(self):
     e = self.x&0xAA
     self.check(e, EX.ExprAnd(self.ex, EX.ExprCst(0xAA, 8)))