Compare commits
31 Commits
0ecdc5a3ac
...
af0a55f49a
Author | SHA1 | Date |
---|---|---|
Achim D. Brucker | af0a55f49a | |
Achim D. Brucker | 2911969097 | |
Achim D. Brucker | cee54c801c | |
Achim D. Brucker | 8d8b7e04e3 | |
Achim D. Brucker | de8e087e0e | |
Achim D. Brucker | afd08d989f | |
Achim D. Brucker | ca16ede2f7 | |
Achim D. Brucker | 417d93ecb1 | |
Achim D. Brucker | 2065fec897 | |
Achim D. Brucker | d51055e0cc | |
Achim D. Brucker | 9cf9120a10 | |
Achim D. Brucker | 297e187cf0 | |
Achim D. Brucker | b6cb4a9afc | |
Achim D. Brucker | 9b004207b2 | |
Achim D. Brucker | 41748b3c54 | |
Achim D. Brucker | 390662891c | |
Achim D. Brucker | 6137968cd1 | |
Achim D. Brucker | e274698e17 | |
Achim D. Brucker | 19f5d7920a | |
Achim D. Brucker | 681d9d59e5 | |
Achim D. Brucker | 624decf575 | |
Achim D. Brucker | 4f7c07ac40 | |
Achim D. Brucker | 2115640ff3 | |
Achim D. Brucker | 64193d9195 | |
Achim D. Brucker | 465a3cf0f1 | |
Achim D. Brucker | e3001f8402 | |
Achim D. Brucker | 07ad780011 | |
Achim D. Brucker | 925ec9c437 | |
Achim D. Brucker | 1e2e1a26c1 | |
Achim D. Brucker | 7bb70c17e8 | |
Achim D. Brucker | afffccbdb6 |
|
@ -1,8 +1,14 @@
|
|||
src/*/.classpath
|
||||
src/*/.settings
|
||||
src/*/.project
|
||||
src/*/target
|
||||
src/*/bin
|
||||
src/com.logicalhacking.dasca.dataflow/config/main.config
|
||||
src/com.logicalhacking.dasca.dataflow/main.log*
|
||||
src/com.logicalhacking.dasca.crosslanguage/BuildCordovaCallgraph.launch
|
||||
*/.classpath
|
||||
*/.settings
|
||||
*/.project
|
||||
*/.cache*
|
||||
*/target
|
||||
*/bin
|
||||
.gradle
|
||||
.settings
|
||||
.project
|
||||
build
|
||||
*/build
|
||||
com.logicalhacking.dasca.dataflow/config/main.config
|
||||
com.logicalhacking.dasca.dataflow/main.log*
|
||||
com.logicalhacking.dasca.crosslanguage/BuildCordovaCallgraph.launch
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
[submodule "externals/WALA"]
|
||||
path = externals/WALA
|
||||
url = https://git.logicalhacking.com/DASCA/WALA.git
|
||||
branch = master
|
83
README.md
83
README.md
|
@ -1,88 +1,87 @@
|
|||
# DASCA
|
||||
|
||||
## Installation
|
||||
|
||||
### Prerequisites
|
||||
|
||||
* Java 8 (Java 9 or later is currently *not* supported)
|
||||
* Android SDK (to obtain dx.jar)
|
||||
* Eclipse Oxygen, including
|
||||
* The Plug-in Development Environment (PDE)
|
||||
* JavaScript Development Tools (JSDT)
|
||||
* Gradle Integration (Buildship)
|
||||
* [Scala IDE and Scalatest Runner (the latter is optional)](http://download.scala-ide.org/sdk/lithium/e44/scala211/stable/site)
|
||||
* ["Maven for Scala" - Maven Integration for Eclipse](http://alchim31.free.fr/m2e-scala/update-site)
|
||||
* m2e - Maven Integration for Eclipse
|
||||
* [CVC3](http://cs.nyu.edu/acsys/cvc3/) including the Java bindings for CVC3
|
||||
* [apktool](https://ibotpeaches.github.io/Apktool/)
|
||||
|
||||
|
||||
### Checkout
|
||||
Note that this repository imports [WALA](http://wala.sf.net) as a submodule. Thus,
|
||||
you either need to recursively clone this repository, e.g.,
|
||||
```
|
||||
git clone --recursive https://git.logicalhacking.com/DASCA/DASCA.git
|
||||
```
|
||||
or execute ``git submodule update --init --recursive`` after
|
||||
cloning the repository.
|
||||
|
||||
The repository can be cloned as usual:
|
||||
|
||||
### Resolving external dependencies
|
||||
* Ensure that the environment variable `ANDROID_HOME` is set correctly and that
|
||||
the Android SDK has API 19 installed, i.e.,
|
||||
`${ANDROID_HOME}/platforms/android-19/android.jar` should be a valid path.
|
||||
* Install ``apktool_2.3.0.jar`` into your local maven repository:
|
||||
|
||||
```
|
||||
cd $(mktemp -d)
|
||||
wget https://bitbucket.org/iBotPeaches/apktool/downloads/apktool_2.3.0.jar
|
||||
mvn install:install-file -Dfile=apktool_2.3.0.jar -DgroupId=apktool -DartifactId=apktool -Dpackaging=jar -Dversion=2.3.0
|
||||
``` sh
|
||||
git clone https://git.logicalhacking.com/DASCA/DASCA.git
|
||||
```
|
||||
|
||||
### WALA configuration
|
||||
DASCA (and the underlying WALA setup) is tested with Java version 8.
|
||||
If DASCA is installed using Java 8, there should be no need for updating
|
||||
the WALA configuration.
|
||||
|
||||
If you experience problems or want to optimize the performance (e.g.,
|
||||
by analyzing the programs based on a different Java version), you
|
||||
DASCA (and the underlying WALA setup) is tested with Java version 8.
|
||||
If DASCA is installed using Java 8, there should be no need for updating
|
||||
the WALA configuration.
|
||||
|
||||
If you experience problems or want to optimize the performance (e.g.,
|
||||
by analyzing the programs based on a different Java version), you
|
||||
might need to configure the location of the Java JDK. The JDK used
|
||||
as part of the static analysis is configured in the `wala.properties`
|
||||
as part of the static analysis is configured in the `wala.properties`
|
||||
file, e.g.
|
||||
```
|
||||
|
||||
``` sh
|
||||
cd DASCA/
|
||||
echo "java_runtime_dir = <PATH-TO-JDK>" >> externals/WALA/com.ibm.wala.core/dat/wala.properties
|
||||
```
|
||||
|
||||
Don't forget to adjust the path to the Java JDK accordingly, i.e.,
|
||||
the `<PATH-TO-JDK>` should point to the directory containing the file
|
||||
`rt.lib`.
|
||||
|
||||
### How to Compile
|
||||
First check that the variable `JAVA_HOME` is configured correctly, e.g.:
|
||||
```
|
||||
|
||||
First check that the variable `JAVA_HOME` is configured correctly, to ensure
|
||||
that Java 8 is used, e.g.:
|
||||
|
||||
``` sh
|
||||
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
|
||||
export PATH=$JAVA_HOME/bin:$PATH
|
||||
```
|
||||
|
||||
Second, resolve the dependencies using maven:
|
||||
```
|
||||
cd src/com.logicalhacking.dasca.parent/
|
||||
mvn -P wala clean verify -DskipTests=true
|
||||
The project can be compiled using gradle
|
||||
|
||||
``` sh
|
||||
./gradlew clean assemble test
|
||||
```
|
||||
|
||||
After this, all projects can be imported into a fresh Eclipse
|
||||
workspace using `File -> Import -> Maven -> Existing Maven Projects`:
|
||||
1. Select the DASCA `src` folder as source for the import
|
||||
2. Import all offered projects (WALA and DASCA)
|
||||
### Import into Eclipse
|
||||
|
||||
While some WALA projects may contain compilation errors, all DASCA
|
||||
projects (i.e., `com.logicalhacking.dasca.*`) should compile without errors.
|
||||
All projects can be imported into a (fresh) Eclipse workspace
|
||||
using `File -> Import -> Gradle -> Existing Maven Projects`:
|
||||
|
||||
1. Select the DASCA folder as source for the import
|
||||
2. Import all offered projects
|
||||
|
||||
## Team
|
||||
|
||||
## Team
|
||||
Main contact: [Achim D. Brucker](http://www.brucker.ch/)
|
||||
|
||||
### Contributors
|
||||
|
||||
* Thomas Deuster
|
||||
* [Michael Herzberg](http://www.dcs.shef.ac.uk/cgi-bin/makeperson?M.Herzberg)
|
||||
* Tim Herres
|
||||
|
||||
## License
|
||||
This project is licensed under the Eclipse Public License 1.0.
|
||||
|
||||
This project is licensed under the Eclipse Public License 1.0.
|
||||
|
||||
## Publications
|
||||
|
||||
* Achim D. Brucker and Michael Herzberg. [On the Static Analysis of
|
||||
Hybrid Mobile Apps: A Report on the State of Apache Cordova
|
||||
Nation.](https://www.brucker.ch/bibliography/download/2016/brucker.ea-cordova-security-2016.pdf)
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
plugins {
|
||||
id 'de.undercouch.download'
|
||||
}
|
||||
|
||||
|
||||
|
||||
allprojects {
|
||||
apply plugin: 'maven'
|
||||
|
||||
group = 'com.logicalhacking.dasca'
|
||||
version = '0.1'
|
||||
}
|
||||
|
||||
|
||||
|
||||
subprojects {
|
||||
apply plugin: 'java'
|
||||
sourceCompatibility = 1.8
|
||||
targetCompatibility = 1.8
|
||||
tasks.withType(JavaCompile) {
|
||||
options.encoding = 'UTF-8'
|
||||
}
|
||||
|
||||
|
||||
repositories {
|
||||
maven { url "https://artifacts.logicalhacking.com/maven3" }
|
||||
maven { url "https://repo.maven.apache.org/maven2" }
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
/.gradle/
|
|
@ -0,0 +1,7 @@
|
|||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile 'de.undercouch:gradle-download-task:3.4.3'
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
import org.gradle.api.tasks.*
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// create a Javadoc-style "package-list" file
|
||||
//
|
||||
|
||||
@CacheableTask
|
||||
class CreatePackageList extends org.gradle.api.DefaultTask {
|
||||
|
||||
@PathSensitive(PathSensitivity.RELATIVE)
|
||||
@Input Object sourceSet
|
||||
|
||||
@OutputFile File packageList = new File("$temporaryDir/package-list")
|
||||
|
||||
@TaskAction
|
||||
def create() {
|
||||
sourceSet.sourceCollections.collect { collection ->
|
||||
def sourceRoot = collection.tree.dir.toPath()
|
||||
collection.collect { source ->
|
||||
def javaSourceFilePath = source.toPath()
|
||||
def parentPath = javaSourceFilePath.parent
|
||||
def relativePath = sourceRoot.relativize(parentPath)
|
||||
relativePath.toString().replace(File.separator, '.')
|
||||
}
|
||||
}.flatten().sort().unique().each {
|
||||
packageList << "$it\n"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
import org.gradle.api.tasks.*
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// download and use checksum to verify that we got what we expected
|
||||
//
|
||||
|
||||
@CacheableTask
|
||||
class VerifiedDownload extends org.gradle.api.DefaultTask {
|
||||
|
||||
// URL of resource to download
|
||||
def @Input src
|
||||
|
||||
// expected checksum of resource as hex digits
|
||||
def @Input checksum
|
||||
|
||||
// algorithm to use for computing checksum
|
||||
def @Input algorithm = 'MD5'
|
||||
|
||||
// whether to use ETag for selective downloading
|
||||
def @Input useETag = true
|
||||
|
||||
// local file into which resource should be saved
|
||||
def @OutputFile dest
|
||||
|
||||
File getDest() {
|
||||
return project.file(dest)
|
||||
}
|
||||
|
||||
VerifiedDownload() {
|
||||
outputs.upToDateWhen {
|
||||
getDest().exists()
|
||||
}
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
downloadAndVerify() {
|
||||
def destFile = getDest()
|
||||
project.download {
|
||||
src this.src
|
||||
dest destFile
|
||||
overwrite true
|
||||
onlyIfModified true
|
||||
useETag this.useETag
|
||||
}
|
||||
project.verifyChecksum {
|
||||
src destFile
|
||||
algorithm this.algorithm
|
||||
checksum this.checksum
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
apply plugin: 'scala'
|
||||
|
||||
description = 'com.logicalhacking.dasca.crosslanguage.test'
|
||||
|
||||
def osName = System.getProperty('os.name')
|
||||
ext.isWindows = osName.startsWith('Windows ')
|
||||
|
||||
task downloadAndroidSdk(type: VerifiedDownload) {
|
||||
def sdkOs
|
||||
switch (osName) {
|
||||
case ~/Linux/:
|
||||
sdkOs = 'linux'
|
||||
checksum '444e22ce8ca0f67353bda4b85175ed3731cae3ffa695ca18119cbacef1c1bea0'
|
||||
break
|
||||
case ~/Mac OS X/:
|
||||
sdkOs = 'darwin'
|
||||
checksum '4a81754a760fce88cba74d69c364b05b31c53d57b26f9f82355c61d5fe4b9df9'
|
||||
break
|
||||
case ~/Windows.*/:
|
||||
sdkOs = 'windows'
|
||||
checksum '7f6037d3a7d6789b4fdc06ee7af041e071e9860c51f66f7a4eb5913df9871fd2'
|
||||
break
|
||||
}
|
||||
def archive = "sdk-tools-$sdkOs-3859397.zip"
|
||||
src "https://dl.google.com/android/repository/$archive"
|
||||
dest "$temporaryDir/$archive"
|
||||
algorithm 'SHA-256'
|
||||
}
|
||||
|
||||
task installAndroidSdk(type: Sync, dependsOn: downloadAndroidSdk) {
|
||||
from zipTree(downloadAndroidSdk.dest)
|
||||
into temporaryDir
|
||||
|
||||
def buildToolsVersion = '26.0.2'
|
||||
ext {
|
||||
components = [
|
||||
'build-tools': buildToolsVersion,
|
||||
'platforms': "android-${buildToolsVersion.tokenize('.')[0]}"
|
||||
]
|
||||
}
|
||||
|
||||
doLast {
|
||||
exec {
|
||||
def shell, shellFlags, yes, semicolon, discard
|
||||
if (project.isWindows) {
|
||||
shell = 'PowerShell'
|
||||
shellFlags = '-Command'
|
||||
yes = 'echo y'
|
||||
semicolon = '`;'
|
||||
discard = '$null'
|
||||
} else {
|
||||
shell = 'sh'
|
||||
shellFlags = '-ceu'
|
||||
yes = 'yes 2>/dev/null'
|
||||
semicolon = /\;/
|
||||
discard = '/dev/null'
|
||||
}
|
||||
|
||||
def componentArgs = components.collect { "$it.key$semicolon$it.value" }.join ' '
|
||||
commandLine shell, shellFlags, "$yes | $temporaryDir/tools/bin/sdkmanager $componentArgs >$discard"
|
||||
}
|
||||
}
|
||||
outputs.cacheIf { true }
|
||||
}
|
||||
|
||||
task copyAndroidJar(type: Sync, dependsOn: installAndroidSdk) {
|
||||
from "${installAndroidSdk.destinationDir}/platforms/${installAndroidSdk.components['platforms']}/android.jar"
|
||||
into temporaryDir
|
||||
}
|
||||
|
||||
processResources {
|
||||
with copySpec {
|
||||
from copyAndroidJar
|
||||
rename { "android-dasca.jar" }
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation group: 'org.scala-lang', name: 'scala-library', version:'2.12.3'
|
||||
implementation group: 'junit', name: 'junit', version: '4.12'
|
||||
implementation group: 'org.scalatest', name: 'scalatest_2.12', version: '3.0.5'
|
||||
implementation group: 'com.ibm.wala', name: 'com.ibm.wala.core' , version:walaVersion
|
||||
implementation group: 'com.ibm.wala', name: 'com.ibm.wala.shrike' , version:walaVersion
|
||||
implementation group: 'com.ibm.wala', name: 'com.ibm.wala.util' , version:walaVersion
|
||||
implementation group: 'com.ibm.wala', name: 'com.ibm.wala.cast' , version:walaVersion
|
||||
implementation group: 'com.ibm.wala', name: 'com.ibm.wala.cast.js' , version:walaVersion
|
||||
implementation group: 'com.ibm.wala', name: 'com.ibm.wala.cast.js.rhino' , version:walaVersion
|
||||
implementation group: 'com.ibm.wala', name: 'com.ibm.wala.dalvik' , version:walaVersion
|
||||
implementation project(':com.logicalhacking.dasca.crosslanguage')
|
||||
testRuntime group: 'org.slf4j', name: 'slf4j-api', version: '1.7.2'
|
||||
testRuntime group: 'org.smali', name: 'dexlib2', version: '2.2.5'
|
||||
testRuntime group: 'net.htmlparser.jericho', name: 'jericho-html', version:'3.2'
|
||||
testRuntime group: 'commons-io', name: 'commons-io', version:'2.4'
|
||||
testRuntime group: 'com.google.guava', name: 'guava', version: '23.0'
|
||||
testRuntime group: 'org.mozilla', name: 'rhino', version: '1.7.10'
|
||||
testRuntime group: 'com.typesafe.scala-logging', name: 'scala-logging_2.12', version: '3.5.0'
|
||||
testRuntime group: 'apktool', name: 'apktool', version:'2.3.0'
|
||||
}
|
||||
|
||||
|
|
@ -13,7 +13,6 @@ package com.logicalhacking.dasca.crosslanguage.test
|
|||
|
||||
import java.io.File
|
||||
import com.logicalhacking.dasca.crosslanguage.util.SourceLocation
|
||||
import com.logicalhacking.dasca.crosslanguage.test.AppTest
|
||||
import com.logicalhacking.dasca.crosslanguage.builder.CrossBuilderOption
|
||||
|
||||
trait AppInfo {
|
|
@ -23,6 +23,7 @@ import com.logicalhacking.dasca.crosslanguage.builder.CrossBuilderOption
|
|||
import com.logicalhacking.dasca.crosslanguage.builder.MergedCallGraph
|
||||
import com.logicalhacking.dasca.crosslanguage.builder._
|
||||
import com.ibm.wala.cast.ir.ssa.AstIRFactory
|
||||
import com.ibm.wala.cast.ir.ssa.AstIRFactory.AstIR
|
||||
import com.ibm.wala.classLoader.IMethod
|
||||
|
||||
class AppTest {
|
||||
|
@ -127,12 +128,12 @@ class AppTest {
|
|||
) yield {
|
||||
if (Util.isJavaNode(origin._1)) {
|
||||
target.getIR match {
|
||||
case ir: AstIRFactory[IMethod]#AstIR => (JavaSourceLocation(origin._1, origin._2), JavaScriptSourceLocation(ir))
|
||||
case ir: AstIR => (JavaSourceLocation(origin._1, origin._2), JavaScriptSourceLocation(ir))
|
||||
case _ => (JavaSourceLocation(origin._1, origin._2), new JavaScriptSourceLocation(-1, -1, "unknown"))
|
||||
}
|
||||
} else {
|
||||
origin._1.getIR match {
|
||||
case ir: AstIRFactory[IMethod]#AstIR => (JavaScriptSourceLocation(ir, origin._2), JavaSourceLocation(target))
|
||||
case ir: AstIR => (JavaScriptSourceLocation(ir, origin._2), JavaSourceLocation(target))
|
||||
case _ => (new JavaScriptSourceLocation(-1, -1, "unknown"), JavaSourceLocation(target))
|
||||
}
|
||||
}
|
|
@ -20,7 +20,6 @@ import com.logicalhacking.dasca.crosslanguage.builder.FilterJavaCallSites
|
|||
import com.logicalhacking.dasca.crosslanguage.builder.MockCordovaExec
|
||||
import com.logicalhacking.dasca.crosslanguage.builder.ReplacePluginDefinesAndRequires
|
||||
import com.logicalhacking.dasca.crosslanguage.builder.FilterJSFrameworks
|
||||
import com.logicalhacking.dasca.crosslanguage.test.Tag._
|
||||
|
||||
|
||||
@RunWith(classOf[JUnitRunner])
|
|
@ -20,7 +20,6 @@ import com.logicalhacking.dasca.crosslanguage.builder.FilterJavaCallSites
|
|||
import com.logicalhacking.dasca.crosslanguage.builder.MockCordovaExec
|
||||
import com.logicalhacking.dasca.crosslanguage.builder.ReplacePluginDefinesAndRequires
|
||||
import com.logicalhacking.dasca.crosslanguage.builder.FilterJSFrameworks
|
||||
import com.logicalhacking.dasca.crosslanguage.test.Tag._
|
||||
|
||||
|
||||
|
|
@ -20,7 +20,6 @@ import com.logicalhacking.dasca.crosslanguage.builder.FilterJavaCallSites
|
|||
import com.logicalhacking.dasca.crosslanguage.builder.MockCordovaExec
|
||||
import com.logicalhacking.dasca.crosslanguage.builder.ReplacePluginDefinesAndRequires
|
||||
import com.logicalhacking.dasca.crosslanguage.builder.FilterJSFrameworks
|
||||
import com.logicalhacking.dasca.crosslanguage.test.Tag._
|
||||
|
||||
|
||||
@RunWith(classOf[JUnitRunner])
|
|
@ -8,7 +8,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
package com.logicalhacking.dasca.crosslanguage.test.Tag
|
||||
package com.logicalhacking.dasca.crosslanguage.test
|
||||
|
||||
import org.scalatest.Tag
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
apply plugin: 'scala'
|
||||
|
||||
description = 'com.logicalhacking.dasca.crosslanguage'
|
||||
dependencies {
|
||||
implementation group: 'org.scala-lang', name: 'scala-library', version:'2.12.3'
|
||||
implementation group: 'org.scala-lang.modules', name: 'scala-xml_2.12', version: '1.1.1'
|
||||
implementation group: 'io.spray', name: 'spray-json_2.12', version:'1.3.2'
|
||||
implementation group: 'com.ibm.wala', name: 'com.ibm.wala.core' , version:walaVersion
|
||||
implementation group: 'com.ibm.wala', name: 'com.ibm.wala.shrike' , version:walaVersion
|
||||
implementation group: 'com.ibm.wala', name: 'com.ibm.wala.util' , version:walaVersion
|
||||
implementation group: 'com.ibm.wala', name: 'com.ibm.wala.cast' , version:walaVersion
|
||||
implementation group: 'com.ibm.wala', name: 'com.ibm.wala.cast.js' , version:walaVersion
|
||||
implementation group: 'com.ibm.wala', name: 'com.ibm.wala.cast.js.rhino' , version:walaVersion
|
||||
implementation group: 'com.ibm.wala', name: 'com.ibm.wala.dalvik' , version:walaVersion
|
||||
implementation group: 'org.slf4j', name: 'slf4j-api', version: '1.7.2'
|
||||
implementation group: 'org.smali', name: 'dexlib2', version: '2.2.5'
|
||||
implementation group: 'net.htmlparser.jericho', name: 'jericho-html', version:'3.2'
|
||||
implementation group: 'commons-io', name: 'commons-io', version:'2.4'
|
||||
implementation group: 'com.google.guava', name: 'guava', version: '23.0'
|
||||
implementation group: 'org.mozilla', name: 'rhino', version: '1.7.10'
|
||||
implementation group: 'com.typesafe.scala-logging', name: 'scala-logging_2.12', version: '3.5.0'
|
||||
implementation group: 'apktool', name: 'apktool', version:'2.3.0'
|
||||
}
|
|
@ -56,7 +56,7 @@ object Main {
|
|||
if (n.getMethod().getName.equals(execSQL)) { sinks = sinks.+:(n) }
|
||||
}else{
|
||||
try{
|
||||
if((n.getMethod().asInstanceOf[JavaScriptLoader#JavaScriptMethodObject]).getDeclaringClass()
|
||||
if((n.getMethod().asInstanceOf[JavaScriptLoader#DynamicMethodObject]).getDeclaringClass()
|
||||
.getSourceFileName().endsWith("index.js"))
|
||||
{roots = roots.+:(n) }
|
||||
}catch{
|
|
@ -159,13 +159,14 @@ class CordovaCGBuilder(val apk: File, val apkUnzipDir: File) {
|
|||
}
|
||||
|
||||
private def createJavaCallGraph = {
|
||||
val tmpAndroidJar = File.createTempFile("android", "jar")
|
||||
val tmpAndroidJar = File.createTempFile("android-dasca", ".jar")
|
||||
tmpAndroidJar.deleteOnExit()
|
||||
if (null != getClass.getClassLoader.getResource("android19.jar")){
|
||||
TemporaryFile.urlToFile(tmpAndroidJar, getClass.getClassLoader.getResource("android19.jar"))
|
||||
if (null != getClass.getClassLoader.getResource("android-dasca.jar")){
|
||||
TemporaryFile.urlToFile(tmpAndroidJar, getClass.getClassLoader.getResource("android-dasca.jar"))
|
||||
}else{
|
||||
logger.error("Please install android19.jar.");
|
||||
throw new FileNotFoundException("Please install android19.jar.");
|
||||
val msg = "Please install android-dasca.jar in resources directory."
|
||||
logger.error(msg);
|
||||
throw new FileNotFoundException(msg);
|
||||
}
|
||||
val scope = AndroidAnalysisScope.setUpAndroidAnalysisScope(apk.toURI(), getClass.getClassLoader.getResource("javaexclusions.txt").getFile, CordovaCGBuilder.getClass.getClassLoader())
|
||||
scope.addToScope(ClassLoaderReference.Primordial, new JarFileModule(new JarFile(tmpAndroidJar)))
|
||||
|
@ -178,7 +179,7 @@ class CordovaCGBuilder(val apk: File, val apkUnzipDir: File) {
|
|||
val entryPoints = eps.getEntryPoints(cha).asScala ++ pluginEntryPoints
|
||||
val options = new AnalysisOptions(scope, entryPoints.asJava);
|
||||
options.setReflectionOptions(ReflectionOptions.FULL);
|
||||
val cgb = WalaUtil.makeZeroCFABuilder(options, cache, cha, scope);
|
||||
val cgb = WalaUtil.makeZeroCFABuilder(com.ibm.wala.classLoader.Language.JAVA, options, cache, cha, scope);
|
||||
cgb.makeCallGraph(options, null);
|
||||
}
|
||||
|
|
@ -50,6 +50,8 @@ import scala.collection.mutable.ListBuffer
|
|||
import com.ibm.wala.cast.ir.ssa.AstIRFactory
|
||||
import scala.collection.mutable.LinkedHashSet
|
||||
import com.ibm.wala.classLoader.IMethod
|
||||
import com.ibm.wala.cast.ir.ssa.AstIRFactory.AstIR
|
||||
import com.ibm.wala.cast.ir.ssa.AstIRFactory.AstIR
|
||||
|
||||
class MergedCallGraph(val javaCG: CallGraph, val jsCG: CallGraph, val configXml: Elem) extends Iterable[CGNode] {
|
||||
val logger = Logger(LoggerFactory.getLogger(getClass.toString))
|
||||
|
@ -240,7 +242,7 @@ class MergedCallGraph(val javaCG: CallGraph, val jsCG: CallGraph, val configXml:
|
|||
def findJsExecuteNode(node: CGNode, csr: CallSiteReference) = getPossibleTargets(node, csr).collectFirst({
|
||||
n =>
|
||||
n.getMethod match {
|
||||
case m: JavaScriptLoader#JavaScriptMethodObject if (m.getEntity.getName.endsWith(CordovaCGBuilder.ExecuteSuffix)) => n
|
||||
case m: JavaScriptLoader#DynamicMethodObject if (m.getEntity.getName.endsWith(CordovaCGBuilder.ExecuteSuffix)) => n
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -258,11 +260,11 @@ class MergedCallGraph(val javaCG: CallGraph, val jsCG: CallGraph, val configXml:
|
|||
private def skipCrossCall(from: CGNode, csr: CallSiteReference, to: CGNode): Boolean = {
|
||||
if (Util.isJavaNode(from)) {
|
||||
to.getMethod match {
|
||||
case m: JavaScriptLoader#JavaScriptMethodObject if (m.getEntity.getName.startsWith("make_")) => return true
|
||||
case m: JavaScriptLoader#DynamicMethodObject if (m.getEntity.getName.startsWith("make_")) => return true
|
||||
case _ =>
|
||||
}
|
||||
to.getIR match {
|
||||
case ir: AstIRFactory[IMethod]#AstIR => {
|
||||
case ir: AstIR => {
|
||||
val (_, _, _, _, relPath:String) = Util.getJavaScriptSourceInfo(ir, ir.getInstructions.find(_ != null).get)
|
||||
val lc = relPath.toLowerCase()
|
||||
val filename = lc.substring(lc.lastIndexOf('/'))
|
||||
|
@ -277,7 +279,7 @@ class MergedCallGraph(val javaCG: CallGraph, val jsCG: CallGraph, val configXml:
|
|||
}
|
||||
} else {
|
||||
from.getIR match {
|
||||
case ir: AstIRFactory[IMethod]#AstIR => {
|
||||
case ir: AstIR => {
|
||||
val (_, _, _, _, relPath:String) = Util.getJavaScriptSourceInfo(ir, ir.getInstructions.find(_ != null).get)
|
||||
val lc = relPath.toLowerCase()
|
||||
val filename = lc.substring(lc.lastIndexOf('/'))
|
|
@ -16,6 +16,7 @@ import com.ibm.wala.ipa.callgraph.CGNode
|
|||
import com.ibm.wala.ssa.SSAInstruction
|
||||
import com.ibm.wala.cast.js.html.IncludedPosition
|
||||
import com.ibm.wala.classLoader.IMethod
|
||||
import com.ibm.wala.cast.ir.ssa.AstIRFactory.AstIR
|
||||
|
||||
class JavaScriptSourceLocation(val line: Int, val column: Int, val filePath: String) extends SourceLocation with Equals {
|
||||
|
||||
|
@ -39,12 +40,12 @@ class JavaScriptSourceLocation(val line: Int, val column: Int, val filePath: Str
|
|||
object JavaScriptSourceLocation {
|
||||
val JavaScriptPathRegex = """.+/assets/(.+)""".r
|
||||
|
||||
def apply(ir: AstIRFactory[IMethod]#AstIR, inst: SSAInstruction): JavaScriptSourceLocation = {
|
||||
def apply(ir: AstIR, inst: SSAInstruction): JavaScriptSourceLocation = {
|
||||
val (line:Int, col:Int, _, _, relPath:String) = Util.getJavaScriptSourceInfo(ir, inst)
|
||||
new JavaScriptSourceLocation(line, col, relPath)
|
||||
}
|
||||
|
||||
def apply(ir: AstIRFactory[IMethod]#AstIR, csr: CallSiteReference): JavaScriptSourceLocation = apply(ir, ir.getCalls(csr)(0))
|
||||
def apply(ir: AstIR, csr: CallSiteReference): JavaScriptSourceLocation = apply(ir, ir.getCalls(csr)(0))
|
||||
|
||||
def apply(ir: AstIRFactory[IMethod]#AstIR): JavaScriptSourceLocation = apply(ir, ir.getInstructions.find({ i => i != null }).get)
|
||||
def apply(ir: AstIR): JavaScriptSourceLocation = apply(ir, ir.getInstructions.find({ i => i != null }).get)
|
||||
}
|
|
@ -30,6 +30,7 @@ import com.logicalhacking.dasca.crosslanguage.builder.FilterJSFrameworks
|
|||
import com.logicalhacking.dasca.crosslanguage.builder.PreciseJS
|
||||
import com.logicalhacking.dasca.crosslanguage.builder.RunBuildersInParallel
|
||||
import com.ibm.wala.classLoader.IMethod
|
||||
import com.ibm.wala.cast.ir.ssa.AstIRFactory.AstIR
|
||||
|
||||
object Util {
|
||||
val cachedDalvikLines = Map[(CGNode, SSAInstruction), Int]()
|
||||
|
@ -51,7 +52,7 @@ object Util {
|
|||
}
|
||||
|
||||
val JavaScriptPathRegex = """.+/assets/(.+)""".r
|
||||
def getJavaScriptSourceInfo(ir: AstIRFactory[IMethod]#AstIR, inst: SSAInstruction) = {
|
||||
def getJavaScriptSourceInfo(ir:AstIR, inst: SSAInstruction) = {
|
||||
val sourcePos = ir.getMethod.getSourcePosition(inst.iindex) match {
|
||||
case iPos: IncludedPosition => iPos.getIncludePosition
|
||||
case sp => sp
|
||||
|
@ -73,7 +74,7 @@ object Util {
|
|||
s"$className:$line, Method: $method, Path: $path"
|
||||
} else {
|
||||
node.getIR match {
|
||||
case ir:AstIRFactory[IMethod]#AstIR => {
|
||||
case ir:AstIR => {
|
||||
val (line, col, start, end, relPath:String) = getJavaScriptSourceInfo(ir, inst)
|
||||
val fileName = relPath.substring(relPath.lastIndexOf('/') + 1)
|
||||
s"$fileName:$line:$col ($start -> $end), Path: $relPath"
|
|
@ -0,0 +1,2 @@
|
|||
|
||||
description = 'DASCA - Dataflow Test Data'
|
|
@ -0,0 +1,28 @@
|
|||
|
||||
description = 'com.logicalhacking.dasca.dataflow'
|
||||
|
||||
dependencies {
|
||||
compile group: 'com.ibm.wala', name: 'com.ibm.wala.core', version: walaVersion
|
||||
compile group: 'com.ibm.wala', name: 'com.ibm.wala.shrike', version: walaVersion
|
||||
compile group: 'com.ibm.wala', name: 'com.ibm.wala.util', version: walaVersion
|
||||
compile group: 'com.ibm.wala', name: 'com.ibm.wala.cast', version: walaVersion
|
||||
compile group: 'com.ibm.wala', name: 'com.ibm.wala.cast.java', version: walaVersion
|
||||
compile group: 'com.ibm.wala', name: 'com.ibm.wala.cast.java.ecj', version: walaVersion
|
||||
compile group: 'junit', name: 'junit', version:'4.12'
|
||||
compile group: 'log4j', name: 'log4j', version:'1.2.17'
|
||||
compile group: 'cvc3', name: 'libcvc3', version: '5.0.0'
|
||||
compile 'org.eclipse.platform:org.eclipse.equinox.common:3.10.100'
|
||||
compile 'org.eclipse.platform:org.eclipse.core.resources:3.13.100'
|
||||
compile 'org.eclipse.platform:org.eclipse.core.runtime:3.15.0'
|
||||
compile 'org.eclipse.jdt:org.eclipse.jdt.core:3.15.0'
|
||||
compile 'org.eclipse.platform:org.eclipse.core.jobs:3.10.100'
|
||||
compile 'org.eclipse.platform:org.eclipse.osgi:3.13.100'
|
||||
compile 'org.eclipse.platform:org.eclipse.core.contenttype:3.7.100'
|
||||
compile 'org.eclipse.platform:org.eclipse.osgi.services:3.7.100'
|
||||
compile 'org.eclipse.platform:org.eclipse.equinox.preferences:3.7.200'
|
||||
}
|
||||
|
||||
test {
|
||||
exclude '**/Test0*.class'
|
||||
exclude '**/Test1*.class'
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<launchConfiguration type="org.eclipse.jdt.junit.launchconfig">
|
||||
<listAttribute key="StepOutExcludePkgsOrClasses"/>
|
||||
<stringAttribute key="org.eclipse.buildship.core.originalclasspathprovider" value="org.eclipse.m2e.launchconfig.classpathProvider"/>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
|
||||
<listEntry value="/com.logicalhacking.dasca.dataflow/src/test/java/com/logicalhacking/dasca/dataflow/test/TestSuite.java"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
|
||||
<listEntry value="1"/>
|
||||
</listAttribute>
|
||||
<mapAttribute key="org.eclipse.debug.core.preferred_launchers">
|
||||
<mapEntry key="[run]" value="org.eclipse.jdt.junit.launchconfig"/>
|
||||
</mapAttribute>
|
||||
<stringAttribute key="org.eclipse.jdt.junit.CONTAINER" value=""/>
|
||||
<booleanAttribute key="org.eclipse.jdt.junit.KEEPRUNNING_ATTR" value="false"/>
|
||||
<stringAttribute key="org.eclipse.jdt.junit.TESTNAME" value=""/>
|
||||
<stringAttribute key="org.eclipse.jdt.junit.TEST_KIND" value="org.eclipse.jdt.junit.loader.junit4"/>
|
||||
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/>
|
||||
<listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry containerPath="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8/" javaProject="com.logicalhacking.dasca.dataflow" path="1" type="4"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry containerPath="ECLIPSE_HOME/plugins/org.eclipse.equinox.common_3.9.0.v20170207-1454.jar" path="3" type="3"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry id="org.eclipse.jdt.launching.classpathentry.defaultClasspath"> <memento exportedEntriesOnly="false" project="com.logicalhacking.dasca.dataflow"/> </runtimeClasspathEntry> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry containerPath="ECLIPSE_HOME/plugins/org.eclipse.core.resources_3.12.0.v20170417-1558.jar" path="3" type="3"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry containerPath="ECLIPSE_HOME/plugins/org.eclipse.core.runtime_3.13.0.v20170207-1030.jar" path="3" type="3"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry containerPath="ECLIPSE_HOME/plugins/org.eclipse.jdt.core_3.13.101.v20180215-0725.jar" path="3" type="3"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry containerPath="ECLIPSE_HOME/plugins/org.eclipse.core.jobs_3.9.3.v20180115-1757.jar" path="3" type="3"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry containerPath="ECLIPSE_HOME/plugins/org.eclipse.osgi_3.12.100.v20180210-1608.jar" path="3" type="3"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry containerPath="ECLIPSE_HOME/plugins/org.eclipse.core.contenttype_3.6.0.v20170207-1037.jar" path="3" type="3"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry containerPath="ECLIPSE_HOME/plugins/org.eclipse.osgi.services_3.6.0.v20170228-1906.jar" path="3" type="3"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry containerPath="ECLIPSE_HOME/plugins/org.eclipse.equinox.preferences_3.7.0.v20170126-2132.jar" path="3" type="3"/> "/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="org.eclipse.buildship.core.classpathprovider"/>
|
||||
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.logicalhacking.dasca.dataflow.test.TestSuite"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.logicalhacking.dasca.dataflow"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.m2e.launchconfig.sourcepathProvider"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-ea"/>
|
||||
</launchConfiguration>
|
|
@ -19,6 +19,6 @@ logging_properties_file = config/log4j.properties
|
|||
|
||||
dot_path = /tmp/graphs
|
||||
dot_remove_empty_nodes = no
|
||||
|
||||
|
||||
# Usually not required
|
||||
# java_runtime_dir = /usr/lib/jvm/java-6-openjdk-amd64/jre/lib
|
||||
java_runtime_dir = ../../jre/lib
|
|
@ -33,6 +33,7 @@ import com.ibm.wala.cast.java.loader.JavaSourceLoaderImpl.ConcreteJavaMethod;
|
|||
import com.ibm.wala.cast.java.ssa.AstJavaInvokeInstruction;
|
||||
import com.ibm.wala.classLoader.IClass;
|
||||
import com.ibm.wala.classLoader.IMethod;
|
||||
import com.ibm.wala.classLoader.Language;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisCache;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisCacheImpl;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
|
||||
|
@ -148,7 +149,7 @@ public class AnalysisUtil {
|
|||
entryPoints = HashSetFactory.make();
|
||||
for(IClass class1 : cha) {
|
||||
if(class1.getClassLoader().getReference().equals(clr)) {
|
||||
Collection<IMethod> allMethods = class1.getDeclaredMethods();
|
||||
Collection<? extends IMethod> allMethods = class1.getDeclaredMethods();
|
||||
for(IMethod m : allMethods) {
|
||||
if(m.isPrivate()) {
|
||||
continue;
|
||||
|
@ -170,8 +171,8 @@ public class AnalysisUtil {
|
|||
}
|
||||
AnalysisOptions options = new AnalysisOptions(scope, entryPoints);
|
||||
|
||||
// CallGraphBuilder builder = com.ibm.wala.ipa.callgraph.impl.Util.makeRTABuilder(options, new AnalysisCacheImpl(), cha, scope); // Rapid Type Analysis
|
||||
SSAPropagationCallGraphBuilder builder = com.ibm.wala.ipa.callgraph.impl.Util.makeZeroCFABuilder(options, new AnalysisCacheImpl(), cha, scope); // 0-CFA = context-insensitive, class-based heap
|
||||
// CallGraphBuilder builder = com.ibm.wala.ipa.callgraph.impl.Util.makeRTABuilder(options, new AnalysisCacheImpl(), cha, scope); // Rapid Type Analysis
|
||||
SSAPropagationCallGraphBuilder builder = com.ibm.wala.ipa.callgraph.impl.Util.makeZeroCFABuilder(Language.JAVA, options, new AnalysisCacheImpl(), cha, scope); // 0-CFA = context-insensitive, class-based heap
|
||||
// CallGraphBuilder builder = com.ibm.wala.ipa.callgraph.impl.Util.makeZeroOneCFABuilder(options, new AnalysisCacheImpl(), cha, scope); // 0-1-CFA = context-insensitive, allocation-site-based heap
|
||||
// CallGraphBuilder builder = com.ibm.wala.ipa.callgraph.impl.Util.makeZeroOneContainerCFABuilder(options, new AnalysisCacheImpl(), cha, scope); // 0-1-Container-CFA = object-sensitive container
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
description = 'com.logicalhacking.dasca.js'
|
||||
dependencies {
|
||||
compile group: 'com.ibm.wala', name: 'com.ibm.wala.core', version:walaVersion
|
||||
compile group: 'com.ibm.wala', name: 'com.ibm.wala.cast', version:walaVersion
|
||||
compile group: 'com.ibm.wala', name: 'com.ibm.wala.cast.js', version:walaVersion
|
||||
compile group: 'com.ibm.wala', name: 'com.ibm.wala.cast.js.rhino', version:walaVersion
|
||||
compile group: 'com.ibm.wala', name: 'com.ibm.wala.util', version:walaVersion
|
||||
compile group: 'com.ibm.wala', name: 'com.ibm.wala.shrike', version:walaVersion
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue