예제 #1
0
def calls_test():
    os.system("gcc ../tests/simple_cond_call_cond.c -o ../test -O0 -g")

    proj = angr.Project("../test")
    testscope = GlobalScope(proj)

    # General condition
    allowed = ASTNode(Operator.VAR,
                      ["allowed", ExprType(Type.BV8, 0), testscope])
    one_node = ASTNode(Operator.LITERAL, [1, ExprType(Type.BV8, 0)])

    cond = ASTNode(Operator.EQ, [allowed, one_node])

    evt = CallEvent(proj.loader.find_symbol("special"), testscope, cond,
                    "CALL(special) -> allowed == 1")

    return Engine(proj, [evt])
예제 #2
0
def return_test():
    os.system("gcc ../tests/return.c -o ../test -O0 -g")

    proj = angr.Project("../test")
    testscope = GlobalScope(proj)

    # General Condition
    retn_node = ASTNode(Operator.RETN, [ExprType(Type.BV32, 0)])
    val_node = ASTNode(Operator.VAR,
                       ["val", ExprType(Type.BV32, 0), testscope])

    cond = ASTNode(Operator.GT, [retn_node, val_node])

    evt = ReturnEvent(
        proj.loader.find_symbol("main").rebased_addr, testscope, cond,
        "RETURN() -> RETURN_VAL() > val")

    return Engine(proj, [evt])
예제 #3
0
def locals_test():
    os.system("gcc ../tests/locals.c -o ../test -O0 -g")

    proj = angr.Project("../test")
    testscope = GlobalScope(proj)
    funcscope = FunctionScope(proj, "func")

    # General Condition
    local_node = ASTNode(
        Operator.VAR,
        ["local", ExprType(Type.BV32, signed=True), funcscope])
    arg_node = ASTNode(
        Operator.VAR,
        ["arg", ExprType(Type.BV32, signed=True), funcscope])
    next_node = ASTNode(Operator.NEXT, [local_node])

    cond = ASTNode(Operator.GT, [local_node, arg_node])

    evt = ReturnEvent(
        proj.loader.find_symbol("func").rebased_addr, funcscope, cond,
        "WRITE(local) -> NEXT(local) > arg")

    return Engine(proj, [evt])
예제 #4
0
def arrays_test():
    os.system("gcc ../tests/arrays.c -o ../test -O0 -g")

    proj = angr.Project("../test")
    testscope = GlobalScope(proj)

    # # General Condition
    arr_node = ASTNode(Operator.VAR,
                       ["arr", ExprType(Type.BV32, 0), testscope])
    idx_node = ASTNode(Operator.VAR,
                       ["idx", ExprType(Type.BV32, 0), testscope])
    two_node = ASTNode(Operator.LITERAL, [2, ExprType(Type.BV32, 0)])

    arr_index_two_node = ASTNode(Operator.INDEX, [arr_node, two_node])
    arr_index_idx_node = ASTNode(Operator.INDEX, [arr_node, idx_node])
    next_node = ASTNode(Operator.NEXT, [arr_index_two_node])

    cond = ASTNode(Operator.LE, [arr_index_idx_node, next_node])
    print("General Constraint: " + cond.stringify())

    evt = WriteEvent(arr_index_two_node, testscope, cond,
                     "WRITE(arr[2]) -> arr[idx] <= NEXT(arr[2])")

    return Engine(proj, [evt])
예제 #5
0
def write_next_test():
    os.system("gcc ../tests/next_definition.c -o ../test -O0 -g")

    proj = angr.Project("../test")
    testscope = GlobalScope(proj)

    # General condition
    var_name = "pUID"
    var_type = ExprType(Type.BV32, 1)
    var_scope = testscope
    var_node = ASTNode(Operator.VAR, [var_name, var_type, var_scope])
    deref_node = ASTNode(Operator.DEREF, [var_node])
    next_node = ASTNode(Operator.NEXT, [deref_node])
    cond = ASTNode(Operator.GE, [next_node, deref_node])
    print("General Contraint: " + cond.stringify())

    # Create the event
    evt = WriteEvent(deref_node, testscope, cond,
                     "WRITE(*pUID) -> NEXT(*pUID) >= *pUID")

    return Engine(proj, [evt])
