arguslab / Argus-SAF

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

Component based analysis output #63

Open mehrant95 opened 5 years ago

mehrant95 commented 5 years ago

I'm trying to write a code to extract all ICC activities from a single APK. Similar to the code in issue 45, i tried to extract RPC calls using the following code:

import org.argus.amandroid.core.decompile._
import org.argus.jawa.core.util.FileUtil
import org.argus.jawa.core.io.{MsgLevel, DefaultReporter, PrintReporter}
import org.argus.amandroid.core.{AndroidGlobalConfig, ApkGlobal}
import org.argus.amandroid.core.model.ApkModel
import org.argus.amandroid.core.AndroidConstants
import org.argus.amandroid.alir.pta.model.AndroidModelCallHandler
import org.argus.jawa.flow.summary.SummaryManager
import org.argus.amandroid.alir.pta.summaryBasedAnalysis.AndroidSummaryProvider
import org.argus.jawa.flow.summary.BottomUpSummaryGenerator
import hu.ssh.progressbar.ConsoleProgressBar
import org.argus.jawa.flow.summary.wu.{PTStore, PTSummary, PTSummaryRule}
import org.argus.jawa.core.Global
import org.argus.jawa.core.util._
import org.argus.jawa.core.elements.Signature
import org.argus.jawa.flow.summary.wu.WorkUnit
import org.argus.jawa.flow.Context
import org.argus.jawa.flow.pta.PTASlot
import org.argus.amandroid.core.model.Intent
import org.argus.amandroid.alir.pta.reachingFactsAnalysis.IntentHelper
import org.argus.jawa.flow.cg.CHA
import org.argus.amandroid.summary.wu.IntentWu
import org.argus.amandroid.alir.componentSummary.{ComponentBasedAnalysis, ApkYard}
import scala.concurrent.duration.FiniteDuration
import java.util.concurrent.TimeUnit
import org.argus.amandroid.alir.componentSummary.{ICC_Summary, IntentCaller, ComponentSummaryTable, IntentResultCaller}
import scala.util.control.Exception.Catch
import java.util.NoSuchElementException
import org.argus.amandroid.alir.componentSummary.{RPC_Summary, CSTCaller}

object HelloWorld {
  def main(args: Array[String]): Unit = {
    val apkUri = FileUtil.toUri("/home/ubuntu/data/apks/FriendTracker.apk")
    val outputUri = FileUtil.toUri("/home/ubuntu/data/apks/result_dir")
    val layout = DecompileLayout(outputUri)
    val strategy = new DecompileStrategy(layout)
    val reporter = new DefaultReporter
    val settings = DecompilerSettings(debugMode = false, forceDelete = true, strategy, reporter)
    val yard = new ApkYard(reporter)
    val apk = yard.loadApk(apkUri, settings, collectInfo = true, resolveCallBack = true)
    val handler: AndroidModelCallHandler = new AndroidModelCallHandler
    val sm: SummaryManager = new AndroidSummaryProvider(apk).getSummaryManager
    componentBasedGraph(apk, yard)
  }
  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))
    println("starting ...")
    apk.getSummaryTables.foreach{ st => 
      val table : RPC_Summary = st._2.get(ComponentSummaryTable.CHANNELS.RPC)
      table.asCaller.foreach{ x => 
        val method = x._1.getOwner.methodName
        val intent: CSTCaller = x._2.asInstanceOf[CSTCaller]
        println(s"$method ==> ${intent}")
      }
    }
    println("finished ...")
  }
}

The output is:

