Skip to content

DependableSystemsLab/RVDebloater

Repository files navigation

RVDebloater Artifact

Welcome to the artifact for the USENIX VehicleSec 2026 submission of our paper, titled "RVDebloater: Mode-based Adaptive Firmware Debloating for Robotic Vehicles".

Instructions (Tested on Ubuntu 22.04 LTS)

  1. Clone the Repository

    • Create an RVDebloater Project Directory and set the environment variable $RVD_PROJ
    mkdir rvd-project
    echo 'export RVD_PROJ=${HOME}/rvd-project' >> ${HOME}/.bashrc
    source ${HOME}/.bashrc

    Change ${HOME}/rvd-project to the correct path and name if you use a different path or name

    • Clone the RVDebloater repository:
    cd ${RVD_PROJ}
    git clone https://github.com/anonymoussubmission26/RVDebloaterArtifact.git
    • Rename the cloned repository folder from RVDebloaterArtifact to RVDebloater (required, as all scripts reference this path):
    mv ${RVD_PROJ}/RVDebloaterArtifact ${RVD_PROJ}/RVDebloater
  2. Pre-requisites

    • If go is already installed check the version

      • check version using
        /usr/local/go/bin/go version
      • If version is 1.17 or higher, skip to the next step, otherwise remove it with the following
        /usr/local/go/bin/go env GOPATH
        and run sudo rm -rf [directory] on the resulting directory, for example:
        sudo rm -rf ${HOME}/go
        lastly run
        sudo rm -rf /usr/local/go
    • Run the prereq script to install dependencies and set environment variables:

      cd ${RVD_PROJ}
      ./RVDebloater/scripts/pre-req.sh
      source ${HOME}/.bashrc

      The script does the following:

      • Installs some dependencies for SVF and gllvm
      • Installs our version of gllvm (ap-gllvm) using go
      • Clones ArduPilot (tag Copter-4.6.3) and PX4 (tag v1.16.0) repositories to rvd-project directory
      • Builds and configures SVF

      Note: The setup process can take approximately 20 minutes on a standard PC configuration, as it installs LLVM among other dependencies.

  3. Instrumented Simulation

    The run-simulation.sh script does the following:

    • Builds ArduPilot (copter, plane, or Rover) using our modified version of gllvm (Please modify the commented instructions in the script according to your target vehicle)
    • Extracts the whole program bitcode file
    • Runs instrumentation on the bitcode file
      • *Note: instrument-ap.sh script supports two separate operations (instrumentation for profiling and instrumentation for monitoring), please comment or uncomment the corresponding sections of the script depending on which operation you intend to use.
      • AddDPFunc.so and AddTrack.so are for profiling. CallOverwrite.so and AddEnforce.so are for monitoring.*
    • Recompiles the bitcode back to executable
    • Runs the ArduPilot SITL simulation using the instrumented executable file
    • The generated files including final executable and bitcode file are stored in ${AP_BIN} (e.g., rvd-project/ardupilot/build/sitl/bin)

    Run with:

    cd ${RVD_PROJ}
    RVDebloater/scripts/run-simulation.sh
  4. Running Vehicle In Simulation

    The following instructions is for copter

    • Once the simulation has loaded, wait for the following 2 lines to appear in the console
      AP: EKF3 IMU0 is using GPS
      AP: EKF3 IMU1 is using GPS

    • Then run the following 3 commands in the terminal:

      • mode guided
      • arm throttle
      • takeoff 10

      each of these commands should produce a message in the console indicating that the command was accepted, e.g. Got COMMAND_ACK: DO_SET_MODE: ACCEPTED after mode guided

      For plane the commands would be:

      • qloiter
      • arm throttle
      • rc 3 1500
      • rc 3 1700
      • qloiter
    • Then try repositioning the vehicle

      • Right-click anywhere on the mini map
      • Select "Fly To"
      • Press "OK" on the Altitude pop up window after entering the desired value

      For rover the commands would be:

      • mode guided
      • arm throttle
    • The vehicle should begin moving to the selected location

    • The current setup doesn't require your intervention, as it uses an automatic script to run different missions.

    Manual Control: By default, run-simulation.sh runs the simulation automatically. To control the vehicle manually, uncomment the following line in the script:

    ${SIM_V_SCRIPT} -v ${VEHICLE} ${FRAME_ARG} --console --map -w -N

    And comment out the following lines:

    # cp ${RVD_PATH}/scripts/run_missionRover.py \
    # ${AUTOTEST_BASE}
    # cp -r ${RVD_PATH}/mission ${AUTOTEST_BASE}/
    # cd ${AP_PATH}/ArduCopter
    # cd ${AP_PATH}/ArduPlane
    # cd ${AP_PATH}/Rover
    # ${AUTO_MISSION}

Software Dependencies

