arguslab / Argus-SAF

Argus static analysis framework
Apache License 2.0
183 stars 49 forks source link

Missing ICC links #45

Closed sangamk closed 6 years ago

sangamk commented 6 years ago

It seems like I am missing ICC links in the icfg.

What I tried:

    var entryPoints = apk.getEntryPoints(AndroidConstants.MAINCOMP_ENV) // Exposed components
    val spark = new InterProceduralSuperSpark(apk)
    val idfg = spark.build(entryPoints.map(_.getSignature))
    val icfg = idfg.icfg
    val callGraph = icfg.getCallGraph
    icfg.toDot(new PrintWriter(System.out))
    val icfg = new InterProceduralControlFlowGraph[ICFGNode]
    val ptaresult = new PTAResult
    val sp = new AndroidSummaryProvider(apk)

    AndroidReachingFactsAnalysisConfig.resolve_icc = true
    AndroidReachingFactsAnalysisConfig.resolve_static_init = false
    AndroidReachingFactsAnalysisConfig.parallel = false

    val analysis = new AndroidReachingFactsAnalysis(apk, icfg, ptaresult,
      new AndroidModelCallHandler,
      sp.getSummaryManager,
      new ClassLoadManager,
      AndroidReachingFactsAnalysisConfig.resolve_static_init,
      timeout = Some(new MyTimeout(FiniteDuration(5, TimeUnit.MINUTES)))
    )

    var entryPoints = apk.getEntryPoints(AndroidConstants.MAINCOMP_ENV)

    val entryPoint : JawaMethod = entryPoints.head
    val idfg = analysis.build(entryPoint, initContext = new Context(apk.nameUri))
    val iddResult = InterProceduralDataDependenceAnalysis(apk, idfg)
    println(iddResult)

    idfg.icfg.toDot(new PrintWriter(System.out))

How do I enable ICC?

fgwei commented 6 years ago

We don't use that flag anymore, I forget to remove it. If you want to do inter-component analysis, you can use: ComponentBasedAnalysis You can check this for how to use it: TaintAnalysisTask

fgwei commented 6 years ago

If you want to know the design you could check our TOPS paper

sangamk commented 6 years ago

Thx, for the fast reply. I looked through the code and skimmed the paper. From what I understand since I only want to see the data flow with ICC links and I do not want to perform taint analysis. I can skip phase 3.

The ICC links are incorporated in the ICFG and I can also directly acces ICCLinks via the summaryTable?

To clarify this is what I was doing before, based on SAF-playground:

    val handler: AndroidModelCallHandler = new AndroidModelCallHandler
    val sm: SummaryManager = new AndroidSummaryProvider(apk).getSummaryManager
    val analysis = new BottomUpSummaryGenerator[Global](apk, sm, handler,
      PTSummary(_, _),
      ConsoleProgressBar.on(System.out).withFormat("[:bar] :percent% :elapsed Left: :remain"))
    val store: PTStore = new PTStore
    val sigs: ISet[Signature] = apk.model.getComponentInfos.flatMap(apk.getEntryPoints)
    val cg = SignatureBasedCallGraph(apk, sigs, None)
    val orderedWUs: IList[WorkUnit[Global]] = cg.topologicalSort(true).map { sig =>
      val method = apk.getMethodOrResolve(sig).getOrElse(throw new RuntimeException("Method does not exist: " + sig))
      new IntentWu(apk, method, sm, handler, store, "intent")
    }

    analysis.build(orderedWUs)
    val candidate = store.getPropertyOrElse[MSet[(Context, PTASlot)]]("intent", msetEmpty)
    val intents: MSet[(Intent, Signature)] = msetEmpty

    val signature: MMap[Signature, String] = mmapEmpty
    candidate.foreach { case (ctx, s) =>
      val intentInss = store.resolved.pointsToSet(ctx, s)
      val intent = IntentHelper.getIntentContents(store.resolved, intentInss, ctx)
      println(s"${ctx.getMethodSig.methodName} calls Intent:")
      println(intent)
      println()
      if (intent.head.componentNames.nonEmpty) {
        signature.put(ctx.getMethodSig, intent.head.componentNames.head)
        intents.add((intent.head, ctx.getMethodSig))
      } else {
        println(s"NO component link. Its likely an action ${intent}")
      }
    }

And now I can use:

  def componentBasedGraph(apk: ApkGlobal, yard : ApkYard): Unit ={
    ComponentBasedAnalysis.prepare(Set(apk))(FiniteDuration(5, TimeUnit.MINUTES))
    val cba = new ComponentBasedAnalysis(yard)
    cba.phase1(Set(apk))
    val iddResult = cba.phase2(Set(apk))

    apk.getSummaryTables.foreach{ st =>
        val table : ICC_Summary = st._2.get(CHANNELS.ICC)
        table.asCaller.foreach{ x =>
          val method = x._1.getOwner.methodName
          val intent: IntentCaller = x._2.asInstanceOf[IntentCaller]
          println(s"$method calls ${intent.intent.componentNames.head}")
        }
    }
    println("finished")
  }

Is this somewhat correct?

fgwei commented 6 years ago

Yeah. But I like the ButtomUpSummary with IntentWu way because it is much faster. But you are right, for the component based way if you don't need taint analysis, you can just use phase2 to get SummaryTable.