2015-10-14 20:01:52 +00:00
|
|
|
/*
|
|
|
|
* (C) Copyright 2010-2015 SAP SE.
|
|
|
|
*
|
|
|
|
* All rights reserved. This program and the accompanying materials
|
|
|
|
* are made available under the terms of the Eclipse Public License v1.0
|
|
|
|
* which accompanies this distribution, and is available at
|
|
|
|
* http://www.eclipse.org/legal/epl-v10.html
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2017-05-21 14:58:16 +00:00
|
|
|
package com.logicalhacking.dasca.crosslanguage
|
2015-10-14 20:01:52 +00:00
|
|
|
|
|
|
|
import java.io.File
|
2017-05-21 14:58:16 +00:00
|
|
|
import com.logicalhacking.dasca.crosslanguage.builder._
|
|
|
|
import com.logicalhacking.dasca.crosslanguage.cg._
|
2015-10-14 20:01:52 +00:00
|
|
|
import scala.collection.mutable.ListBuffer
|
|
|
|
import java.lang.management.ManagementFactory
|
2017-05-21 14:58:16 +00:00
|
|
|
import com.logicalhacking.dasca.crosslanguage.util.Util
|
2015-10-14 20:01:52 +00:00
|
|
|
import org.slf4j.LoggerFactory
|
|
|
|
import com.typesafe.scalalogging.Logger
|
2016-09-11 12:08:36 +00:00
|
|
|
import com.ibm.wala.ipa.callgraph.CGNode
|
|
|
|
import com.ibm.wala.cast.js.loader.JavaScriptLoader
|
|
|
|
import com.ibm.wala.util.strings.Atom
|
2015-10-14 20:01:52 +00:00
|
|
|
|
|
|
|
object Main {
|
2016-09-10 18:32:00 +00:00
|
|
|
def main(args: Array[String]): Unit = {
|
|
|
|
if (args.length < 1 || (args.length < 2 && args(0).charAt(0) == '-')) {
|
|
|
|
println("You must at least provide the path to the apk!")
|
|
|
|
return
|
|
|
|
}
|
2015-10-14 20:01:52 +00:00
|
|
|
|
2016-09-10 18:32:00 +00:00
|
|
|
val apk = if (args(0).charAt(0) == '-') new File(args(1)) else new File(args(0))
|
2015-10-14 20:01:52 +00:00
|
|
|
|
2016-09-10 18:32:00 +00:00
|
|
|
if (!apk.exists() || !apk.getCanonicalPath.endsWith(".apk")) {
|
|
|
|
println("Please provide a valid apk file!")
|
|
|
|
return
|
2015-10-14 20:01:52 +00:00
|
|
|
}
|
2016-09-10 18:32:00 +00:00
|
|
|
|
|
|
|
val options = if (args(0).charAt(0) == '-') Util.argsToOptions(args(0)) else List()
|
|
|
|
implicit val logger = Logger(LoggerFactory.getLogger(getClass.toString))
|
2016-09-11 12:08:36 +00:00
|
|
|
var cg = null:MergedCallGraph
|
2016-09-10 18:32:00 +00:00
|
|
|
Util.time("Creation of the Cordova unified call graph", {
|
|
|
|
val builder = CordovaCGBuilder(apk)
|
|
|
|
builder.setOptions(options: _*)
|
2016-09-11 12:08:36 +00:00
|
|
|
cg = builder.createCallGraph
|
|
|
|
})
|
|
|
|
|
|
|
|
// compute sinks (JS entry points from index.js) and
|
|
|
|
// sources (execSQL statements)
|
|
|
|
val it = cg.iterator()
|
|
|
|
var sinks = List[CGNode]()
|
|
|
|
var roots = List[CGNode]()
|
|
|
|
val execSQL = Atom.findOrCreateUnicodeAtom("execSQL");
|
|
|
|
for(n <- it){
|
|
|
|
if (Util.isJavaNode(n)){
|
|
|
|
if (n.getMethod().getName.equals(execSQL)) { sinks = sinks.+:(n) }
|
|
|
|
}else{
|
|
|
|
try{
|
2018-10-25 20:52:51 +00:00
|
|
|
if((n.getMethod().asInstanceOf[JavaScriptLoader#DynamicMethodObject]).getDeclaringClass()
|
2016-09-11 12:08:36 +00:00
|
|
|
.getSourceFileName().endsWith("index.js"))
|
|
|
|
{roots = roots.+:(n) }
|
|
|
|
}catch{
|
|
|
|
case e:ClassCastException => {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
println ("Number of roots: "+roots.size)
|
|
|
|
roots.map { x => println(" "+x) }
|
|
|
|
println ("Number of sinks: "+sinks.size)
|
|
|
|
sinks.map { x => println(" "+x) }
|
|
|
|
|
|
|
|
Util.time("Creation of the CallForest", {
|
|
|
|
val callForest = CallTreeBuilder.buildCallForest(cg, 15, roots, sinks)
|
|
|
|
print ("Number of trees: "+callForest.size)
|
|
|
|
callForest.map { x => print ("\n"+x+"\n\n") }
|
2016-09-10 18:32:00 +00:00
|
|
|
})
|
|
|
|
}
|
2015-10-14 20:01:52 +00:00
|
|
|
}
|