The artifact requires Ubuntu 22.04 LTS and has been developed and tested exclusively on this distribution. Other Linux distributions are not automatically supported and may fail during build or simulation due to differences in library versions, package managers, or system paths.

All required software dependencies (including LLVM, SVF, and the modified version of gllvm) are installed and configured by scripts/pre-req.sh. The pre-req.sh script requires go version 1.17 or higher.


Benchmarks & Pinned Firmware Versions

The artifact includes pre-defined mission files (in the missions directory) for each evaluated RV type: ArduCopter, ArduPlane, ArduRover, and PX4. The following pinned firmware versions are used to ensure reproducibility:

  • ArduPilot: tag Copter-4.6.3 on the ArduPilot GitHub repository
  • PX4: tag v1.16.0 on the PX4-Autopilot GitHub repository

The pre-req.sh script automatically clones these exact tagged versions.


Artifact Directory Structure

Directory Description
SVF Modified SVF pointer analysis framework for firmware analysis
callgraphs Pre-generated call graphs for each RV type (Copter, Plane, Rover)
missions Flight or navigation mission definitions for RV simulation
outputs Required functions identified by RVDebloater static analysis
profiles RVDebloater profiler tool and profiling results
scripts Primary scripts for running RVDebloater analysis and simulation

Basic Test

The scripts are pre-configured to run RVDebloater in Rover (profiling) mode. To verify a successful installation, run:

cd ${RVD_PROJ}
RVDebloater/scripts/run-simulation.sh

Once the simulation has loaded, wait for the following two lines to appear:

AP: EKF3 IMU0 is using GPS
AP: EKF3 IMU1 is using GPS

Then issue the following commands in the terminal (one at a time):

For Rover:

mode guided
arm throttle

Each command should produce an acknowledgment in the console (e.g., Got COMMAND_ACK: DO_SET_MODE: ACCEPTED after mode guided). A successful run will produce profiling output in the profiles directory and simulation logs confirming mission completion.


Evaluation Workflow

Major Claims

  • (C1): RVDebloater effectively identifies required functions through combined static and dynamic analysis and reduces the firmware's attack surface at runtime (Section 6.2 in paper).
  • (C2): RVDebloater supports multiple RV types (ArduCopter, ArduPlane, ArduRover, and PX4) and operates correctly in both profiling and monitoring modes.

(E1): Effectiveness — Profiling Mode

Estimated time: 15 human-minutes + 1 compute-hour

This experiment demonstrates that RVDebloater correctly identifies required functions using profiling-based analysis for each RV type.

Step 1 — Select RV type. Edit scripts/run-simulation.sh and uncomment the appropriate mission line (keep only one uncommented):

# For Copter:
AUTO_MISSION="${AUTOTEST_BASE}/run_mission.py"
# For Plane:
AUTO_MISSION="${AUTOTEST_BASE}/run_missionPlane.py"
# For Rover:
AUTO_MISSION="${AUTOTEST_BASE}/run_missionRover.py"

Step 2 — Configure vehicle type. In the same file, uncomment the vehicle and frame configuration (keep only one uncommented):

# For Copter:
# export VEHICLE="copter"
# FRAME_ARG=""
# For Plane:
# export VEHICLE="plane"
# FRAME_ARG="-f quadplane"
# For Rover:
export VEHICLE="rover"
FRAME_ARG=""

Also uncomment one of lines 168, 169, or 170 based on your vehicle type:

# For Copter:
# cp ${RVD_PATH}/scripts/run_mission.py ${AUTOTEST_BASE}
# For Plane:
# cp ${RVD_PATH}/scripts/run_missionPlane.py ${AUTOTEST_BASE}
# For Rover:
cp ${RVD_PATH}/scripts/run_missionRover.py ${AUTOTEST_BASE}

And one of lines 172, 173, or 174:

# For Copter:
# cd ${AP_PATH}/ArduCopter
# For Plane:
# cd ${AP_PATH}/ArduPlane
# For Rover:
cd ${AP_PATH}/Rover

Step 3 — Set analysis mode to profiling. Edit scripts/dependent/instrument-ap.sh and uncomment the profiling passes (ensure monitoring passes are commented out):

opt -load ./lib/AddDPFuncs.so -dp-funcs \
    ardu${VEHICLE}-uninstr-linked.bc \
    -o ardu${VEHICLE}-instr-linked.bc

opt -load ./lib/AddTrack.so -track-funcs \
    ardu${VEHICLE}-instr-linked.bc \
    -o ardu${VEHICLE}-instr-linked.bc

Also uncomment the appropriate llvm-link line based on vehicle type:

# For Copter:
# llvm-link ardu${VEHICLE}-uninstr.bc req_funcs.bc -o ardu${VEHICLE}-uninstr-linked.bc
# For Plane:
# llvm-link ardu${VEHICLE}-uninstr.bc req_funcs_plane.bc -o ardu${VEHICLE}-uninstr-linked.bc
# For Rover:
llvm-link ardu${VEHICLE}-uninstr.bc req_funcs_rover.bc -o ardu${VEHICLE}-uninstr-linked.bc

