示例#1
0
     [
         0x37, 0x8e, 0xe7, 0x67, 0xf1, 0x16, 0x31, 0xba, 0xd2, 0x13, 0x80,
         0xb0, 0x04, 0x49, 0xb1, 0x7a, 0xcd, 0xa4, 0x3c, 0x32, 0xbc, 0xdf,
         0x1d, 0x77, 0xf8, 0x20, 0x12, 0xd4, 0x30, 0x21, 0x9f, 0x9b, 0x5d,
         0x80, 0xef, 0x9d, 0x18, 0x91, 0xcc, 0x86, 0xe7, 0x1d, 0xa4, 0xaa,
         0x88, 0xe1, 0x28, 0x52, 0xfa, 0xf4, 0x17, 0xd5, 0xd9, 0xb2, 0x1b,
         0x99, 0x48, 0xbc, 0x92, 0x4a, 0xf1, 0x1b, 0xd7, 0x20
     ]]

from arybo.lib import MBA, simplify, simplify_inplace
from pytanque import symbol, Vector
import copy, random, sys
mba8 = MBA(8)
mba64 = MBA(64)

data = [mba8.from_cst(random.randint(0, 255)) for i in range(32)]
nbits = int(sys.argv[1])
idxes = list(range(nbits))
random.shuffle(idxes)
for i in range(nbits):
    data[idxes[i]].vec[random.randint(0, 7)] = symbol("i%d" % i)
sbox_E, X = mba8.permut2expr(sbox)
sbox = sbox_E.vectorial_decomp([X])


def S(K):
    return [mba8.from_vec(simplify_inplace(sbox(K[i].vec))) for i in range(64)]


def P(K):
    return [K[tau[i]] for i in range(64)]
示例#2
0
    return b


def xor(a, b):
    return [a[i] ^ b[i] for i in range(16)]


def even_mansour(block, key):
    block = xor(block, key[:16])
    block = f(block)
    block = xor(block, key[16:])
    return block


block = [mba8.var('b%d' % i) for i in range(16)]
key_zero = [mba8.from_cst(0)] * 32
cipher = even_mansour(block, key_zero)
cipher = flatten_vec(cipher)

CZ = mba128.from_vec(cipher).vectorial_decomp(block)
Minv = CZ.matrix().inverse()


def recover(plaintext, cipher_plaintext, cipher_unk):
    plaintext = mba128.from_bytes(plaintext)
    cipher_plaintext = mba128.from_bytes(cipher_plaintext)
    cipher_unk = mba128.from_bytes(cipher_unk)

    tmp = mba128.from_vec(
        simplify(Minv * ((cipher_plaintext ^ cipher_unk).vec)))
    return (plaintext ^ tmp).to_bytes()
