| 57 | |
| 58 | # Define a background thread object for solving in the background |
| 59 | class Solver(BackgroundTaskThread): |
| 60 | def __init__(self, find, avoid, view): |
| 61 | BackgroundTaskThread.__init__(self, "Solving with angr...", True) |
| 62 | self.find = tuple(find) |
| 63 | self.avoid = tuple(avoid) |
| 64 | self.view = view |
| 65 | |
| 66 | # Write the binary to disk so that the angr API can read it |
| 67 | self.binary = tempfile.NamedTemporaryFile() |
| 68 | self.binary.write(view.file.raw.read(0, len(view.file.raw))) |
| 69 | self.binary.flush() |
| 70 | |
| 71 | def run(self): |
| 72 | # Create an angr project and an explorer with the user's settings |
| 73 | p = angr.Project(self.binary.name) |
| 74 | e = p.surveyors.Explorer(find=self.find, avoid=self.avoid) |
| 75 | |
| 76 | # Solve loop |
| 77 | while not e.done: |
| 78 | if self.cancelled: |
| 79 | # Solve cancelled, show results if there were any |
| 80 | if len(e.found) > 0: |
| 81 | break |
| 82 | return |
| 83 | |
| 84 | # Perform the next step in the solve |
| 85 | e.step() |
| 86 | |
| 87 | # Update status |
| 88 | active_count = len(e.active) |
| 89 | found_count = len(e.found) |
| 90 | |
| 91 | progress = "Solving with angr (%d active path%s" % (active_count, "s" if active_count != 1 else "") |
| 92 | if found_count > 0: |
| 93 | progress += ", %d path%s found" % (found_count, "s" if found_count != 1 else "") |
| 94 | self.progress = progress + ")..." |
| 95 | |
| 96 | # Solve complete, show report |
| 97 | text_report = "Found %d path%s.\n\n" % (len(e.found), "s" if len(e.found) != 1 else "") |
| 98 | i = 1 |
| 99 | for f in e.found: |
| 100 | text_report += "Path %d\n"%i + "="*10 + "\n" |
| 101 | text_report += "stdin:\n" + escaped_output(f.state.posix.dumps(0)) + "\n\n" |
| 102 | text_report += "stdout:\n" + escaped_output(f.state.posix.dumps(1)) + "\n\n" |
| 103 | text_report += "stderr:\n" + escaped_output(f.state.posix.dumps(2)) + "\n\n" |
| 104 | i += 1 |
| 105 | |
| 106 | name = self.view.file.filename |
| 107 | if len(name) > 0: |
| 108 | show_plain_text_report("Results from angr - " + os.path.basename(self.view.file.filename), text_report) |
| 109 | else: |
| 110 | show_plain_text_report("Results from angr", text_report) |
| 111 | |
| 112 | |
| 113 | def find_instr(bv, addr): |