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.
abstract_retrace.py
is an experimental abstract retracing, using no
symbolic execution and just the AST from libclang parser.
Any software which is written in C/C++, with the source code available.
- python3
- libclang (
pip install libclang
)
- C compiler (or your build system at choice) to compile the instrumented software
- C compiler (or your build system at choice) to compile the instrumented software
- python3
- angr for symbolic execution (
pip install angr
)
- Run make
make
- Install the python package
pip install .
-
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 createdfunctions_database.db
.
- 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 ofgcc
- Note: you might also want compiler optimizations like
-O3
for recording/replaying - Note: if you enabled
TRACEFORK_ZSTD
ininclude/src_tracer/constants.h
, you would need-lzstd
here
- Note: you might want to use a diferent compiler like
- Run it (replace
42
to get another trace)The name of the recorded trace corresponds to the current time, e.g../checksum_trace 42
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
ininclude/src_tracer/constants.h
, you would need to decompress the trace first usingzstd -d
- Note: if you enabled
- 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 tracedstate
in the interactive shell)The last one just retraces functionretrace.py checksum_retrace 2023-04-28-143402-checksum.c.trace echo "C1 IIO" > sub.trace.txt retrace.py checksum_retrace sub.trace.txt
checksum
.
- For abstract retracing, you don't need to recompile. Make sure that you are in the folder of the database:
abstract_retrace.py 2023-04-28-143402-checksum.c.trace
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.
- Set some envirenmental variables.
This will set CC, CFLAGS and LIBS.
source gcc_env.sh
- 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!
- Same envirenmental variables as before.
- If you want to
./configure
your project again (e.g. with other options likeCFLAGS
with-g
) make sure to setSRC_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.