Package: pyafl-qemu-trace
pyafl_qemu_tracepip-installable afl-qemu-trace python packageInstallationpython3-mpipinstallpyafl-qemu-traceIf you would like to install the trace viewer for binaryninja:mkdir-p~/.binaryninja/plugins/trace_viewer/
cputilities/trace_viewer.py~/.binaryninja/plugins/trace_viewer/__init__.pyBuildingNote: donottry to publish sdist! Only wheels will work since we are distributing
binaries.If you would like to build this package, clone it and runpoetry build -f wheel.You will need to havepoetry,docker, anddocker-composeordocker compose(v2)
installed.To build multiple versions (if you have multiple python versions installed) just:$deactivate
$poetryenvuse3.8
$poetrybuild-fwheel
<...snip...forasmanyversionsasyouneed...>
$deactivate
$poetryenvuse3.9
$poetrybuild-fwheel
$poetrypublishFeaturesThis tool is meant to be, for the most part, dependency free and provided as a
binary-only package to be used as a component of other tools. However, there are a few
features beyond what theinspirationprovided.Improved trace parsing -- parses more events from the trace and eschews YACC for regexFaster throughput -- uses pipes to collect data from afl-qemu-trace instead of going
through the filesystem for super fast readsHas some test cases!There is also a loader for Binary Ninjaherethat can load
parsedTraceResultoutputs that have been serialized to JSON withTraceResult.exportand display them as a heatmap on the CFG as shown below:ExamplesGeneral Usagefrompyafl_qemu_traceimportqemu_path# Get the path to the tracer binarytracer=qemu_path("x86_64")# Run the tracer with the provided wrapperfrompyafl_qemu_traceimportTraceRunnerfromshutilimportwhichretcode,stdout,stderr,log=TraceRunner.run("x86_64",which("xxd"),cwd="/tmp",input_data="\x41"*400,timeout=10)# Parse the output of the tracer into a programmatically# workable data structure resultfrompyafl_qemu_traceimportTraceParserresult=TraceParser.parse(log)print(f"The trace has{len(result.addrs)}instructions!")Export trace for viweing```pythonfrompyafl_qemu_traceimportTraceRunner,TraceParserfromshutilimportwhichfrompathlibimportPathretcode,stdout,stderr,log=TraceRunner.run("x86_64",which("xxd"),cwd="/tmp",input_data="\x41"*400,timeout=10)result=TraceParser.parse(log)result.export(Path("/tmp/trace.json"))This trace can then be loaded into binaryninja withthe provided trace viewerby pickingTools -> Plugins -> Open File (QEMU Format)and selecting the exported JSON file.Embarrasingly Parallel Tracingfromconcurrent.futuresimportas_completed,ThreadPoolExecutorfrompyafl_qemu_traceimportTraceRunner,TraceParserfromshutilimportwhich# .41s to run this...not bad!withThreadPoolExecutor()asexecutor:futures=[]forain(b"\x41",b"\x42",b"\x43",b"\x44",b"\x45",b"\x46",b"\x47",b"\x48",):futures.append(executor.submit(TraceRunner.run,"x86_64",which("xxd"),input_data=a*400,ld_library_paths=["/lib64","/lib"],timeout=5,))forfutureinas_completed(futures):try:retcode,stdout,stderr,log=future.result()print(f"Completed with:{retcode}and loglength{len(log)}")assertlen(log)==8872190exceptExceptionase:assertFalse,"Exception:{}".format(e)Embarrasingly Parallel Tracing And Parsing(Seetest_parse_multi_parallel_real_x86_64for an example
that parallelizes the parsing step as well)RequirementsEitherdocker-composeordocker composeshould be available at build time, but when
installing, no dependencies are required, this basically just downloads a bunch of
binaries for you.TestingTests can be run withpoetry run pytest, you'll need to runpoetry installfirst.Profiling with memray can be added to tests by runningpoetry run pytest --memray.TargetsSupported targets forafl-qemu-traceare as follows:aarch64armi386mipsmips64ppcppc64riscv32riscv64x86_64