示例#3
0
class TritonTest():
    def setUp(self):
        # Initialize the engine
        TT.setArchitecture(TT.ARCH.X86)

        self.mba8 = MBA(8)
        self.mba16 = MBA(16)
        self.mba8.use_esf = True
        self.mba16.use_esf = True
        # Useful variables using duringtests
        self.x8_t = TAst.variable(TT.newSymbolicVariable(8))
        self.y8_t = TAst.variable(TT.newSymbolicVariable(8))
        self.x16_t = TAst.variable(TT.newSymbolicVariable(16))
        self.y16_t = TAst.variable(TT.newSymbolicVariable(16))
        self.x8 = self.mba8.var(self.x8_t.getValue())
        self.y8 = self.mba8.var(self.y8_t.getValue())
        self.x16 = self.mba16.var(self.x16_t.getValue())
        self.y16 = self.mba16.var(self.y16_t.getValue())

    # Helpers
    def astEquals(self, ast, v):
        if self.use_expr:
            e = tritonast2arybo(ast, use_exprs=True, use_esf=False)
            e = eval_expr(e, use_esf=False)
            v = expand_esf_inplace(v)
            v = simplify_inplace(v)
        else:
            e = tritonast2arybo(ast, use_exprs=False, use_esf=True)
        self.assertEqual(e, v)

    # Tests
    def test_leaves(self):
        c = random.choice(range(0xff))
        self.astEquals(TAst.bv(c, 8), self.mba8.from_cst(c))

        self.astEquals(self.x8_t, self.x8)

    def test_zx_sx(self):
        self.astEquals(TAst.zx(8, TAst.bv(0xff, 8)),
                       self.mba16.from_cst(0x00ff))

        self.astEquals(TAst.sx(8, TAst.bv(0xff, 8)),
                       self.mba16.from_cst(0xffff))

    def test_extract_contract(self):
        self.astEquals(TAst.extract(7, 0, TAst.bv(0xffff, 16)),
                       self.mba8.from_cst(0xff))

        self.astEquals(TAst.concat([TAst.bv(0xff, 8),
                                    TAst.bv(0x00, 8)]),
                       self.mba16.from_cst(0xff00))

    def test_unaryops(self):
        self.astEquals(TAst.bvnot(self.x8_t), ~self.x8)

        self.astEquals(TAst.bvneg(self.x8_t), -self.x8)

    def test_binaryops(self):
        ops = ((TAst.bvadd, operator.add), (TAst.bvsub, operator.sub),
               (TAst.bvand, operator.and_), (TAst.bvor, operator.or_),
               (TAst.bvxor, operator.xor), (TAst.bvmul, operator.mul),
               (TAst.bvnand, lambda x, y: ~(x & y)),
               (TAst.bvnor, lambda x, y: ~(x | y)), (TAst.bvxnor,
                                                     lambda x, y: ~(x ^ y)))
        for op in ops:
            self.astEquals(op[0](self.x8_t, self.y8_t), op[1](self.x8,
                                                              self.y8))

        # One udiv test because it can take a lot of time...
        e = TAst.bvudiv(self.x8_t, TAst.bv(15, 8))
        self.astEquals(e, self.x8.udiv(15))

    def test_shifts(self):
        # Triton interface is not consistant between sh{r,l} and ro{l,r}.
        # For the first kind, it can take any AstNode. For the second one, an
        # integer is forced.
        ops = (
            (TAst.bvlshr, operator.rshift),
            (TAst.bvshl, operator.lshift),
        )
        for op in ops:
            for s in range(9):
                self.astEquals(op[0](self.x8_t, TAst.bv(s, 8)), op[1](self.x8,
                                                                      s))

        ops = ((TAst.bvrol, lambda x, n: x.rol(n)), (TAst.bvror,
                                                     lambda x, n: x.ror(n)))
        for op in ops:
            for s in range(9):
                self.astEquals(op[0](s, self.x8_t), op[1](self.x8, s))

    def test_mba(self):
        # x^y = (x+y) - ((x&y)<<1)
        e = TAst.bvsub(
            TAst.bvadd(self.x8_t, self.y8_t),
            TAst.bvshl(TAst.bvand(self.x8_t, self.y8_t), TAst.bv(1, 8)))
        ea = tritonast2arybo(e, use_exprs=False, use_esf=True)
        simplify_inplace(expand_esf_inplace(ea))
        self.assertEqual(ea, self.x8 ^ self.y8)

    def test_logical(self):
        e = TAst.equal(self.x8_t, self.y8_t)
        ea = tritonast2arybo(e, use_exprs=True, use_esf=False)
        ea = eval_expr(ea, use_esf=False)
        self.assertEqual(ea.nbits, 1)

    def test_exprs_xor_5C(self):
        # Based on djo's example

        # This is the xor_5C example compiled with optimisations for x86-4
        code = [
            "\x41\xB8\xE5\xFF\xFF\xFF",
            "\x89\xF8",
            "\xBA\x26\x00\x00\x00",
            "\x41\x0F\xAF\xC0",
            "\xB9\xED\xFF\xFF\xFF",
            "\x89\xC7",
            "\x89\xD0",
            "\x83\xEF\x09",
            "\x0F\xAF\xC7",
            "\x89\xC2",
            "\x89\xF8",
            "\x0F\xAF\xC1",
            "\xB9\x4B\x00\x00\x00",
            "\x8D\x44\x02\x2A",
            "\x0F\xB6\xC0",
            "\x89\xC2",
            "\xF7\xDA",
            "\x8D\x94\x12\xFF\x00\x00\x00",
            "\x81\xE2\xFE\x00\x00\x00",
            "\x01\xD0",
            "\x8D\x14\x00",
            "\x8D\x54\x02\x4D",
            "\x0F\xB6\xF2",
            "\x6B\xF6\x56",
            "\x83\xC6\x24",
            "\x83\xE6\x46",
            "\x89\xF0",
            "\x0F\xAF\xC1",
            "\xB9\xE7\xFF\xFF\xFF",
            "\x89\xC6",
            "\x89\xD0",
            "\xBA\x3A\x00\x00\x00",
            "\x0F\xAF\xC1",
            "\x89\xC1",
            "\x89\xD0",
            "\x8D\x4C\x0E\x76",
            "\xBE\x63\x00\x00\x00",
            "\x0F\xAF\xC1",
            "\x89\xC2",
            "\x89\xC8",
            "\x0F\xAF\xC6",
            "\x83\xEA\x51",
            "\xBE\x2D\x00\x00\x00",
            "\x83\xE2\xF4",
            "\x89\xC1",
            "\x8D\x4C\x0A\x2E",
            "\x89\xC8",
            "\x25\x94\x00\x00\x00",
            "\x01\xC0",
            "\x29\xC8",
            "\xB9\x67\x00\x00\x00",
            "\x0F\xAF\xC1",
            "\x8D\x48\x0D",
            "\x0F\xB6\xD1",
            "\x69\xD2\xAE\x00\x00\x00",
            "\x83\xCA\x22",
            "\x89\xD0",
            "\x41\x0F\xAF\xC0",
            "\x89\xC2",
            "\x89\xC8",
            "\x0F\xAF\xC6",
            "\x8D\x44\x02\xC2",
            "\x0F\xB6\xC0",
            "\x2D\xF7\x00\x00\x00",
            "\x69\xC0\xED\x00\x00\x00",
            "\x0F\xB6\xC0",
        ]

        TT.setArchitecture(TT.ARCH.X86_64)

        rdi = TT.convertRegisterToSymbolicVariable(TT.REG.RDI)
        rdi = tritonast2arybo(TAst.variable(rdi), use_exprs=False)

        for opcodes in code:
            inst = TT.Instruction(opcodes)
            TT.processing(inst)

        rax_ast = TT.buildSymbolicRegister(TT.REG.RAX)
        rax_ast = TT.getFullAst(rax_ast)
        rax_ast = TT.simplify(rax_ast, True)
        # Check that this gives a xor 5C
        e = tritonast2arybo(rax_ast, use_exprs=self.use_expr, use_esf=False)
        if self.use_expr:
            e = eval_expr(e)
        self.assertEqual(e, ((rdi & 0xff) ^ 0x5C).vec)
