Exemple #1
0
 def compute_logical(vec, X, Y, ctx, use_esf):
     nbits = X.nbits
     e = imm(1)
     for i in range(nbits):
         e *= X.eval(vec, i, use_esf) + Y.eval(vec, i, use_esf) + imm(1)
         simplify_inplace(e)
     return e
Exemple #2
0
 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)
Exemple #3
0
def find_esfs_degree(e, d):
    esfs = []
    while True:
        esf, anf_esf = find_one_esf(e, d)
        if esf is None:
            break
        e += anf_esf
        simplify_inplace(e)
        esfs.append(esf)
    return esfs
Exemple #4
0
 def compute(self, vec, i, args, ctx, use_esf):
     if ((self.mask >> i) & 1) == 1:
         return imm(1)
     args = list(args)
     ret = esf(1, args)
     for i in range(2, len(args) + 1):
         ret += esf(i, args)
     if not use_esf:
         expand_esf_inplace(ret)
         simplify_inplace(ret)
     return ret
Exemple #5
0
    def compute_binop_(vec, i, X, Y, CC, use_esf):
        carry = CC.carry

        sum_args = simplify_inplace(X + Y)
        ret = simplify_inplace(sum_args + carry)
        carry = esf(2, [X + imm(1), Y, carry])
        if not use_esf:
            expand_esf_inplace(carry)
            carry = simplify_inplace(carry)

        CC.carry = carry
        return ret
Exemple #6
0
    def compute_binop_(vec, i, X, Y, CC, use_esf):
        carry = CC.carry

        sum_args = simplify_inplace(X + Y)
        ret = simplify_inplace(sum_args + carry)
        # TODO: optimize this like in mba_if
        carry = esf(2, [X, Y, carry])
        if not use_esf:
            expand_esf_inplace(carry)
            simplify_inplace(carry)

        CC.carry = carry
        return ret
Exemple #7
0
def L(K):
    state = K
    for i in range(8):
        v = mba64.from_cst(0)
        for k in range(8):
            for j in range(8):
                v ^= mba64.from_vec(
                    mba64.from_cst(A[k * 8 + j]).vec *
                    state[i * 8 + k].vec[7 - j])
                simplify_inplace(v)

        for k in range(8):
            for b in range(8):
                state[i * 8 + k].vec[b] = simplify_inplace(v[(7 - k) * 8 + b])
    return state
Exemple #8
0
 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)
Exemple #9
0
def app_inverse(A):
    M = A.matrix()
    NL = A.nl()
    V = A.cst()
    Minv = M.inverse()
    if Minv.ncols() == 0:
        return None

    N = V.size()
    mba = MBA(N)
    Y = mba.var('Y')
    G0 = Minv * Y.vec + Minv * V
    G1nl = simplify_inplace(Minv * NL(Y.vec))

    # Check if G1 is inversible through a dependency graph
    DG = nx.DiGraph()
    idx_base = Y[0].sym_idx()
    for i, e in enumerate(G1nl):
        for d in get_depends_as_set(e):
            DG.add_edge(Y[i].sym_idx() - idx_base, d.sym_idx() - idx_base)

    if not nx.is_directed_acyclic_graph(DG):
        return None

    # Use the graph to get the inverse of G1
    X = mba.var('X')
    resolve_order = nx.topological_sort(DG, reverse=True)
    solved = dict()
    for i in resolve_order:
        e = G1nl[i]
        if e.is_imm() and e.imm_value() == 0:
            solved[i] = X[i]
        else:
            # Doing this in the reversed topological order should make this always work!
            solved[i] = simplify_inplace(X[i] + simplify_inplace(
                subs_exprs(G1nl[i], [Y[j] for j in six.iterkeys(solved)],
                           list(six.itervalues(solved)))))
    G1inv = Vector(N)
    for i in range(N):
        G1inv[i] = solved.get(i, X[i])
    G1inv = MBAVariable(mba, G1inv)
    Finv = G1inv.eval({X: G0})
    Finv = MBAVariable(mba, Finv)
    return Finv.vectorial_decomp([Y])
Exemple #10
0
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)
Exemple #11
0
def find_one_esf(e, d):
    h = SymbolsHist()
    h.compute(e, d)
    #for v in h: print(v)

    # "Invert" the histogram
    hinv = collections.defaultdict(list)
    max_count = 0
    for v in h:
        c = v.count()
        hinv[c].append(v.sym())
        if max_count < c: max_count = c
    #print(hinv)

    # Compute the maximum number of arguments for this degree
    nterms = 0
    for a in e.args():
        if a.is_mul() and a.args().size() == d:
            nterms += 1
    max_args = solve_binomial(d, nterms)
    #print("max_args: %d" % max_args)

    # Compute the exact counts we will search from
    counts_args = filter(lambda v: v[0] <= max_count,
                         ((int(binom(A - 1, d - 1)), A)
                          for A in reversed(range(d + 1, max_args + 1))))

    for ca in counts_args:
        c, nargs = ca
        #print(d,c)
        cur_args = []
        for i in range(c, max_count + 1):
            cur_args += hinv.get(i, [])
        if len(cur_args) < nargs:
            continue
        for A in reversed(range(nargs, max_args + 1)):
            #print(d, "test %d args among %d (%d)" % (A, len(cur_args), binom(len(cur_args),A)))
            # TODO: optimize this
            for args in itertools.combinations(cur_args, A):
                args = sorted(args)
                test_esf = esf(d, list(args))
                anf_esf = simplify_inplace(expand_esf(test_esf))
                if e.contains(anf_esf):
                    #print("[+] found", test_esf)
                    return test_esf, anf_esf
    return None, None
Exemple #12
0
def simp_inplace(L):
    for o in L:
        simplify_inplace(o)
    return L
Exemple #13
0
def xor512(A, B):
    return [simplify_inplace(A[i] ^ B[i]) for i in range(64)]
Exemple #14
0
def S(K):
    return [mba8.from_vec(simplify_inplace(sbox(K[i].vec))) for i in range(64)]
Exemple #15
0
def step(b):
    new = S((b[10] ^ b[12] ^ b[13] ^ b[15]).vec)
    new = mba8.from_vec(simplify_inplace(new))
    return [new] + b[:15]
Exemple #16
0
 def eval(self, vec, i, use_esf):
     return simplify_inplace(
         self.e.eval(vec, i, self.ctx, self.args, use_esf))
Exemple #17
0
 def compute_logical(vec, X, Y, ctx, use_esf):
     return simplify_inplace(
         ExprCmpEq.compute_logical(vec, X, Y, ctx, use_esf) + imm(1))