updateStatus ==> BoundServiceCaller(FriendTracker.apk,ComponentInfo(org.siislab.tutorial.friendtracker.FriendTrackerControl,ACTIVITY,true,true,Set(),Map()),Lorg/siislab/tutorial/friendtracker/FriendTracker$1;.isTracking:()Z)
updateStatus ==> BoundServiceCaller(FriendTracker.apk,ComponentInfo(org.siislab.tutorial.friendtracker.FriendTrackerControl,ACTIVITY,true,true,Set(),Map()),Lorg/siislab/tutorial/friendtracker/FriendTracker$1;.isTracking:()Z)
isTracking ==> BoundServiceReturnCaller(FriendTracker.apk,ComponentInfo(org.siislab.tutorial.friendtracker.FriendTracker,SERVICE,false,true,Set(org.siislab.tutorial.permission.FRIEND_SERVICE),Map()),Lorg/siislab/tutorial/friendtracker/FriendTracker$1;.isTracking:()Z,true)
onStart ==> BoundServiceCaller(FriendTracker.apk,ComponentInfo(org.siislab.tutorial.friendtracker.FriendTracker,SERVICE,false,true,Set(org.siislab.tutorial.permission.FRIEND_SERVICE),Map()),Lorg/siislab/tutorial/friendtracker/FriendTracker;.updateFriendLocations:()V)
onStart ==> BoundServiceCaller(FriendTracker.apk,ComponentInfo(org.siislab.tutorial.friendtracker.FriendTracker,SERVICE,false,true,Set(org.siislab.tutorial.permission.FRIEND_SERVICE),Map()),Lorg/siislab/tutorial/friendtracker/FriendTracker;.scheduleTracking:()V)
onStart ==> BoundServiceCaller(FriendTracker.apk,ComponentInfo(org.siislab.tutorial.friendtracker.FriendTracker,SERVICE,false,true,Set(org.siislab.tutorial.permission.FRIEND_SERVICE),Map()),Lorg/siislab/tutorial/friendtracker/FriendTracker;.updateFriendLocations:()V)
addNickname ==> BoundServiceReturnCaller(FriendTracker.apk,ComponentInfo(org.siislab.tutorial.friendtracker.FriendTracker,SERVICE,false,true,Set(org.siislab.tutorial.permission.FRIEND_SERVICE),Map()),Lorg/siislab/tutorial/friendtracker/FriendTracker$1;.addNickname:(Ljava/lang/String;I)Z,true)
onStart ==> BoundServiceCaller(FriendTracker.apk,ComponentInfo(org.siislab.tutorial.friendtracker.FriendTracker,SERVICE,false,true,Set(org.siislab.tutorial.permission.FRIEND_SERVICE),Map()),Lorg/siislab/tutorial/friendtracker/FriendTracker;.cancelTracking:()V)
onStart ==> BoundServiceCaller(FriendTracker.apk,ComponentInfo(org.siislab.tutorial.friendtracker.FriendTracker,SERVICE,false,true,Set(org.siislab.tutorial.permission.FRIEND_SERVICE),Map()),Lorg/siislab/tutorial/friendtracker/FriendTracker;.deactivateProvider:()V)
access$1 ==> BoundServiceCaller(FriendTracker.apk,ComponentInfo(org.siislab.tutorial.friendtracker.FriendTracker,SERVICE,false,true,Set(org.siislab.tutorial.permission.FRIEND_SERVICE),Map()),Lorg/siislab/tutorial/friendtracker/FriendTracker;.checkFriends:(Landroid/location/Location;)V)
onStart ==> BoundServiceCaller(FriendTracker.apk,ComponentInfo(org.siislab.tutorial.friendtracker.FriendTracker,SERVICE,false,true,Set(org.siislab.tutorial.permission.FRIEND_SERVICE),Map()),Lorg/siislab/tutorial/friendtracker/FriendTracker;.scheduleTracking:()V)

There are mainly two problems with the results:

  1. There are some duplicate results, e.g. the first and second line of the output say that there are two calls to isTracking() inside updateStatus method of FriendTrackerControl activity, but there is only one call.
  2. Some of RPC calls in the output are internal method calls inside a service, e.g. onStart() calling method updateFriendLocations() or scheduleTracking(). Are they indeed RPC calls?

BTW, i inspected ICC calls using ComponentSummaryTable.CHANNELS.ICC but it didn't include any provider-related ICC link. How can i extract provider-related communication links?

More info:

fgwei commented 4 years ago

The multiple outputs might be because find multiple callees at https://github.com/arguslab/Argus-SAF/blob/6adf246af40c77c067216812bf0bbfe1dfe79b89/amandroid/src/main/scala/org/argus/amandroid/alir/componentSummary/ComponentSummaryTable.scala#L104

fgwei commented 4 years ago

The RPC method detection logic is here: https://github.com/arguslab/Argus-SAF/blob/df2557a9654260d5dd933a15f52143bbd6da1f6d/amandroid/src/main/scala/org/argus/amandroid/core/appInfo/AppInfoCollector.scala#L205

fgwei commented 4 years ago

Currently, content provider is unsupported due to the method call to content providers are URI based and the URI string is runtime constructed. It is hard to resolve.