예제 #6
0
def parse_tree(tree, variables):
    if isinstance(tree, InvariantParser.FunAppExprContext):
        func_tok = tree.getChild(0)
        if func_tok.getChild(0) is None:
            func_name = func_tok.symbol.text
        else:
            func_name = func_tok.getChild(0).symbol.text
        assert(func_name == "NEXT" or func_name == "RETURN_VAL")
        if func_name == "NEXT":
            operand_one = parse_tree(tree.getChild(2), variables)
            return ASTNode(Operator.NEXT, [operand_one])
        else:
            type_tok = tree.getChild(2)
            if type_tok.getChild(0) is None:
                type_name = type_tok.symbol.text
            else:
                type_name = type_tok.getChild(0).symbol.text
            operand_one = get_type_from_str(type_name)
            return ASTNode(Operator.RETN, [operand_one])
    elif isinstance(tree, InvariantParser.IndexExprContext):
        operand_one = parse_tree(tree.getChild(0), variables)
        operand_two = parse_tree(tree.getChild(2), variables)
        return ASTNode(Operator.INDEX, [operand_one, operand_two])
    op = int((tree.getChildCount() - 1) / 2)
    token = tree.getChild(op)
    if token is None:
        if re.fullmatch('[0-9]+', tree.symbol.text):
            return ASTNode(Operator.LITERAL, [int(tree.symbol.text),
                                              ExprType(Type.BV64, pointers=0,
                                                       signed=int(tree.symbol.text) <= 2 ** 63 - 1)])
        else:
            if tree.symbol.text == "true" or tree.symbol.text == "false":
                return ASTNode(Operator.LITERAL, [tree.symbol.text == "true", ExprType(Type.BOOL, 0)])
            assert(tree.symbol.text in variables)
            return ASTNode(Operator.VAR,
                           [tree.symbol.text, variables[tree.symbol.text][0], variables[tree.symbol.text][1]])
    if token.symbol.text == "+":
        operand_one = parse_tree(tree.getChild(0), variables)
        operand_two = parse_tree(tree.getChild(2), variables)
        operator = Operator.PLUS
        return ASTNode(operator, [operand_one, operand_two])
    elif token.symbol.text == "-":
        if tree.getChildCount == 3:
            operand_one = parse_tree(tree.getChild(0), variables)
            operand_two = parse_tree(tree.getChild(2), variables)
            operator = Operator.MINUS
            return ASTNode(operator, [operand_one, operand_two])
        else:
            operand_one = ASTNode(Operator.LITERAL, ['0', ExprType(Type.BV64, 0)])
            operand_two = parse_tree(tree.getChild(1), variables)
            operator = Operator.MINUS
            return ASTNode(operator, [operand_one, operand_two])
    elif token.symbol.text == '*':
        if tree.getChildCount() == 3:
            operand_one = parse_tree(tree.getChild(0), variables)
            operand_two = parse_tree(tree.getChild(2), variables)
            operator = Operator.TIMES
            return ASTNode(operator, [operand_one, operand_two])
        else:
            operand_one = parse_tree(tree.getChild(1), variables)
            operator = Operator.DEREF
            return ASTNode(operator, [operand_one])
    elif token.symbol.text == '/':
        operand_one = parse_tree(tree.getChild(0), variables)
        operand_two = parse_tree(tree.getChild(2), variables)
        operator = Operator.DIVIDE
        return ASTNode(operator, [operand_one, operand_two])
    elif token.symbol.text == '&':
        operand_one = parse_tree(tree.getChild(0), variables)
        operand_two = parse_tree(tree.getChild(2), variables)
        operator = Operator.BAND
        return ASTNode(operator, [operand_one, operand_two])
    elif token.symbol.text == '|':
        operand_one = parse_tree(tree.getChild(0), variables)
        operand_two = parse_tree(tree.getChild(2), variables)
        operator = Operator.BOR
        return ASTNode(operator, [operand_one, operand_two])
    elif token.symbol.text == '^':
        operand_one = parse_tree(tree.getChild(0), variables)
        operand_two = parse_tree(tree.getChild(2), variables)
        operator = Operator.BXOR
        return ASTNode(operator, [operand_one, operand_two])
    elif token.symbol.text == '==':
        operand_one = parse_tree(tree.getChild(0), variables)
        operand_two = parse_tree(tree.getChild(2), variables)
        operator = Operator.EQ
        return ASTNode(operator, [operand_one, operand_two])
    elif token.symbol.text == '!=':
        operand_one = parse_tree(tree.getChild(0), variables)
        operand_two = parse_tree(tree.getChild(2), variables)
        operator = Operator.NEQ
        return ASTNode(operator, [operand_one, operand_two])
    elif token.symbol.text == '>':
        operand_one = parse_tree(tree.getChild(0), variables)
        operand_two = parse_tree(tree.getChild(2), variables)
        operator = Operator.GT
        return ASTNode(operator, [operand_one, operand_two])
    elif token.symbol.text == '<':
        operand_one = parse_tree(tree.getChild(0), variables)
        operand_two = parse_tree(tree.getChild(2), variables)
        operator = Operator.LT
        return ASTNode(operator, [operand_one, operand_two])
    elif token.symbol.text == '>=':
        operand_one = parse_tree(tree.getChild(0), variables)
        operand_two = parse_tree(tree.getChild(2), variables)
        operator = Operator.GE
        return ASTNode(operator, [operand_one, operand_two])
    elif token.symbol.text == '<=':
        operand_one = parse_tree(tree.getChild(0), variables)
        operand_two = parse_tree(tree.getChild(2), variables)
        operator = Operator.LE
        return ASTNode(operator, [operand_one, operand_two])
    elif token.symbol.text == '&&':
        operand_one = parse_tree(tree.getChild(0), variables)
        operand_two = parse_tree(tree.getChild(2), variables)
        operator = Operator.LAND
        return ASTNode(operator, [operand_one, operand_two])
    elif token.symbol.text == '||':
        operand_one = parse_tree(tree.getChild(0), variables)
        operand_two = parse_tree(tree.getChild(2), variables)
        operator = Operator.LOR
        return ASTNode(operator, [operand_one, operand_two])
    elif token.symbol.text == '!':
        operand_one = parse_tree(tree.getChild(1), variables)
        operator = Operator.LNOT
        return ASTNode(operator, [operand_one])
    elif token.symbol.text == '~':
        operand_one = parse_tree(tree.getChild(1), variables)
        operator = Operator.BNOT
        return ASTNode(operator, [operand_one])
    elif re.fullmatch('[0-9]+', token.symbol.text):
        return ASTNode(Operator.LITERAL,
                       [int(token.symbol.text), ExprType(Type.BV64, pointers=0, signed=int(token.symbol.text) <= 2 ** 63 - 1)])
    else:
        if token.symbol.text == "true" or token.symbol.text == "false":
            return ASTNode(Operator.LITERAL, [token.symbol.text == "true", ExprType(Type.BOOL, 0)])
        assert (token.symbol.text in variables)
        return ASTNode(Operator.VAR,
                       [token.symbol.text, variables[token.symbol.text][0], variables[token.symbol.text][1]])
예제 #7
0
def operators_test():
    solver = claripy.Solver()

    sym_one = claripy.BVS("one", 32)
    sym_uone = claripy.BVS("uone", 8)
    sym_zero = claripy.BVS("zero", 32)
    sym_neg_one = claripy.BVS("neg_one", 32)
    sym_uint_max = claripy.BVS("uint_max", 32)

    solver.add(sym_one == 1)
    solver.add(sym_uone == 1)
    solver.add(sym_zero == 0)
    solver.add(sym_neg_one == -1)
    solver.add(sym_uint_max == (2**32) - 1)

    one_node = ASTNode(Operator.LITERAL,
                       [sym_one, ExprType(Type.BV32, signed=True)])
    uone_node = ASTNode(Operator.LITERAL,
                        [sym_uone, ExprType(Type.BV8, signed=False)])
    zero_node = ASTNode(Operator.LITERAL,
                        [sym_zero, ExprType(Type.BV32, signed=True)])
    neg_one_node = ASTNode(
        Operator.LITERAL,
        [sym_neg_one, ExprType(Type.BV32, signed=True)])
    uint_max_node = ASTNode(
        Operator.LITERAL,
        [sym_uint_max, ExprType(Type.BV32, signed=False)])

    one_eq_zero_node = ASTNode(Operator.NEQ, [one_node, zero_node])
    check(solver, one_eq_zero_node.get_sym(None))

    neg_one_eq_uint_max_node = ASTNode(Operator.NEQ,
                                       [neg_one_node, uint_max_node])
    check(solver, neg_one_eq_uint_max_node.get_sym(None))

    uone_eq_one_node = ASTNode(Operator.EQ, [one_node, uone_node])
    check(solver, uone_eq_one_node.get_sym(None))

    sum_node = ASTNode(Operator.PLUS, [one_node, neg_one_node])
    sum_zero_node = ASTNode(Operator.EQ, [sum_node, zero_node])
    check(solver, sum_zero_node.get_sym(None))

    sub_node = ASTNode(Operator.MINUS, [zero_node, neg_one_node])
    sub_one_node = ASTNode(Operator.EQ, [sub_node, one_node])
    check(solver, sub_one_node.get_sym(None))

    mul_node = ASTNode(Operator.MUL, [neg_one_node, neg_one_node])
    mul_one_node = ASTNode(Operator.EQ, [mul_node, one_node])
    check(solver, mul_one_node.get_sym(None))

    xor_node = ASTNode(Operator.BXOR, [uint_max_node, neg_one_node])
    xor_zero_node = ASTNode(Operator.EQ, [xor_node, zero_node])
    check(solver, xor_zero_node.get_sym(None))