======================== Using SystemTap with S2E ======================== SystemTap is a powerful tracing framework on Linux. It can intercept any function calls or instructions in the kernel and invoke custom scripts. Such scripts have full access to the system state, can leverage debugging information, etc. SystemTap provides S2E users a flexible way of controlling symbolic execution. Users write a SystemTap script with embedded calls to S2E custom instructions. This allows injecting symbolic values anywhere, kill states based on complex conditions, etc. In this tutorial, we describe how to build and run SystemTap on S2E. We also give several examples of useful analyses that can be achieved. .. note:: This tutorial assumes the following knowledge: 1. How to build guest images with s2e-env 2. How to create Linux analysis projects with s2e-env 3. How to use SystemTap Building and running SystemTap in S2E ===================================== Using SystemTap in S2E is very simple, the workflow looks like this: 1. Build the SystemTap probe on your host machine. This will produce a ``.ko`` file. You can conveniently do this from the provided Docker image (see below). 2. Upload the ``.ko`` file from the host into the guest using ``s2ecmd get`` in the ``bootstrap.sh`` file. It is best to store the ``.ko`` directly in the project directory. The S2E images built by ``s2e-env`` already have SystemTap pre-installed. If you want to customize the installed version, have a look at the image installation scripts. SystemTap is installed `here `__. You must build the Linux images from scratch in order to have the required Docker containers and kernel ``*.deb`` packages. If you downloaded pre-built images, delete them and rebuild them from scratch. This process will create two Docker images on your host: ``linux-build-i386`` and ``linux-build-x86_64``. .. code-block:: console # Create a new analysis project on your host. This tutorial assumes a 32-bit project. Adapt the command lines # accordingly if you need 64-bit. The --no-target option instructs s2e to create a generic project structure # that does not target any particular binary. You will then later customize the project manually in order to # fetch the .ko file generated by SystemTap. host $ cd /home/user/s2e/env host $ s2e new_project -n systemtap -i debian-12.5-i386 --no-target --type linux # Start the docker container in order to build the hello world SystemTap probe host $ docker run --rm -ti -v $HOME:$HOME linux-build-i386 # Install the kernel packages in the running container docker # dpkg -i /home/user/s2e/env/images/.tmp-output/linux-4.9.3-i386/*.deb # Compile the demo probe docker # cd /home/user/s2e/env/projects/systemtap docker # stap -a i386 -r 4.9.3-s2e -e 'probe vfs.read { log("hello world") exit() }' -m simple .. note:: It is also possible to build the ``simple.ko`` module directly from ``bootstrap.sh`` inside the guest instead of using a Docker image on the host. However, doing so is significantly slower (up to several minutes). At this point, you must have the ``/home/user/s2e/env/projects/systemtap/simple.ko`` file. Now it is time to update ``bootstrap.sh``: .. code-block:: bash ${S2ECMD} get simple.ko sudo staprun simple.ko Then, run the analysis: .. code-block:: bash host $ cd /home/user/s2e/env/projects/systemtap host $ ./launch-s2e.sh The analysis should finish in a few seconds and ``serial.txt`` should contain the following output: .. code-block:: none ... Waiting for S2E mode... ... S2E mode detected ... file simple.ko of size 59076 was transferred successfully to /home/s2e/simple.ko hello world Creating a simple SystemTap script for symbolic execution ========================================================= .. warning:: The following content is under construction. It may or may not work on your setup. In this section, we show how to intercept the network packets received by the ``pcnet32`` driver and replace the content of the IP header field with symbolic values. Create (on the host machine) a ``pcnet32.stp`` file with the following content: .. literalinclude:: pcnet32.stp Compile the script with SystemTap in the ``chroot`` environment, adjusting the kernel version to suit your needs. .. code-block:: console docker # stap -a i386 -r 4.9.3-s2e -g -m pcnet_probe pcnet32.stp This will result in a module called ``pcnet_probe.ko`` that we will upload to the VM as explained earlier in this tutorial. Running the script in S2E ========================= .. code-block:: console staprun pcnet_probe.ko & This will load the probe into the kernel. Symbolic execution will start when the network card receives the first packet. To send a packet, use ``netcat`` (in the guest) to send a UDP packet: