Data-Flow Steps

Data-Flow Steps are Complex Steps that represent flows of data.

We will look at each one using our sample program X42:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[]) {
  if (argc > 1 && strcmp(argv[1], "42") == 0) {
    fprintf(stderr, "It depends!\n");
    exit(42);
  }
  printf("What is the meaning of life?\n");
  exit(0);
}

reachableBy #

reachableBy is a Data-Flow Step that returns sources for flows of data from sinks to sources.

joern> cpg.call.name("strcmp").reachableBy(cpg.method.parameter).l
res0: List[MethodParameterIn] = List(
  MethodParameterIn(
    id -> 1000104L,
    code -> "char *argv[]",
    order -> 2,
    name -> "argv",
    evaluationStrategy -> "BY_VALUE",
    typeFullName -> "char * [ ]",
    dynamicTypeHintFullName -> List(),
    lineNumber -> Some(5),
    columnNumber -> Some(19)
  )
)

reachableByFlows #

reachableByFlows is a Data-Flow Step that returns paths for flows of data from sinks to sources.

joern> sink.reachableByFlows(source).l
res0: List[Path] = List(
  Path(
    List(
      MethodParameterIn(
        id -> 1000104L,
        code -> "char *argv[]",
        order -> 2,
        name -> "argv",
        evaluationStrategy -> "BY_VALUE",
        typeFullName -> "char * [ ]",
        dynamicTypeHintFullName -> List(),
        lineNumber -> Some(5),
        columnNumber -> Some(19)
      ),
      Call(
        id -> 1000112L,
        code -> "strcmp(argv[1], \"42\")",
        name -> "strcmp",
        order -> 1,
        methodInstFullName -> None,
        methodFullName -> "strcmp",
        argumentIndex -> 1,
        dispatchType -> "STATIC_DISPATCH",
        signature -> "TODO assignment signature",
        typeFullName -> "ANY",
        dynamicTypeHintFullName -> List(),
        lineNumber -> Some(6),
        columnNumber -> Some(18),
        resolved -> None,
        depthFirstOrder -> None,
        internalFlags -> None
      )
    )
  )
)