Skip to content
spds
Switch branches/tags
Code

Latest commit

 

Git stats

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
 
 
doc
 
 
jvm
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

macOS CI Ubuntu CI

SWAN

This branch contains the new generation of the SWAN framework.

The SWAN version described in our ESEC/FSE 2020 paper is located on this branch. This paper no longer represents the current state of SWAN because we have redesigned it entirely.

Summary

SWAN is a static program analysis framework that enables deep dataflow analysis for Swift applications (incl. iOS/macOS). Its applications include finding API misuses using typestate analysis and detecting security vulnerabilities using taint analysis.

We aim to provide developers and researchers with an easy-to-use and well-documented platform for analyzing Swift applications.

🚧 SWAN is WIP. However, we are working on a pre-release to get the community involved. We will release an extensive video playlist explaining how SWAN works, which should enable you to experiment with SWAN.

Features

  • Wrappers for xcodebuild and swiftc that build and dump SIL
  • SIL parser (99% coverage, up to 100k lines/second)
  • Well documented intermediate representation (IR), called SWIRL
  • Ability to write models for black-box functions with SWIRL
  • Partial language and Swift Standard Library models
  • Modular IR translation pipeline (for integration with other engines)
  • Development tool for viewing Swift, SIL, and SWIRL side-by-side
  • Optimizations: multi-threaded module processing, caching, selective parsing
  • Cross-module analysis support
  • Synchronized Pushdown Systems (SPDS) integration
  • Call graph construction
  • Configurable taint analysis
  • Configurable typestate analysis
  • Analysis for Visits Location Service and Standard Location Service for finding energy inefficient configuration
  • Annotation checker for regression testing

Currently working on

  • Improving taint and typestate analysis
  • More language and Swift Standard Library modeling
  • iOS lifecycle support
  • Crypto API misuse detection
  • ... and much more!

Relevant Wiki pages

Getting started

For now, you will need to build the framework to use SWAN, but we will soon make a release available.

We have tested SWAN on macOS Big Sur with Xcode 12.5 and Ubuntu 20.04 with Swift 5.4. You need Xcode Command Line Tools installed for macOS, or the latest Swift release for Linux (see this). Anything involving Xcode will not work on Linux, but you should be able to build Swift Package Manager projects. You also need Java 8.

git clone https://github.com/themaplelab/swan.git -b spds

Add your GitHub username and personal access token (with read:packages) to jvm/gradle.properties. The SPDS dependency requires this. Do not push these credentials.

Copy swift-demangle to /usr/local/bin/ or add it to $PATH. On Linux, swift-demangle is distributed alongside swiftc, so you do not need to do this step. You also need swiftc and xcodebuild to be on $PATH.

sudo cp /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift-demangle /usr/local/bin/

Run build.sh in the repo root. You can also run the nested build.sh scripts from root to build separate toolchain components.

All toolchain components should now be available in lib/. If you want to make sure everything works, you can run run ./gradlew build in jvm/ and ./test.bash in tests/.


SWAN's toolchain uses a three-step process:

  1. Build the Swift application and dump SIL to a directory
  2. Analyze the SIL in the directory
  3. Process analysis results

1. Dump SIL using either swan-swiftc or swan-xcodebuild

You can dump SIL for Xcode projects with swan-xcodebuild. Give it the same arguments you give xcodebuild, but put them after -- (swan-xcodebuild specific arguments go before --). If you specify a single architecture with -arch, the build time will be faster and swan-xcodebuild will have less output to parse.

It will build your project and then dump the SIL to the swan-dir/ directory. You can optionally specify an alternative directory name with --swan-dir.

swan-xcodebuild -- -project MyProject.xcodeproj -scheme MyScheme -arch arm64

The same idea applies for swan-swiftc, which dumps SIL for single .swift files, and you only need to specify the Swift file.

swan-swiftc -- MyFile.swift

Generating Xcode projects

To build your project with (swan-)xcodebuild you need an .xcodeproj. If your project uses the Swift Package Manager (SPM), you will need to generate a .xcodeproj for your project, which you can do with swift package generate-xcodeproj. If you use CocoaPods, make sure to use -workspace instead of -project. You can also look into adding XcodeGen to your project to generate the .xcodeproj. If you are unsure what schemes or targets you can build, you can use -list.

2. Run Analysis

Use driver.jar to analyze the SIL in the swan-dir/. You can use -h to view the driver options.

You can learn about how to write analysis for SWAN here. Use -t to give the driver a taint analysis specification. Use -e to give the driver a typestate specification. You can view some example specifications in specifications/. Use -p to enable path-tracking. Note that path-tracking sometimes hangs (see the related issue for details). The default analysis will still show you the source and sink callsite locations.

The analysis engine (SDPS) may run out of stack memory. Currently, it will not tell you if this has happened. You can use -Xss to increase the stack memory.

3. Processing analysis results

The driver writes analysis results to swan-dir/*-results.json.

Annotations

You can annotate the source code and verify the results are correct automatically with annotation.jar.

Taint analysis example:

let sourced = source(); //!testing!source
sink(sunk: sourced); //!testing!sink

Typestate analysis example:

let f = File()
f.open() //?FileOpenClose?error

Once you run the driver, you can run the following to check the annotations against the results.

java -jar annotation.jar swan-dir/

This is intended for automatic regression testing. You can take a look inside tests/ to get a better idea of how annotation testing works. tests/README.md contains more information about testing.

IDE

Open jvm/ in IntelliJ. Be sure to select Import as Gradle Project.

Install the Scala plugin (Preferences -> Plugins, Search for Scala).

See IDE Configuration if you would like to configure syntax highlighting for SWIRL and SIL.

You can use the Playground run configurations to debug specific Swift, SIL, and SWIRL cases. Just paste the code in question to the appropriate playground.* in jvm/resources/playground/.