@@ -0,0 +1,2383 @@
+#!/usr/bin/env python%0A%0Aimport angr%0Aimport sys%0Aimport termcolor%0A%0Adef ok(s):%0A    status = termcolor.colored(%22*%22, %22cyan%22, attrs=%5B%22bold%22%5D)%0A    print %22%5B%25s%5D %25s%22 %25 (status, s)%0A%0Adef die(s):%0A    status = termcolor.colored(%22-%22, %22red%22, attrs=%5B%22bold%22%5D)%0A    print %22%5B%25s%5D %25s%22 %25 (status, s)%0A    sys.exit(1)%0A%0A%0Adef branch_for_input(branch, inputstream):%0A%0A    stdin_bytes = branch.state.posix.files%5B0%5D.all_bytes()%0A%0A    stdin_bytes_cnt = stdin_bytes.length / 8%0A%0A    padded = inputstream.ljust(stdin_bytes_cnt, %22%5Cx00%22)%0A    pad_cnt = 0%0A    constraints = %5B %5D %0A    for bit in range(0, stdin_bytes.length, 8)%5B::-1%5D:%0A        upper_bit = bit + 7%0A        constraints.append(stdin_bytes%5Bupper_bit:bit%5D == ord(padded%5Bpad_cnt%5D))%0A        pad_cnt += 1%0A%0A    return branch.state.se.satisfiable(extra_constraints = constraints)%0A%0Adef path_jump_targets(project, inputstream):%0A%0A%0A    next_branch = project.path_generator.entry_point()%0A%0A    while True:%0A        branches = windup_to_branch(next_branch)%0A%0A        if len(branches) == 0:%0A            return%0A%0A        branch1 = branches%5B0%5D%0A        branch2 = branches%5B1%5D%0A%0A        branch1_taker = branch_for_input(branch1, inputstream)%0A        branch2_taker = branch_for_input(branch2, inputstream)%0A%0A        assert not (branch1_taker and branch2_taker)%0A%0A        if branch1_taker:%0A            next_branch = branch1%0A        else:%0A            next_branch = branch2%0A%0A        print next_branch%0A%0A%0Adef windup_to_branch(path):%0A    '''%0A    windup the path until we hit our first branch, return a list of branches%0A    '''%0A%0A    current_path = path%0A    branches = %5B%5D%0A    while len(branches) %3C 2:%0A        branches = current_path.successors%0A        try:%0A            current_path = branches%5B0%5D%0A        except IndexError:%0A            return %5B%5D%0A%0A    return branches%0A%0Adef main(argc, argv):%0A    if (argc != 3):%0A        print %22usage: %25s %3Cbinary%3E %3Cinputfile%3E%22 %25 (argv%5B0%5D)%0A        return 1%0A%0A    binary = argv%5B1%5D%0A    inputfile = argv%5B2%5D%0A%0A    ok(%22drilling into %25s with inputfile %25s%22 %25 (binary, inputfile)) %0A    try:%0A        inputstream = open(inputfile).read()%0A    except IOError:%0A        die(%22file %5C%22%25s%5C%22 does not exist%22 %25 inputfile)%0A%0A    project = angr.Project(binary)%0A    entry_point = project.path_generator.entry_point()%0A%0A    ok(%22entry point found at 0x%25x%22 %25 entry_point.addr)%0A%0A    print path_jump_targets(project, inputstream)%0A%0A%0Aif __name__ == %22__main__%22:%0A    sys.exit(main(len(sys.argv), sys.argv))%0A

Add input tracing