-
Git
-
IntelliJ (tested with 2025.1.4.1) with the Scala plugin installed
-
Install SBT and JDK (tested with 1.11.3 (Ubuntu Java 21.0.9)):
sudo apt-get update
sudo apt-get install apt-transport-https curl gnupg -yqq
echo "deb https://repo.scala-sbt.org/scalasbt/debian all main" | sudo tee /etc/apt/sources.list.d/sbt.list
echo "deb https://repo.scala-sbt.org/scalasbt/debian /" | sudo tee /etc/apt/sources.list.d/sbt_old.list
curl -sL "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x2EE0EA64E40A89B84B2DF73499E82A75642AC823" | sudo -H gpg --no-default-keyring --keyring gnupg-ring:/etc/apt/trusted.gpg.d/scalasbt-release.gpg --import
sudo chmod 644 /etc/apt/trusted.gpg.d/scalasbt-release.gpg
sudo apt-get update
sudo apt-get install sbt
sudo apt install openjdk-21-jdk
- Clone our Joern Project:
git clone https://github.com/KIT-TVA/joern.git
- Go into the joern directory
cd joern/
- Clone our SuperC project into Joern
git clone git@gitlab.kit.edu:kit/tva/baechle/student-work/master/2026-ma-dormann-superc.git
- Rename the superC project:
mv 2026-ma-dormann-superc/ superc
- Install libaries required by superC and copy them into the bin directory
sudo apt-get install -y libz3-java=4.8.12-3.1build1 libjson-java sat4j bison
cd superc
# Please check if all 3 libraries are named the same. If not, update the names in the following command.
cp /usr/share/java/org.sat4j.core.jar /usr/share/java/com.microsoft.z3-4.8.12.0.jar /usr/share/java/json-lib.jar bin
- Clone our CodePropertyGraph project
cd ../..
git clone https://github.com/KIT-TVA/codepropertygraph.git
cd codepropertygraph/
sudo apt install git-lfs
git lfs pull
- Compile and publish the CodePropertyGraph project locally
sbt clean test publishM2
- Go back into the Joern directory
cd ../joern
- Open the SBT console
sbt
- Compile the project and keep the SBT console open!
compile
-
With the SBT console open, open the Joern Project in IntelliJ. When prompted to either use SBT or BSP import, select BSP.
-
Once IntelliJ finished the import, you can close the sbt console and should be able to compile the project in IntelliJ.
-
The SuperC frontend is implemented as part of the C frontend. The implementation of the frontend is located at
joern/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/. The enty point for the VA-AST is theVAstCreatorNew.scala. All definedVAstPatternConvertersandVAstFeatureHandlerare located injoern/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/converterand are registerres/initizialted injoern/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/VAstConverterForC.scalaAVAstPatternConvertershandles the conversion of one C-Feature as listed in the table below. AVAstFeatureHandlerprovides functionality that is required by multipleVAstPatternConverters. -
The corresponding tests are located at
joern/joern-cli/frontends/c2cpg/src/test/scala/io/joern/c2cpg/variability. -
Furthermore, changes to the derivation process of the CFG have been made in
joern/joern-cli/frontends/x2cpg/src/main/scala/io/joern/x2cpg/passes/controlflow/cfgcreation/CfgCreator.scalaand the PDG annotation pass is located atjoern/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/passes/variability/PdgPresenceConditionAnnotationPass.scala. -
The SuperC VA-AST plotting implementation is lacated in
joern/joern-cli/frontends/c2cpg/src/test/scala/io/joern/c2cpg/variability/util/TestUtil.scala. If only a SuperC VA-AST should be plotedTestUtil.superCGraphToDotGraph(...)an be used, but it is recomende to useTestUtil.generateVASTDot(...),TestUtil.generateVCFGDot(...),TestUtil.generateVPDGDot(...),TestUtil.generateVCPGDot(...)to abstrct from the aditional complexity event if the variabiable JOERN GRAPH is also returned. -
The JOERN AST, CFG, PDG, CPG, VA-AST, VA-CFG, VA-PDG and VA-CPG can be plotted with
DotAstGenerator.dotAst(...)andDotCpg14Generator.toDotCpg14(...). The JOERN dot-graph generator extensions are located injoern/semanticcpg/src/main/scala/io/shiftleft/semanticcpg/dotgenerator/DotSerializer.scala.
package io.joern.c2cpg.variability.vast
import io.joern.c2cpg.testfixtures.C2CpgSuite
import io.joern.c2cpg.variability.util.TestUtil.generateVASTDot
import io.joern.x2cpg.testfixtures.TestCpg
import io.shiftleft.codepropertygraph.generated.nodes
import io.shiftleft.codepropertygraph.generated.nodes.Method
import io.shiftleft.semanticcpg.dotgenerator.DotAstGenerator
class testComplexFunctionReturnTypes extends C2CpgSuite(withOssDataflow = true) {
/////////////////////////
// C-Sample Code //
/////////////////////////
// Defines the C sample.
val cFileName: String = "Test.c"
val cCode: String =
"""
|void foo() {
| int x = source(); // Attacker−controlled.
| if(x < MAX){ // Does not enforce x >= 0.
| int y = 0;
|#ifdef CONFIG_PROCESS_INPUT
| y = 2 * x;
| #ifdef CONFIG_SEND_DATA
| sink(y); // Security−sensitive operation.
| #endif
|#endif
| // ...
| }
|}
|
|""".stripMargin
/////////////////////////////////////////////////////////////////////////
// JOERN C-Frontend Implementation (without Variability Support) //
/////////////////////////////////////////////////////////////////////////
// Creates the CPG (together with AST, CFG and PDG) using the default C-Frontend of JOERN.
val cCpg: TestCpg = code(cCode, cFileName)
// Splits the returned JOERN CPG into several Sub-CPGs that start with a method declaration node (node kind 25),
// including the "<global>" method declaration node, that contains all variable and method declarations.
val cTraversal: Iterator[Method] = cCpg.graph._nodes(25).asInstanceOf[Iterator[nodes.Method]]
// Returns for each of the method declaration sub-CPGs the AST as a dot-graph with node coloring (withColoring = true)
// and all node-specific parameters, except for graph-related parameters (extendedView = true).
val cAstDotString: Iterator[String] = DotAstGenerator.dotAst(cTraversal, extendedView = true, withColoring = true)
println("Standard JOERN C AST:")
println(cAstDotString.mkString)
// Returns for each of the method declaration sub-CPGs the CPG as a dot-graph with node coloring (withColoring = true),
// edge coloring and all node-specific parameters, except for graph-related parameters (extendedView = true).
val cCpgDotString: Iterator[String] = DotCpg14Generator.toDotCpg14(cTraversal, extendedView = true, withColoring = true)
println("Standard JOERN C CPG:")
println(cCpgDotString.mkString)
///////////////////////////////////////////////////////////////////
// Variable C-Frontend Implementation (out Implementation) //
///////////////////////////////////////////////////////////////////
// Creates the JOERN VA-CPG (together with VA-AST, VA-CFG and VA-PDG) using the new variable C-Frontend of JOERN and
// returns the SuperC VA-AST and JOERN VA-ASTs (extendedView = true, withColoring = true) as dot-graphs.
val (superCAstDotString: String, superCJoernAstDotString: String) = generateVASTDot(cCode, cFileName)
println("\nSuperC VA-AST (original data structure):")
println(superCAstDotString)
println("\nSuperC-JOERN VA-AST (translated to JOERN VA-AST data structure):")
println(superCJoernAstDotString)
// Creates the JOERN VA-CPG (together with VA-AST, VA-CFG and VA-PDG) using the new variable C-Frontend of JOERN and
// returns the SuperC VA-AST and JOERN VA-CPGs (extendedView = true, withColoring = true and edge coloring) as
// dot-graphs.
val (superCCpgDotString: String, superCJoernCpgotString: String) =
generateVASTDot(cCode, cFileName, onlyGlobalGraph = false, onlyVAST = false)
println("\nSuperC VA-AST (original data structure):")
println(superCCpgDotString)
println("\nSuperC-JOERN VA-CPG (translated to JOERN VA-CPG data structure):")
println(superCJoernCpgotString)
}
| Task | Description | Status |
|---|---|---|
| 1 | unary operations handling | done |
| 2 | binary operations handling | done |
| 3 & 4 | multi variable declaration | done |
| 5 | typedef and struct declaration |
todo |
| 6 | assembly code and register access handling [optional] | todo |
| 7 | enum declaration |
done |
| 8 | goto and goto label handling |
done |
| 9 | multi file support [optional] | todo |
| 10 & 15 | multi function declaration | ongoing |
| 11 | code generation/reconstruction | done |
| 12 | if statements |
done |
| 13 | switch-case statements |
done |
| 14 | code block handling | done |
| 16 | function call handling | done |
| 17 | static assertions [optional] | todo |
| 18 | dot-graph generation for JOERN and SuperC | done |
| 19 | while and do-while loop handling |
done |
| 20 | for loop handling |
done |
| 21 | breake, continue instruction handling |
done |
| 22 | simple parameterized macro handling | todo |
| 23 | conditional macros handling | done |
More detailed information on the software architecture, the current status, and the background can be found in the PDF Family-Based_Vulnerability_Discovery_for_HCSS.pdf and the presentation Family-Based_Vulnerability_Discovery_for_HCSS_(slides).pdf.
- Each C feature has its own
VAstPatternConverter, which implementsio.joern.c2cpg.astcreation.converter.VAstPatternConverterand must be registered inVASTConverterForC. - Functionality required by multiple C features is outsourced to so-called
VAstFeatureHandlers, which also has to be registered inVASTConverterForC. - The location information methods in
VASTCreatorNewshould not be used, because it is simpler to extract the code positions directly from the SuperC AST (from the Language and Text nodes). - JOERN Choice nodes can now have more than 2 sub-ASTs and never have a code position specified.
- JOERN return nodes have a code position specification only if they have a return argument; otherwise, they have no code position specification.
- The JOERN dot-graph plotting functionality now offers options for coloring important nodes, outputting important node parameters, or edge-type coloring.
- The SuperC AST can now also be output as a dot graph.
- Red colored JOERN nodes in the VAST or other JOERN graphs indicate an incomplete translation caused by missing C feature support.
- All tests are located in the package:
io.joern.c2cpg.variability.vast
- It is recommended to implement
typedefandstructdeclarations asVAstFeatureHandlerand, similar to theVAstPatternConverterForConditionalMacro, to define an additionalVASTPatternConverterthat internally uses theVAstFeatureHandler, becausetypedefandstructdeclarations can be combined with variable declarations, meaning that atypedeforstructdeclaration can be a sub-AST of a variable declaration or a multi-variable declaration. - It is essential to ensure that control flows and data dependencies are handled correctly for complex features such as method declarations or switch cases, especially since a major adjustment has been made in the modeling of conditional return types for method declarations and
Choicenodes can now have more than two children. - It is recommended to adjust the function parameter declaration again and use a structure similar to that of variable accesses (JOERN
Identifiernodes) if the parameters are conditional. - The conditional handling of the conditional return-type pointer degree and the conditional decision of whether an array is returned is still missing and needs to be added.
- The handling of array initializations needs to be added.
Joern is a platform for analyzing source code, bytecode, and binary executables. It generates code property graphs (CPGs), a graph representation of code for cross-language code analysis. Code property graphs are stored in a custom graph database. This allows code to be mined using search queries formulated in a Scala-based domain-specific query language. Joern is developed with the goal of providing a useful tool for vulnerability discovery and research in static program analysis.
Website: https://joern.io
Documentation: https://docs.joern.io/
Specification: https://cpg.joern.io
- Joern v4.0.0 migrates from overflowdb to flatgraph
- Joern v2.0.0 upgrades from Scala2 to Scala3
- Joern v1.2.0 removes the
overflowdb.traversal.Traversalclass. This change is not completely backwards compatible. See here for a detailed writeup.
- JDK 21 (other versions might work, but have not been properly tested)
- optional: gcc and g++ (for auto-discovery of C/C++ system header files if included/used in your C/C++ code)
wget https://github.com/joernio/joern/releases/latest/download/joern-install.sh
chmod +x ./joern-install.sh
sudo ./joern-install.sh
joern
██╗ ██████╗ ███████╗██████╗ ███╗ ██╗
██║██╔═══██╗██╔════╝██╔══██╗████╗ ██║
██║██║ ██║█████╗ ██████╔╝██╔██╗ ██║
██ ██║██║ ██║██╔══╝ ██╔══██╗██║╚██╗██║
╚█████╔╝╚██████╔╝███████╗██║ ██║██║ ╚████║
╚════╝ ╚═════╝ ╚══════╝╚═╝ ╚═╝╚═╝ ╚═══╝
Version: 2.0.1
Type `help` to begin
joern>
If the installation script fails for any reason, try
./joern-install --interactive
Unit tests:
sbt testIntegration tests:
sbt joerncli/stage querydb/createDistribution
python -m pip install requests pexpect # wexpect on Windows
python -u ./testDistro.pydocker run --rm -it -v /tmp:/tmp -v $(pwd):/app:rw -w /app -t ghcr.io/joernio/joern joern
To run joern in server mode:
docker run --rm -it -v /tmp:/tmp -v $(pwd):/app:rw -w /app -t ghcr.io/joernio/joern joern --server
Almalinux 9 requires the CPU to support SSE4.2. For kvm64 VM use the Almalinux 8 version instead.
docker run --rm -it -v /tmp:/tmp -v $(pwd):/app:rw -w /app -t ghcr.io/joernio/joern-alma8 joern
A new release is created automatically once per day. Contributers can also manually run the release workflow if they need the release sooner.
Thank you for taking time to contribute to Joern! Here are a few guidelines to ensure your pull request will get merged as soon as possible:
- Try to make use of the templates as far as possible, however they may not suit all needs. The minimum we would like to see is:
- A title that briefly describes the change and purpose of the PR, preferably with the affected module in square brackets, e.g.
[javasrc2cpg] Addition Operator Fix. - A short description of the changes in the body of the PR. This could be in bullet points or paragraphs.
- A link or reference to the related issue, if any exists.
- A title that briefly describes the change and purpose of the PR, preferably with the affected module in square brackets, e.g.
- Do not:
- Immediately CC/@/email spam other contributors, the team will review the PR and assign the most appropriate contributor to review the PR. Joern is maintained by industry partners and researchers alike, for the most part with their own goals and priorities, and additional help is largely volunteer work. If your PR is going stale, then reach out to us in follow-up comments with @'s asking for an explanation of priority or planning of when it may be addressed (if ever, depending on quality).
- Leave the description body empty, this makes reviewing the purpose of the PR difficult.
- Remember to:
- Remember to format your code, i.e. run
sbt scalafmt Test/scalafmt - Add a unit test to verify your change.
- Remember to format your code, i.e. run
- Download Intellij Community
- Install and run it
- Install the Scala Plugin - just search and install from within Intellij.
- Important: open
sbtin your local joern repository, runcompileand keep it open - this will allow us to use the BSP build in the next step - Back to Intellij: open project: select your local joern clone: select to open as
BSP project(i.e. notsbt project!) - Await the import and indexing to complete, then you can start, e.g.
Build -> build projector run a test
- Install VSCode and Docker
- Install the plugin
ms-vscode-remote.remote-containers - Open Joern project folder in VSCode
- Option 1: Visual Studio Code detects the new files and opens a message box saying:
Folder contains a Dev Container configuration file. Reopen to folder to develop in a container.. Select theReopen in Containerbutton to reopen the folder in the container created by the.devcontainer/Dockerfilefile. - Option 2: press
Ctrl + Shift + Pthen selectDev Containers: Reopen in Container
- Option 1: Visual Studio Code detects the new files and opens a message box saying:
- Press
Ctrl + Shift + Pthen selectMetals: Import build - After
Metals: Import buildsucceeds, you are ready to start writing code for Joern
Quick way to develop and test QueryDB:
sbt stage
./querydb-install.sh
./joern-scan --list-query-names
The last command prints all available queries - add your own in querydb, run the above commands again to see that your query got deployed. More details in the separate querydb readme