示例#4
0
class MBAExprsTest:
    def setUp(self):
        self.mba1 = MBA(1)
        self.mba4 = MBA(4)
        self.mba4.use_esf = False
        self.mba8 = MBA(8)
        self.mba8.use_esf = False

        self.x4 = self.mba4.var('x')
        self.y4 = self.mba4.var('y')
        self.z4 = self.mba4.var('z')
        self.x4_expr = EX.ExprBV(self.x4)
        self.y4_expr = EX.ExprBV(self.y4)
        self.z4_expr = EX.ExprBV(self.z4)

        self.x8 = self.mba8.var('x')
        self.y8 = self.mba8.var('y')
        self.z8 = self.mba8.var('z')

        self.x8_expr = EX.ExprBV(self.x8)
        self.y8_expr = EX.ExprBV(self.y8)
        self.z8_expr = EX.ExprBV(self.z8)

    def exprEqual(self, expr, e):
        expr = EX.eval_expr(expr, self.use_esf)
        if self.use_esf:
            expand_esf_inplace(expr.vec)
            simplify_inplace(expr.vec)
        simplify_inplace(e.vec)
        simplify_inplace(expr.vec)
        self.assertEqual(expr, e)

    def test_leaves(self):
        self.exprEqual(self.x4_expr, self.x4)
        self.exprEqual(EX.ExprCst(0xff, 4), self.mba4.from_cst(0xff))

    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))

    def test_unaryops(self):
        ops = (
            (EX.ExprXor, operator.xor),
            (EX.ExprAnd, operator.and_),
            (EX.ExprOr, operator.or_),
        )

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

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

    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))

    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))

    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))

    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))

    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))

    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)
示例#5
0
from arybo.lib import MBA, simplify, simplify_inplace
from arybo.tools import app_inverse

mba = MBA(32)

S, X = mba.permut2expr(S)
S = S.vectorial_decomp([X])


def compute_arybo(Z):
    C = mba.from_cst(0xFFFFFFFF)
    A = 0

    for N in range(0, 4):
        C_ = (C >> (A * 8)) & 0xFF
        Z_ = (Z >> (N * 8)) & 0xFF
        t = Z_ ^ C_
        T_ = mba.from_vec(simplify(S(t.vec)))
        B = C >> 8
        C = B ^ T_

    C = (~C)
    return simplify_inplace(C)


E = compute_arybo(X)
A = E.vectorial_decomp([X])
Ainv = app_inverse(A)
sol = mba.from_vec(simplify(Ainv(mba.from_cst(3298472535).vec))).to_cst()
print(sol)