about summary refs log tree commit diff stats
path: root/gen_trace.py
diff options
context:
space:
mode:
authorTheofilos Augoustis <theofilos.augoustis@gmail.com>2023-10-21 16:39:49 +0200
committerTheofilos Augoustis <theofilos.augoustis@gmail.com>2023-10-21 16:39:49 +0200
commit6f01367f9c8ad4c3d641cc63dbb1a3977ff4ec56 (patch)
tree5b9677b9a5cca449497cea4418b2bb10e2ab0509 /gen_trace.py
parent83d4b4dbe6f20c2fa7865e4888b89e888d3509f9 (diff)
downloadfocaccia-6f01367f9c8ad4c3d641cc63dbb1a3977ff4ec56.tar.gz
focaccia-6f01367f9c8ad4c3d641cc63dbb1a3977ff4ec56.zip
Support for testing concrete and emulated execution with angr
Diffstat (limited to '')
-rw-r--r--gen_trace.py50
1 files changed, 50 insertions, 0 deletions
diff --git a/gen_trace.py b/gen_trace.py
new file mode 100644
index 0000000..64fcf8f
--- /dev/null
+++ b/gen_trace.py
@@ -0,0 +1,50 @@
+import argparse
+import lldb
+import lldb_target
+
+def parse_args():
+    prog = argparse.ArgumentParser()
+    prog.add_argument('binary',
+                      help='The executable to trace.')
+    prog.add_argument('-o', '--output',
+                      default='breakpoints',
+                      type=str,
+                      help='File to which the recorded trace is written.')
+    prog.add_argument('--args',
+                      default=[],
+                      nargs='+',
+                      help='Arguments to the executable.')
+    return prog.parse_args()
+
+def record_trace(binary: str, args: list[str] = []) -> list[int]:
+    # Set up LLDB target
+    target = lldb_target.LLDBConcreteTarget(binary, args)
+
+    # Skip to first instruction in `main`
+    result = lldb.SBCommandReturnObject()
+    break_at_main = f'b -b main -s {target.module.GetFileSpec().GetFilename()}'
+    target.interpreter.HandleCommand(break_at_main, result)
+    target.run()
+
+    # Run until main function is exited
+    trace = []
+    while not target.is_exited():
+        thread = target.process.GetThreadAtIndex(0)
+        func_names = [thread.GetFrameAtIndex(i).GetFunctionName() for i in range(0, thread.GetNumFrames())]
+        if 'main' not in func_names:
+            break
+        trace.append(target.read_register('pc'))
+        thread.StepInstruction(False)
+
+    return trace
+
+def main():
+    args = parse_args()
+    trace = record_trace(args.binary, args.args)
+    with open(args.output, 'w') as file:
+        for addr in trace:
+            print(hex(addr), file=file)
+    print(f'Generated a trace of {len(trace)} instructions.')
+
+if __name__ == '__main__':
+    main()