Skip to content

lks9/src-tracer

Repository files navigation

Source Tracer

This is a draft of a control flow tracer based on source code instrumentation with a low overhead. Instrument your software with instrumenter.py. When running instrumented software, the trace is written into a file. The format is basically one character (plus an optional number) for each source code block on the trace. For accurate retracing, retrace.py uses symbolic execution.

Which Software to Trace

Any software which is written in C/C++, with the source code available.

Dependencies

For the Instrumentation

  • python3
  • libclang (pip install libclang)

For the Trace Recording

  • C compiler (or your build system at choice) to compile the instrumented software

For the Symbolic Replayer

  • C compiler (or your build system at choice) to compile the instrumented software
  • python3
  • angr for symbolic execution (pip install angr)

Setup

  • Run make
    make
    
  • Install the python package
    pip install .
    

Example checksum.c

  • Optionally: Change configuration in include/src_tracer/constants.h.

  • Load the environmental variables

    source env.sh
    
  • First run the pre-processor

    cd examples/
    cpp -I${SRC_TRACER_INCL} checksum.c -o checksum.i
    
  • Instrument it (the pre-processed version)

    instrumenter.py checksum.i -o checksum_inst.c
    

    For a list of functions together with the num generated by the instrumenter, have a look at the newly created functions_database.db.

Recording

  • Compile it with _TRACE_MODE
    gcc -D_TRACE_MODE -L${SRC_TRACER_LIB} -I${SRC_TRACER_INCL} checksum_inst.c -o checksum_trace -lsrc_tracer
    
    • Note: you might want to use a diferent compiler like clang instead of gcc
    • Note: you might also want compiler optimizations like -O3 for recording/replaying
    • Note: if you enabled TRACEFORK_ZSTD in include/src_tracer/constants.h, you would need -lzstd here
  • Run it (replace 42 to get another trace)
    ./checksum_trace 42
    
    The name of the recorded trace corresponds to the current time, e.g. 2023-04-28-143402-checksum.c.trace.
  • Display the trace (replace the trace name with the correct one!)
    print_trace.py 2023-04-28-143402-checksum.c.trace
    
    • Note: if you enabled TRACEFORK_ZSTD in include/src_tracer/constants.h, you would need to decompress the trace first using zstd -d

Retracing

  • Compile it with _RETRACE_MODE (you might also want different compiler optimizations for recording/replaying)
    gcc -D_RETRACE_MODE -g -I${SRC_TRACER_INCL} -L${SRC_TRACER_LIB} checksum_inst.c -o checksum_retrace -lsrc_tracer
    
  • Retrace it (use python -i to work with the traced state in the interactive shell)
    retrace.py checksum_retrace 2023-04-28-143402-checksum.c.trace
    echo "C1 IIO" > sub.trace.txt
    retrace.py checksum_retrace sub.trace.txt
    
    The last one just retraces function checksum.

Other Example

An example to instrument and retrace busybox with musl-libc can be found in the wiki

Other Software

You can do it manually as for the checksum.c example.

For a more automatic way that works well with make scripts, make use of cc_wrapper/ for the gcc compiler.

Recording

  • Set some envirenmental variables.
    source gcc_env.sh
    
    This will set CC, CFLAGS and LIBS.
  • Now you can ./configure your project:
    export SRC_TRACER=""
    ./configure
    
  • Before the actual compilation:
    export SRC_TRACER="-D_TRACE_MODE"
    
  • Then build your project with make, gcc or similar. Example:
    gcc $CFLAGS checksum.c -o checksum_trace2 $LIBS
    
  • Traces will be stored in ~/.src_tracer by default!

Retracing

  • Same envirenmental variables as before.
  • If you want to ./configure your project again (e.g. with other options like CFLAGS with -g) make sure to set SRC_TRACER="" (as empty string) before you run ./configure.
  • Before the actual compilation:
    export SRC_TRACER="-D_RETRACE_MODE"
    
  • Then build your project with make, gcc or similar. Example:
    gcc $CFLAGS checksum.c -o checksum_retrace2 $LIBS
    

It can be a bit tricky to get the binary linking correctly, make sure that the record/replay executable includes the record/replay version of the app and its libraries.