Sub-Step 3 — Set Vehicle Type. Edit Instrumentation/AddTrack.cpp and uncomment the vehicle type (ensure the others are commented out):

// For Copter:
// if (demangledName == "Copter::set_mode(Mode::Number, ModeReason)")
// For Plane:
// if (demangledName == "Plane::set_mode_by_number(Mode::Number, ModeReason)")
// For Rover:
if (demangledName == "Rover::set_mode(Mode::Number, ModeReason)")

Also uncomment the corresponding lines in Instrumentation/AddTrack.cpp:

  • Copter: Lines 128–170
  • Plane or Rover: Lines 176–218

Execution:

cd ${RVD_PROJ}
RVDebloater/scripts/run-simulation.sh

Results: The experiment generates a file called mode_profile in the profiles directory. Run the following to produce per-mode files listing required functions for each mode:

cd ${RVD_PROJ}/RVDebloater/profiles
python3 FunctionsName_to_Mode.py

Compare the number of identified required functions against Tables 2 and 3 in the paper.


(E2): Effectiveness — Monitoring Mode

Estimated time: 15 human-minutes + 1 compute-hour

This experiment demonstrates RVDebloater's runtime debloating in monitoring mode.

Preparation: Follow Steps 1 and 2 from (E1) to select the RV type.

Step 3 — Set analysis mode to monitoring. Edit scripts/dependent/instrument-ap.sh and uncomment the monitoring passes (ensure profiling passes are commented out; only one pair of passes should be active at a time):

opt -load ./lib/CallOverwrite.so -overwrite-call \
    ardu${VEHICLE}-uninstr-linked.bc \
    -o ardu${VEHICLE}-instr-linked.bc

opt -load ./lib/AddEnforce.so -enforce-funcs \
    ardu${VEHICLE}-instr-linked.bc \
    -o ardu${VEHICLE}-instr-linked.bc

Sub-Step 3 — Set Vehicle Type. Edit Instrumentation/CallOverwrite.cpp and uncomment the vehicle type (ensure the others are commented out):

// For Copter:
// std::set<string> modeNames = {"AUTO", "CIRCLE", "STABILIZE", "GUIDED", "RTL", "LOITER"};
// For Plane:
// std::set<string> modeNames = {"AUTO", "CIRCLE", "GUIDED", "RTL", "QLOITER", "MANUAL", "QHOVER"};
// For Rover:
// std::set<string> modeNames = {"AUTO", "CIRCLE", "GUIDED", "RTL", "LOITER", "MANUAL"};

Also edit Instrumentation/AddEnforce.cpp and uncomment the vehicle type:

// For Copter:
// if (demangledName == "Copter::set_mode(Mode::Number, ModeReason)")
// For Plane:
// if (demangledName == "Plane::set_mode_by_number(Mode::Number, ModeReason)")
// For Rover:
if (demangledName == "Rover::set_mode(Mode::Number, ModeReason)")

Also uncomment the corresponding lines in Instrumentation/AddEnforce.cpp:

  • Copter: Lines 96–138
  • Plane or Rover: Lines 142–185

Execution: Before running, comment out the following block in scripts/run-simulation.sh:

echo "--- Extraction Script for Profiles ---"
cd ${RVD_PROJ}/RVDebloater/profiles
python3 identifyAddress.py
cd ${AP_PATH}
echo "--- Finished Extraction Script ---"

Then run:

cd ${RVD_PROJ}
RVDebloater/scripts/run-simulation.sh

Results: A successful monitoring run will complete the mission without errors and produce simulation logs confirming that RVDebloater's runtime monitor enforces the debloated function set throughout the mission. Verify that the vehicle completes its mission correctly, confirming that the monitor does not incorrectly block required functions.

Note on hardware overhead: To measure overhead on a real device, deploy the firmware (with or without RVDebloater) using the manufacturer's recommended software and standard procedure, then compare measured overhead between the two configurations.


Notes on Reusability

Beyond the contributions of RVDebloater discussed in the paper, this artifact addresses a fundamental gap in the RV firmware ecosystem: the lack of an automated technique for generating LLVM bitcode (.bc) files, which are essential for leveraging analysis frameworks such as LLVM.

To overcome this limitation, we modified the infrastructure of gllvm and its underlying Go implementation, enabling automated generation of LLVM bitcode during the firmware build process. The artifact supports complex, real-world firmware systems such as ArduPilot and PX4 — two of the most widely used RV firmware platforms.

With this capability, developers can seamlessly apply LLVM-based analyses, including custom LLVM passes and third-party tools such as DataFlowSanitizer (DFSan). Because our changes extend the core infrastructure of gllvm and Go, the approach generalizes beyond ArduPilot and PX4 and can support a broader range of firmware.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors