Showing preview only (961K chars total). Download the full file or copy to clipboard to get everything.
Repository: lukeFalsina/Grab-n-Run
Branch: master
Commit: e8de92230247
Files: 145
Total size: 910.8 KB
Directory structure:
gitextract_0udiqonx/
├── .gitmodules
├── COPYRIGHT
├── README.md
├── docs/
│ ├── .gitignore
│ ├── .placeholder
│ ├── Makefile
│ ├── complementary.rst
│ ├── conf.py
│ ├── example.rst
│ ├── index.rst
│ ├── javaDoc/
│ │ ├── allclasses-frame.html
│ │ ├── allclasses-noframe.html
│ │ ├── constant-values.html
│ │ ├── deprecated-list.html
│ │ ├── help-doc.html
│ │ ├── index-files/
│ │ │ ├── index-1.html
│ │ │ ├── index-2.html
│ │ │ ├── index-3.html
│ │ │ ├── index-4.html
│ │ │ ├── index-5.html
│ │ │ └── index-6.html
│ │ ├── index.html
│ │ ├── it/
│ │ │ └── necst/
│ │ │ └── grabnrun/
│ │ │ ├── SecureDexClassLoader.html
│ │ │ ├── SecureLoaderFactory.html
│ │ │ ├── class-use/
│ │ │ │ ├── SecureDexClassLoader.html
│ │ │ │ └── SecureLoaderFactory.html
│ │ │ ├── package-frame.html
│ │ │ ├── package-summary.html
│ │ │ ├── package-tree.html
│ │ │ └── package-use.html
│ │ ├── overview-tree.html
│ │ ├── package-list
│ │ └── stylesheet.css
│ ├── repackaging.rst
│ ├── security.rst
│ └── tutorial.rst
├── downloads/
│ ├── 1.0/
│ │ ├── gnr-1.0.jar
│ │ └── gnr-1.0.jar.sha1
│ ├── 1.0.1/
│ │ ├── gnr-1.0.1.aar
│ │ ├── gnr-1.0.1.aar.sha1
│ │ ├── gnr-1.0.1.jar
│ │ └── gnr-1.0.1.jar.sha1
│ ├── 1.0.2/
│ │ ├── gnr-1.0.2.aar
│ │ ├── gnr-1.0.2.aar.sha1
│ │ ├── gnr-1.0.2.jar
│ │ └── gnr-1.0.2.jar.sha1
│ ├── 1.0.3/
│ │ ├── grabnrun-1.0.3.aar
│ │ ├── grabnrun-1.0.3.aar.sha1
│ │ ├── grabnrun-1.0.3.jar
│ │ └── grabnrun-1.0.3.jar.sha1
│ └── 1.0.4/
│ ├── grabnrun-1.0.4.aar
│ ├── grabnrun-1.0.4.aar.sha1
│ ├── grabnrun-1.0.4.jar
│ └── grabnrun-1.0.4.jar.sha1
├── example/
│ ├── ADT/
│ │ ├── .classpath
│ │ ├── .gitignore
│ │ ├── .project
│ │ ├── AndroidManifest.xml
│ │ ├── assets/
│ │ │ └── exampleJar/
│ │ │ └── componentModifier.jar
│ │ ├── libs/
│ │ │ └── gnr-1.0.1.jar
│ │ ├── lint.xml
│ │ ├── proguard-project.txt
│ │ ├── project.properties
│ │ ├── res/
│ │ │ ├── layout/
│ │ │ │ ├── activity_dex_class_sample.xml
│ │ │ │ └── activity_main.xml
│ │ │ └── values/
│ │ │ └── strings.xml
│ │ └── src/
│ │ └── it/
│ │ └── polimi/
│ │ └── poccodeloading/
│ │ ├── ComponentModifier.java
│ │ ├── DexClassSampleActivity.java
│ │ └── MainActivity.java
│ └── AS/
│ ├── .gitignore
│ ├── app/
│ │ ├── build.gradle
│ │ ├── lint.xml
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ ├── assets/
│ │ │ └── exampleJar/
│ │ │ └── componentModifier.jar
│ │ ├── java/
│ │ │ └── it/
│ │ │ └── polimi/
│ │ │ └── poccodeloading/
│ │ │ ├── ComponentModifier.java
│ │ │ ├── DexClassSampleActivity.java
│ │ │ └── MainActivity.java
│ │ └── res/
│ │ ├── layout/
│ │ │ ├── activity_dex_class_sample.xml
│ │ │ └── activity_main.xml
│ │ └── values/
│ │ └── strings.xml
│ ├── build.gradle
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
├── gnr/
│ ├── .gitignore
│ ├── app/
│ │ ├── build.gradle
│ │ ├── lint.xml
│ │ ├── proguard-project.txt
│ │ └── src/
│ │ ├── main/
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── java/
│ │ │ │ └── it/
│ │ │ │ └── necst/
│ │ │ │ └── grabnrun/
│ │ │ │ ├── CacheLogger.java
│ │ │ │ ├── CertificateFileFilterByNameMatch.java
│ │ │ │ ├── ContainerSignatureVerifier.java
│ │ │ │ ├── DexPathStringProcessor.java
│ │ │ │ ├── FileDownloader.java
│ │ │ │ ├── FileFilterByNameMatch.java
│ │ │ │ ├── FileHelper.java
│ │ │ │ ├── PackageNameHelper.java
│ │ │ │ ├── PackageNameTrie.java
│ │ │ │ ├── SecureDexClassLoader.java
│ │ │ │ └── SecureLoaderFactory.java
│ │ │ └── res/
│ │ │ ├── values-v11/
│ │ │ │ └── styles.xml
│ │ │ └── values-v14/
│ │ │ └── styles.xml
│ │ └── test/
│ │ └── java/
│ │ └── it/
│ │ └── necst/
│ │ └── grabnrun/
│ │ ├── CacheLoggerTest.java
│ │ ├── CertificateFileFilterByNameMatchTest.java
│ │ ├── ContainerSignatureVerifierTest.java
│ │ ├── DexPathStringProcessorTest.java
│ │ ├── FileDownloaderTest.java
│ │ ├── FileFilterByNameMatchTest.java
│ │ ├── FileHelperTest.java
│ │ ├── PackageNameHelperTest.java
│ │ ├── PackageNameTrieTest.java
│ │ ├── SecureDexClassLoaderTest.java
│ │ ├── SecureLoaderFactoryTest.java
│ │ └── shadows/
│ │ ├── BaseDexClassLoaderShadow.java
│ │ └── DexFileShadow.java
│ ├── build.gradle
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradle-app.setting
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
├── grabandrun.bib
└── repackPOC/
├── .gitignore
├── RepackInputSelector/
│ ├── .classpath
│ ├── .project
│ └── src/
│ └── it/
│ └── necst/
│ └── grabnrun/
│ └── selector/
│ ├── LinkContainerDialog.java
│ └── MainFrame.java
├── libs/
│ ├── RepackInputSelector.jar
│ └── apktool.jar
├── repackagingTool.py
├── requirements.txt
└── smaliRes/
└── grabnrun/
├── CacheLogger.smali
├── CertFileFilter.smali
├── FileDownloader$1.smali
├── FileDownloader.smali
├── FileFilterByName.smali
├── PackageNameTrie.smali
├── RepackHandler.smali
├── RepackHandlerTail.smali
├── SecureDexClassLoader$SignatureVerificationTask.smali
├── SecureDexClassLoader.smali
└── SecureLoaderFactory.smali
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitmodules
================================================
[submodule "repackPOC/androguard"]
path = repackPOC/androguard
url = https://github.com/androguard/androguard.git
================================================
FILE: COPYRIGHT
================================================
Copyright 2014 Luca Falsina
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: README.md
================================================
# 
## Research paper
We present the findings of this work in a research paper:
**Grab'n Run: Secure and Practical Dynamic Code Loading for Android Applications**
Luca Falsina, Yanick Fratantonio, Stefano Zanero, Christopher Kruegel, Giovanni Vigna, Federico Maggi.
*In Proceedings of the Annual Computer Security Applications Conference (ACSAC). Los Angeles, CA December, 2015*
[[PDF](http://cs.ucsb.edu/~yanick/publications/2015_acsac_grabandrun.pdf)]
[[Bibtex](https://github.com/lukeFalsina/Grab-n-Run/raw/master/grabandrun.bib)]
If you use *Grab'n Run* in a scientific publication, we would appreciate citations to the previous paper.
Please use this **Bibtex** entry:
``` tex
@InProceedings{falsina15:grabandrun,
author = {Luca Falsina and Yanick Fratantonio and Stefano Zanero and Christopher Kruegel and Giovanni Vigna and Federico Maggi},
title = {{Grab'n Run: Secure and Practical Dynamic Code Loading for Android Applications}},
booktitle = {Proceedings of the Annual Computer Security Applications Conference (ACSAC)},
month = {December},
year = {2015},
address = {Los Angeles, CA}
}
```
## News
- *10/10/2015* - The **repackaging tool** is now **[online](http://grab-n-run.readthedocs.org/en/latest/repackaging.html)**. Use it to patch automatically your applications to use Grab'n Run APIs.
- *01/17/2015* - **Grab'n Run** is now **available** on [JCenter](https://bintray.com/bintray/jcenter?filterByPkgName=grab-n-run)
- *01/16/2015* - **Grab'n Run** project migrates to [Android Studio](http://developer.android.com/tools/studio/index.html), the official *IDE* for **Android application development**. However, you can still use the library also with your *ADT* projects! (*see below the "Quick Setup" section for further details*)
- *11/26/2014* - **Grab'n Run is on line!**
## Introduction
*Grab’n Run* (aka **GNR**) is a **simple** and **effective** Java Library that you can easily add to your Android projects to perform *secure dynamic class loading* operations over standard [DexClassLoader](http://developer.android.com/reference/dalvik/system/DexClassLoader.html).
Previous research has shown that many applications often need to perform dynamic class loading to implement, for example, non-invasive self-update features. However, research has also shown that it is really challenging to *safely* implement these features. This is of particular importance as, in this context, **one single mistake** could open the application (and, therefore, the entire device) to **serious security vulnerabilities**, such as *remote code execution*.
The main goal of *Grab's Run* is to offer an alternative to the native Android APIs, and its design enforces that even the most inexperienced developer cannot perform well-known, serious mistakes.
For a **brief presentation** of the library and some of its features you can give a look at these [slides](https://goo.gl/QrwWey), while if you prefer a more **structured and complete description** with *set up information, tutorials, examples, tips&tricks, and a full presentation of the API* you should definitely check the [documentation](http://grab-n-run.readthedocs.org/en/latest/).
If you desire to suggest new *features, improvements, criticisms* or whatever, I would be more than glad to hear **any kind of constructive feedback** :D
You can contact me either by dropping an email at [lfalsina@gmail.com](mailto:lfalsina@gmail.com) or by pinging me on Twitter [@lfalsina](https://twitter.com/lfalsina).
## Main features
Securely load code dynamically into your Android application from **APK** containers or **JAR** libraries translated to be *executable by both the Dalvik Virtual Machine (DVM) and the Android Runtime (ART)* (don't worry a [section](http://grab-n-run.readthedocs.org/en/latest/complementary.html#on-library-developer-side-how-to-prepare-a-valid-library-container-compatible-with-gnr) of the docs explains step-by-step how to do it).
- *JAR* and *APK* containers can be either already stored on the device or **automatically fetched from remote locations** by GNR.
- Retrieved containers signatures are compared against a **valid developer certificate**. Only containers that are **correctly signed** are allowed to have their classes loaded dynamically. This ensures **integrity** and **developer authentication** on all the retrieved containers.
- Developer certificates are retrieved from remote locations securely and cached on the mobile phone for future verifications.
- *Cached classes, containers and certificates* used for the signature verification are stored into *application-private* folders. This **prevents** your application **from code injection attacks** at runtime.
- GNR implements an **effective caching system** that speeds up its execution and at the same time enables it to *work in most cases also when no connectivity is available*.
- Transition to GNR is **smooth** for the application developer since its **API** where thought to be *as close as possible to the standard API* provided by the Android framework.
- When *many containers* are provided as sources for class loading, *Grab'n Run* performs a **concurrent multi-thread signature verification** in order to *limit the performance overhead*.
- GNR helps the application developer to **implement silent updating** on *remote third-party libraries in a secure and concise way*.
## Quick Setup
This section explains how to setup *Grab'n Run* as a library for your Android applications.
#### 1. Include library
###### a. Android Studio (AS)
* Modify the *build.gradle* file in the *app* module of your Android project by adding the following *compile* line in the *dependencies* body:
``` gradle
dependencies {
// Grab'n Run will be imported from JCenter.
// Verify that the string "jcenter()" is included in your repositories block!
compile 'it.necst.grabnrun:grabnrun:1.0.4'
}
```
* Resync your project to apply changes.
###### b. Android Development Tool (ADT)
* [Download JAR](https://github.com/lukeFalsina/Grab-n-Run/raw/master/downloads/1.0.4/grabnrun-1.0.4.jar)
* Put the JAR in the **libs** subfolder of your Android project
#### 2. Android Manifest
Modify the *Android Manifest* of your application by adding a couple of **required permissions**:
``` xml
<manifest>
<!-- Include following permission to be able to download remote resources
like containers and certificates -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- Include following permission to be able to download remote resources
like containers and certificates -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- Include following permission to be able to import local containers
on SD card -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
...
</manifest>
```
## Quick example of use
This quick use case gives you a taste on how to use GNR once you have added it to your project.
#### 1. Create a key pair to sign your code and export your developer certificate
* Open a terminal and type the following command to **generate a keystore** and a **keypair**:
``` bash
$ keytool -genkey -v -keystore my-tests-key.keystore -alias test_dev_key
-keyalg RSA -keysize 2048 -validity 10000
```
* Next **export** the public key **into a certificate** that will be *used to verify your library code* before dynamically loading it:
``` bash
$ keytool -exportcert -keystore my-tests-key.keystore -alias test_dev_key
-file certificate.pem
```
* You should now see in the folder a **certificate file** called *certificate.pem*
#### 2. Publish your developer certificate on line at a remote location which uses HTTPS protocol
You can publish the certificate wherever you like as long as **HTTPS** protocol is used and **everyone can access this location** from the web.
As a **test** example you could store the *certificate.pem* in your "Public" *Dropbox* folder and then retrieve the **associated public link**, which could be for example something like "https://dl.dropboxusercontent.com/u/00000000/certificate.pem". Note this URL down, you will need it soon.
#### 3. Export an unsigned container and sign it with your developer key
Let's say that in your IDE (i.e., the *Android Development Tools (ADT)*) you have an Android project called **"LoaderApp"** from which you want to load some of its classes dynamically in another project.
* In the *ADT Package Explorer* **right** click on **"LoaderApp"** -> Android Tools -> Export Unsigned Application Package...

* Next select the **same folder** where you have previously saved the keystore and the keypair as the *destination folder* and press OK.
* Open a terminal which points to the destination folder and **sign the apk container** with the previously created key:
``` bash
$ jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1
-keystore my-tests-key.keystore LoaderApp.apk test_dev_key
```
* Finally **align** the apk container to optimize access time to its resources:
``` bash
$ <path_to_your_sdk>/sdk/build-tools/<sdk_version_number>/zipalign -v 4
LoaderApp.apk LoaderAppAligned.apk
```
**P.S.** *Step 3* can also be directly performed by means of your favorite *IDE*. In **ADT** you would have to select the option *"Android Tools -> Export Signed Application Package..."* and, when it is required, navigate to the location of your keystore and inserting its password, the key id and the key password. On the other hand in **Android Studio** the signature process can be automatized by setting up a proper **signing configuration** as described [here](http://developer.android.com/tools/publishing/app-signing.html#release-mode).
#### 4. Publish the signed and aligned version of the source container
Once you have obtained *LoaderAppAligned.apk*, you need to make also this resource **available on line**. Notice that, in this case, both remote locations that use **HTTP** or **HTTPS** protocols are fine as long as they are accessible from the web. Again, as an example, you can store the container in your "Public" *Dropbox* folder and get back a **public URL** like "https://dl.dropboxusercontent.com/u/00000000/LoaderAppAligned.apk".
#### 5. Set up dynamic code loading with GNR in the application
In the end, it is time to set up a *SecureDexClassLoader* instance to **fetch your remote container and developer certificate**, **store it in a safe place** and **perform a signature verification** before dynamically loading your code.
**Copy and paste** the code below in one of the Activity in your target Android project, where you have *already imported GNR*, to **dynamically and securely load** an instance of the class *"com.example.MyClass"*:
``` java
MyClass myClassInstance = null;
jarContainerPath = "https://dl.dropboxusercontent.com/u/00000000/LoaderAppAligned.apk";
try {
Map<String, URL> packageNamesToCertMap = new HashMap<String, URL>();
packageNamesToCertMap.put("com.example", new URL("https://dl.dropboxusercontent.com/u/00000000/certificate.pem"));
SecureLoaderFactory mSecureLoaderFactory = new SecureLoaderFactory(this);
SecureDexClassLoader mSecureDexClassLoader = mSecureLoaderFactory.createDexClassLoader( jarContainerPath,
null,
getClass().getClassLoader(),
packageNamesToCertMap);
Class<?> loadedClass = mSecureDexClassLoader.loadClass("com.example.MyClass");
// Check whether the signature verification process succeeded
if (loadedClass != null) {
// No security constraints were violated and so
// class loading was successful.
myClassInstance = (MyClass) loadedClass.newInstance();
// Do something with the loaded object myClassInstance
// i.e. myClassInstance.doSomething();
}
} catch (ClassNotFoundException e) {
// This exception will be raised when the container of the target class
// is genuine but this class file is missing..
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
// The previous URL used for the packageNamesToCertMap entry was a malformed one.
Log.e("Error", "A malformed URL was provided for a remote certificate location");
}
```
*Et voilà..* now you have an instance of *"MyClass"* loaded in a **secure way** at **run time**!
## Next steps :)
* If you want to learn how to use *Grab'n Run* I suggest to start from the [tutorial](http://grab-n-run.readthedocs.org/en/latest/tutorial.html) and then moving on by analyzing the [example application](http://grab-n-run.readthedocs.org/en/latest/example.html).
* If you are interested in understanding what are the **security threats** of *improper dynamic code loading* fixed by GNR check out the [security resume](http://grab-n-run.readthedocs.org/en/latest/security.html).
* If you would like to implement cool features of GNR like **silent updates**, **handling more containers**, **concurrent code loading** or **dynamically loading JAR libraries in your applications** you should give a look at the [complementary topics](http://grab-n-run.readthedocs.org/en/latest/complementary.html).
* You may also need to **consult** the *JavaDoc-like* [API documentation](https://rawgit.com/lukeFalsina/Grab-n-Run/master/docs/javaDoc/index.html).
* Finally, you may want to convert automatically your applications to use Grab'n Run APIs for secure dynamic code loading. Give a try at the [repackaging tool](http://grab-n-run.readthedocs.org/en/latest/repackaging.html).
## License
*Grab'n Run* is released under the *Apache* license. Check the *COPYRIGHT* file for further details.
[](https://android-arsenal.com/details/1/1185)
================================================
FILE: docs/.gitignore
================================================
/_build/
/javaAPI/
make.bat
================================================
FILE: docs/.placeholder
================================================
================================================
FILE: docs/Makefile
================================================
# Makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
PAPER =
BUILDDIR = _build
# User-friendly check for sphinx-build
ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
endif
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
# the i18n builder cannot share the environment and doctrees with the others
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
help:
@echo "Please use \`make <target>' where <target> is one of"
@echo " html to make standalone HTML files"
@echo " dirhtml to make HTML files named index.html in directories"
@echo " singlehtml to make a single large HTML file"
@echo " pickle to make pickle files"
@echo " json to make JSON files"
@echo " htmlhelp to make HTML files and a HTML help project"
@echo " qthelp to make HTML files and a qthelp project"
@echo " devhelp to make HTML files and a Devhelp project"
@echo " epub to make an epub"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " latexpdf to make LaTeX files and run them through pdflatex"
@echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
@echo " text to make text files"
@echo " man to make manual pages"
@echo " texinfo to make Texinfo files"
@echo " info to make Texinfo files and run them through makeinfo"
@echo " gettext to make PO message catalogs"
@echo " changes to make an overview of all changed/added/deprecated items"
@echo " xml to make Docutils-native XML files"
@echo " pseudoxml to make pseudoxml-XML files for display purposes"
@echo " linkcheck to check all external links for integrity"
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
clean:
rm -rf $(BUILDDIR)/*
html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
dirhtml:
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
singlehtml:
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
@echo
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
pickle:
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
@echo
@echo "Build finished; now you can process the pickle files."
json:
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
@echo
@echo "Build finished; now you can process the JSON files."
htmlhelp:
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
@echo
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in $(BUILDDIR)/htmlhelp."
qthelp:
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
@echo
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/docgrabnrun.qhcp"
@echo "To view the help file:"
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/docgrabnrun.qhc"
devhelp:
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
@echo
@echo "Build finished."
@echo "To view the help file:"
@echo "# mkdir -p $$HOME/.local/share/devhelp/docgrabnrun"
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/docgrabnrun"
@echo "# devhelp"
epub:
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
@echo
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
latex:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
@echo "Run \`make' in that directory to run these through (pdf)latex" \
"(use \`make latexpdf' here to do that automatically)."
latexpdf:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through pdflatex..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
latexpdfja:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through platex and dvipdfmx..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
text:
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
@echo
@echo "Build finished. The text files are in $(BUILDDIR)/text."
man:
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
@echo
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
texinfo:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
@echo "Run \`make' in that directory to run these through makeinfo" \
"(use \`make info' here to do that automatically)."
info:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo "Running Texinfo files through makeinfo..."
make -C $(BUILDDIR)/texinfo info
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
gettext:
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
@echo
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
changes:
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
@echo
@echo "The overview file is in $(BUILDDIR)/changes."
linkcheck:
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
@echo
@echo "Link check complete; look for any errors in the above output " \
"or in $(BUILDDIR)/linkcheck/output.txt."
doctest:
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
@echo "Testing of doctests in the sources finished, look at the " \
"results in $(BUILDDIR)/doctest/output.txt."
xml:
$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
@echo
@echo "Build finished. The XML files are in $(BUILDDIR)/xml."
pseudoxml:
$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
@echo
@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
================================================
FILE: docs/complementary.rst
================================================
Complementary topics
====================
In the end of this documentation a couple of not so trivial use cases of *Grab'n Run* are presented. This section will not introduce new core concepts but it may help the developer to handle some **tricky situations**. For such a reason feel free to **skip this part** and eventually **come back later** to revise it whenever you will encounter one of the following situations while using the library.
Handle containers whose classes come from different package names which have a common relevant prefix
-----------------------------------------------------------------------------------------------------
Before starting diving in this section it is important to recall the **relationship between package name and containers**.
**Package name in apk containers**
*Apk* containers must contain just **one package name**, which must be chosen by the developer when a new application is created. The package name is then stored in the *Android Manifest* of the application. In order to have an application being admitted on the *Google Play* store, it is also fundamental that the chosen package name is **unique** and should **not change** for the whole life cycle of the application.
**Package name in jar containers**
*Jar* containers on the other hand do **not** have such a **strict policy** as in *apk* containers. Hypothetically each class file contained in a *jar* archive may have a different package name and this mean that **many package names** can be present in the **same** *jar* container.
**Common relevant prefix**
In *Grab'n Run* two package names share a relevant common prefix if their prefix match for at least two words separated by one dot.
**Example:**
Consider the following package names:
A. ``com.example.polimi``
B. ``it.example.polimi``
C. ``com.test``
D. ``com.example.application.system``
E. ``com.example.polimi.system``
* A. and B. do **not** share any **common relevant prefix** since they differ in the initial word of the package name (``com`` vs ``it``).
* A. and C. do **not** share any **common relevant prefix** since they just have one word of the package name in common (``com``).
* A. and D. share a **common relevant prefix** (``com.example``).
* A. and E. share a **common relevant prefix** (``com.example.polimi``).
Given these insights a first interesting situation to consider is when a developer wants to *load dynamically classes* from an external *jar* library which contains **more than one package name** that, anyway, share a **common relevant prefix**. Let us assume for example that the target library has the following structure:
.. image:: images/JarContStructure.png
In such a scenario we have four classes (``ClassA``, ``ClassB``, ``ClassC``, ``ClassD``) which belongs to **three different packages**, whose names are respectively ``com.example``, ``com.example.system`` and ``com.example.system.preference``. Let use also assume that this container has being signed with a *valid self-signed certificate*, remotely located at ``https://something.com/example_cert.pem``.
Questions now for the developer are:
1. *How should I fill in the associative map which links package names to remote certificate location in order to being able to load all the classes in this container?*
2. *Am I obliged to insert all three package names pointing to the very same certificate?*
Luckily the answer for the second question is **no**, which means that there is indeed an **easier way** to perform the job. *Grab'n Run* in fact was thought to make the whole dynamic class loading **secure but** at the same time **simple** for applications developers.
You can in fact handle this situation correctly by simply inserting into the associative map a **single entry** where the *key corresponds to the shortest among the package names* belonging to one of the classes that need to be loaded and the *value is the location of the remote certificate* used to sign the container. So in the **previous case** since the classes with the shortest package name are ``com.example.ClassA`` and ``com.example.ClassB`` the following code is appropriate to populate the map::
Map<String, URL> packageNamesToCertMap = new HashMap<String, URL>();
try {
packageNamesToCertMap.put( "com.example",
new URL("https://something.com/example_cert.pem"));
} catch (MalformedURLException e) {
// The previous entry for the map may not necessarily be the right one
// but still it is not malformed so no exception should be raised.
Log.e(TAG_MAIN, "A malformed URL was provided for a remote certificate location");
}
For the rest the developer may proceed as shown in :ref:`Using SecureDexClassLoader to load dynamic code securely`. The result will be that the container is going to be verified against the appropriate certificate and, if it is **genuine**, it will be *also possible to load the other two classes* in the archive with a **different package name** (``com.example.system.ClassC`` and ``com.example.system.preference.ClassD``).
Handle containers whose classes come from different package names with no relevant common prefix
------------------------------------------------------------------------------------------------
Even if it is not such a common situation it is possible for a *jar* archive to *contain classes which belongs to different package names* and does not share any common relevant prefix.
This situation, on the other hand, is **not practical** for *apk* containers since, in order to be **published** on Google Market,
an application needs to have a **single** package name which more over must **not change** during its whole life cycle.
Anyway let us try to sketch the case of the previous cited jar archive and how to handle it with ``SecureDexClassLoader``. As an example we can consider the
scenario in which the goal is loading two classes, whose full class names are respectively ``com.example.MyFirstClass`` and ``com.test.MySecondClass`` and so
which **differs** in the **package name** but are **both stored** in the **same container** ``exampleJar.jar``.
It is also supposed that this container has being signed with a *valid self-signed certificate*, remotely located at ``https://something.com/example_cert.pem``.
In order to handle this situation correctly the developer is required to fill the **associative map** which links package names and certificates
with **two entries**, one per each package name, which will *point to the same remote certificate*. This is exemplified in the following snippet of code::
Map<String, URL> packageNamesToCertMap = new HashMap<String, URL>();
try {
packageNamesToCertMap.put( "com.example",
new URL("https://something.com/example_cert.pem"));
packageNamesToCertMap.put( "com.test",
new URL("https://something.com/example_cert.pem"));
} catch (MalformedURLException e) {
// The previous entries for the map may not be necessarily the right ones
// but still they are not malformed so no exception should be raised.
Log.e(TAG_MAIN, "A malformed URL was provided for a remote certificate location");
}
For the rest the developer may proceed as shown in :ref:`Using SecureDexClassLoader to load dynamic code securely` and this procedure grants to succeed in the loading
process for any of the two classes independently on the order in which they are attempted to be loaded.
.. note::
By design ``SecureDexClassLoader`` assumes that **each package name** is intrinsically related to a **single container**, while it is not necessary true the opposite.
This means that attempting to *load a class*, whose **package name** is associated with **more than one container** provided in *dexPath* (i.e. each one of the two
containers contains at least one class with the same package name), will generate an **unpredictable behavior** since ``SecureDexClassLoader`` will associate
that package name with just one of the two containers.
So it is a **developer responsibility** to check the containers in order to avoid the occurrence of this rare but undesirable situation.
.. _Reverse package name to obtain remote certificate URL:
Reverse package name to obtain remote certificate URL
-----------------------------------------------------
*Grab'n Run* provides as an extra feature the possibility to **reconstruct the remote URL location of the certificate by reversing the package name** provided into the associative map. To enable this feature simply add an entry to the associative map where the **key** is the **desired package name to reverse** and the **value** is ``null``.
Here is a simple snippet of code to exemplify::
Map<String, URL> packageNamesToCertMap = new HashMap<String, URL>();
// Notice that a null entry won't raise a MalformedURLException..
packageNamesToCertMap.put("it.polimi.necst.mylibrary", null);
What is going on behind the curtains is that whenever GNR find an entry with *a valid package name associated to a null value*, it will **reverse the package name** with the following convention:
The **first word** of the package name will be considered as the **top level domain (TLD)**, while the **second** one is going to be the **main domain**. Any **following word** of the package name will be used in the **same order** as they are listed to define the **file path** on the remote server and of course since a secure connection is needed for the certificate, **HTTPS protocol** will be enforced.
Let us translate this theory with some concrete examples:
* Package name ``it`` won't be reverted since it contains just a world (at least two are required for real world package name).
* Package name ``it.polimi`` will be reverted to the URL ``https://polimi.it/certificate.pem``.
* Package name ``it.polimi.necst.mylibrary`` will be reverted to the URL ``https://polimi.it/necst/mylibrary/certificate.pem``.
As you can see from the previous examples this naming convention assumes that the **final certificate** will be found in the *remote folder obtained by reverting the package name* and that the **certificate file** will have been **always renamed** ``certificate.pem``.
Perform dynamic code loading concurrently
-----------------------------------------
.. warning::
Before approaching this paragraph, a good idea is having **first read** the :doc:`security` section of this documentation and in particular the last part on performance-related topics.
By default when a new ``SecureDexClassLoader`` object is instantiated, it will immediately **validate** all of its **containers concurrently** (**Eager signature verification strategy**). By the way sometimes when a large number of containers are assigned to a single ``SecureDexClassLoader`` object, it may just be *more convenient to evaluate each container separately just before loading classes from it*. So in such a scenario a **lazy signature verification strategy** would be advisable.
An even better *performance concern strategy* is loading target classes in a **concurrent** way on different threads. This is perfectly fine with *Grab'n Run* since the library is **thread-safe**.
As an example let us consider the case in which we want to *concurrently load some classes with a lazy strategy* from a ``SecureDexClassLoader`` instance with many containers associated to it. A possible code implementation which also makes use of `Executors <https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html>`_ , `FixedThreadPool <https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html#newFixedThreadPool(int)>`_ and `Future <https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html>`_ classes is the following::
// Make the assumption that packageNamesToCertMap has been already initialized;
// moreover longListOfDexPath is the String with all the containers path listed and
// separated by :
SecureLoaderFactory mSecureLoaderFactory = new SecureLoaderFactory(this);
// Initialize a SecureDexClassLoader instance in LAZY mode.
SecureDexClassLoader mSecureDexClassLoader =
mSecureLoaderFactory.createDexClassLoader( longListOfDexPath,
null,
getClass().getClassLoader(),
packageNamesToCertMap,
true);
// Suppose these classes belongs only to three different containers;
// while longListOfDexPath points to ten containers..
String[] classesToLoad = new String[] { "com.example.classA",
"it.polimi.classB",
"de.application.classC",
"com.example.classD",
"it.polimi.classE"};
// Suppose to store the loaded classes here..
Set<Class<?>> loadedClassesSet = Collections.synchronizedSet(new HashSet<Class<?>>());
// Initialize the thread pool executor with number of thread
// equals to the number of classes to load..
ExecutorService threadLoadClassPool = Executors.newFixedThreadPool(classesToLoad.size());
List<Future<?>> futureTaskList = new ArrayList<Future<?>>();
Iterator<String> classesToLoadIterator = classesToLoad.iterator();
while (classesToLoadIterator.hasNext()) {
String classNameToLoad = classesToLoadIterator.next();
// Submit a new class load thread on a container and store
// a reference in the future objects list.
Future<?> futureTask =
threadLoadClassPool.submit(new classLoadingTask(mSecureDexClassLoader,
classNameToLoad,
loadedClassesSet));
futureTaskList.add(futureTask);
}
// Stop accepting new tasks for the current threadLoadClassPool
threadLoadClassPool.shutdown();
for (Future<?> futureTask : futureTaskList) {
try {
// Wait till the current task for class loading is finished..
futureTask.get();
} catch (InterruptedException | ExecutionException e) {
// Issue while executing the verification on a thread
e.printStackTrace()
}
}
try {
// Join all the threads here.. Use a timeout eventually..
threadLoadClassPool.awaitTermination( KEEP_ALIVE_NUMBER_OF_TIME_UNITS,
KEEP_ALIVE_TIME_UNIT);
} catch (InterruptedException e) {
// One or more of the threads objects were still busy..
// And this should not happen..
e.printStackTrace()
}
And finally here it is the ``classLoadingTask``, an implementation of the `Runnable <https://docs.oracle.com/javase/7/docs/api/java/lang/Runnable.html>`_ interface, which is responsible for **dynamically loading** a single class with the previously created ``SecureDexClassLoader`` instance. Here is the class implementation::
class classLoadingTask implements Runnable {
// The shared instance of SecureDexClassLoader for concurrent load ops.
private SecureDexClassLoader mSecureDexClassLoader;
// The name of the class to load.
private String classNameToLoad;
// Concurrent set of class objects that were successfully loaded.
private Set<String> successLoadedClassesSet;
public classLoadingTask( SecureDexClassLoader mSecureDexClassLoader,
String classNameToLoad,
Set<String> successLoadedClassesSet) {
// Simply copy all the incoming parameters..
this.mSecureDexClassLoader = mSecureDexClassLoader;
this.classNameToLoad = classNameToLoad;
this.successLoadedClassesSet = successLoadedClassesSet;
}
@Override
public void run() {
// Set current thread priority to DEFAULT.
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_DEFAULT);
try {
// Load operation is invoked..
Class<?> loadedClass = mSecureDexClassLoader.loadClass(classNameToLoad);
// Check whether the loading operation succeeds
if (loadedClass != null) {
// Class loading was successful and performed in a safe way.
// Add this class to the concurrent set
successLoadedClassesSet.add(loadedClass);
}
} catch (ClassNotFoundException e) {
// This exception will be raised when the container of the
// target class is genuine but this class file is missing..
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
The interesting **advantage** of this *concurrent evaluation* is that **only the first loaded class** belonging to each separate container will perform the **signature verification** process when the ``loadClass()`` method is invoked, while all the other loaded classes from the same container will benefit from the cached result of this verification and so their evaluation will be way faster (comparable to the ``loadClass()`` time execution of ``DexClassLoader``).
.. note::
Using this **concurrent lazy approach** is a good way to *lower the performance overhead* that may be introduced by *Grab'n Run* and *keep your application always responsive*. Another slight shrewdness that you may consider when you are in need to *load many classes from containers that have to be downloaded* is considering to show a `ProgressDialog <http://developer.android.com/reference/android/app/ProgressDialog.html>`_ or a similar object to *make the user aware that your application is performing some tasks that require him/her to wait* and at the same time prevent the user from clicking everywhere or terminating your application since it sometimes may seem not fully responsive.
.. * By now use SecureDexClassLoader in Lazy mode. Instantiate such an object on the main thread.
.. * Initialize a thread executor and then makes each thread load a class from the same SecureDexClassLoader object. Evaluation of containers will be performed only by the first thread to load a class into a container while the others will use the cached verification mechanism to directly load or reject loading for their target class.
.. * Remember to put a join instruction at the end of the code block on the main thread to be sure that after that line all the classes that you need have attempted to being loaded.
On library developer side: how to prepare a valid library container compatible with GNR
---------------------------------------------------------------------------------------
For once in this tutorial the **focus is now moved** from the *application developer*, who wants to load classes from an external library, **to the library developer**, who wrote a library and wants to make it available to the application developers.
What we are going to discuss about in this section is **how a library developer should prepare his/her library** in order to have it **compatible with GNR** system and more in general with **dynamic code loading**. A hint in this sense is provided by DexClassLoader `documentation <http://developer.android.com/reference/dalvik/system/DexClassLoader.html>`_, which states clearly that this class, and so also ``SecureDexClassLoader`` does, *"loads classes from .jar and .apk files containing a classes.dex entry."*.
.. note::
The procedure outlined below must be performed entirely in case that you want to **export a library** into a *jar* container. The *typical use case* for such a situation is whenever you want to *export a library* which was *initially thought to work just for regular Java applications* but that now you would *also like to execute into an Android application*.
On the other hand, if you decide to **export an Android application** as a source for dynamic class loading, part of the upcoming procedure won't be necessary anymore. This happens because:
1. When an *apk* container is generated, ``dx`` tool is automatically invoked. This means that by considering a valid *apk* container as a source for classes to load, the ``classes.dex`` entry will be already present and so you won't need to manually execute step *1* and step *2* of the following guide.
2. Since Android requires an *apk* container to be signed to allow execution, you can decide, whenever you are ready to **export your application as a library**, to right click on the project and choose ``Android Tools -> Export Signed Application Package...``. By completing the wizard procedure, you are going to export a signed version of the final *apk* container and this basically covers the first *4* steps of the following guide.
So let us assume that you, as a library developer, want to export your project called "MyLibrary" into a *jar* archive compatible with ``SecureDexClassLoader``. The following steps should be performed:
1. Export the project "MyLibrary" into a jar archive.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. highlight:: bash
If your project was developed using **Android Studio**, you can easily obtain a copy of your *jar* library by opening a terminal and pointing it to the main folder of your project and then by invoking a series of tasks through the ``./gradlew`` script as shown here::
$ cd <absolute_path_to_your_jar_lib_project>
$ ./gradlew clean build assembleRelease
If the build process goes smoothly, you should now be able to find a file presumably called *"MyLibrary-release.jar"* located under one of your project ``build/outputs`` folder.
.. highlight:: java
On the other hand if you are relying on the **ADT (Android Development Tool)**, right-click on the project *"MyLibrary"* and select "Export...".
.. image:: images/ExportJarOption.png
Then choose the option "Jar File" and click "Next...".
.. image:: images/ExportJarFile.png
Finally choose the location of the exported *jar* archive by clicking on the "Browse..." button and then "Finish".
.. image:: images/ExportJarFinish.png
Independently from which of the two methods you implied, you should have now successfully exported your project into a *jar* container!
2. Translate Java Byte Code (.class) into Dalvik Byte Code (classes.dex).
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
After having exported your project into a *jar* container you now have code that can run on a **Java Virtual Machine (JVM)** in the form of class file with the extensions ``.class``. Nevertheless in order to have your **code running** with ``SecureDexClassLoader`` **on an Android phone** it is necessary to **translate** the class files from Java Bytecode to **Dalvik Bytecode**. This task can be accomplished easily thanks to the ``dx`` tool, present in the Android SDK folder.
.. note::
Notice that **Dalvik Bytecode** is also compatible with the new `Android Runtime (ART) <https://source.android.com/devices/tech/dalvik/art.html>`_ system. This means that, except for narrow cases, you won't generally need to worry since your library code should execute fine on both the *Dalvik Virtual Machine (DVM)* and the *Android Runtime (ART)*. As related to this guide and more in general to *Grab'n Run*, *choosing one runtime system in stead of the other should not be an issue at all*.
.. highlight:: bash
So by assuming that you have just exported the project into a file called *myLibrary.jar* in a terminal type the following commands::
$ cd <path_to_exported_jar>
$ /<path_to_sdk>/build-tools/<last_stable_sdk_version>/dx --dex --output=myLibrary-dex.jar myLibrary.jar
The result is an output *jar* container called *myLibrary-dex.jar*. You can easily spot that no ``.class`` file is stored in this container and in stead a file called ``classes.dex`` was added. This is the direct **result of the translation** mentioned before.
3. Generate a keypair and export the developer certificate
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If this is the first time that you sign a container you will need to **generate a key pair** with ``keytool`` and then **export a certificate** containing the newly created public key. Otherwise if you *already have a key pair and the associated certificate, simply skip this section* and continue reading from the next one.
In order to **generate a keystore and a key pair** type in the following command line in a terminal::
$ keytool -genkey -v -keystore my-release-key.keystore -alias alias_name -keyalg RSA -keysize 2048 -validity 10000
This line prompts you for passwords for the keystore and private key, and to provide the Distinguished Name fields for your key. It then generates the keystore as a file called ``my-release-key.keystore``. The keystore will contain a single key, valid for 10000 days. The **alias** is a name that you choose to **identify keys** inside the keystore. In this case this private key will be identified as ``alias_name``.
If the previous step succeeded, now it is time to **export your developer certificate** that will be used by *application developers to verify your library code before dynamically loading it*. This can be accomplished again thanks to a ``keytool`` feature::
$ keytool -exportcert -keystore my-release-key.keystore -alias alias_name -file certificate.pem
This command will export the certificate embedding the public key associated to the private key whose alias is ``alias_name``. This certificate will be stored in the file ``certificate.pem``.
Even if the previous commands are all that you will need here, if you desire to deepen your knowledge on *keystore, keys and signing Android applications* visit these reference links:
* https://www.digitalocean.com/community/tutorials/java-keytool-essentials-working-with-java-keystores
* http://developer.android.com/tools/publishing/app-signing.html#signing-manually
4. Sign the library with the developer private key.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Now it is time to **sign** the *jar* library with the **library developer private key** to enable the possibility to verify it.
Assuming that you have generated a private key whose alias is ``alias_name`` and stored it in a keystore whose name is ``my-release-key.keystore`` in order to sign the *jar* container manually type in this line in your terminal::
$ jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore my-release-key.keystore myLibrary-dex.jar alias_name
You can then verify that the jar container is actually signed by typing::
$ jarsigner -verify -verbose -certs myLibrary-dex.jar
.. highlight:: java
.. note::
When you verify the signature of the final container, you will receive a **warning message** like the following *"This jar contains entries whose certificate chain is not validated"*. This is absolutely normal since a **self-signed certificate** was used for the **verification process** and this is acceptable in Android as long as you are absolutely *sure that the certificate used for the verification is actually the library developer one*. In *Grab'n Run* the **chain of trust** is replaced by assuming that the certificate is stored on a domain which is directly controlled by the library developer and can only be retrieved via **HTTPS protocol**.
5. Make the library and the certificate publicly available.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The last step is **making public the signed version of the jar container**, obtained after the previous step, and the **exported certificate** embedding the library developer public key (*as explained in* `3. Generate a keypair and export the developer certificate`_ ).
While you can *store the library container basically everywhere on the web* (application developers can retrieve your library via both HTTP or HTTPS protocol), it is **crucial and fundamental** for the whole security model to handle that you **publish your library developer certificate on a secure trustworthy remote location which can be accessed only via HTTPS protocol**.
If you have successfully followed up all the previous steps, you have now correctly **published your library** and application developers will be able to **run your code securely** by using ``SecureDexClassLoader``.
Let GNR automatically handle library updates silently
-----------------------------------------------------
In the end of this section **silent updating**, a *powerful feature* of **dynamic code loading**, is presented and easily and securely implemented with the use of *Grab'n Run*. Performing silent updates is a convenient techniques which can be used to **keep always updated third-party libraries or frameworks** by *decoupling the update process of the main application from those ones of the non-standalone libraries*. The **advantage** of such an approach is clearly the possibility to have always the **latest features and security workaround on third-party libraries** without continuously bothering the user on updating the application.
Dynamic code loading in this sense can be really effective in such a scenario since the latest version of the code can be retrieved from a remote URL just at runtime and then immediately executed.
Let us now set up a possible use case for this technique and see how to implement it with Grab'n Run from both the library developer and the application developer side: imagine that an application developer wants to dynamically load the latest version of the already seen class ``com.example.ClassA`` stored in "myLibrary-dex.jar", a remote library.
From the point of view of the **library developer** a couple of prerequisite steps must be performed:
* The developer must prepare correctly a **signed version** of his/her library. For a complete walk-through on this task see the previous section `On library developer side: how to prepare a valid library container compatible with GNR`_.
* Once that the last version of the library container is correctly prepared and signed, the **developer must publish** on a domain that (s)he controls a **redirect link** (i.e. ``http://mylibrary.it/downloads/mobile/latest``) which *points to the remote location where the library container is actually stored* (i.e. ``http://mylibrary.it/downloads/mobile/myLibrary-dex-1-8.jar``).
* The developer must also set up a **secure link using HTTPS protocol**, which *points to the remote location of the certificate* associated to the private key used to sign the last version of the library (i.e. ``https://myLibrary.com/developerCert.pem``).
* Every time that a **new version of the same library is ready** (i.e. version 1.9 of myLibrary is now available), the library developer will have to prepare the container in the usual way and sign it with the **SAME** private key associated to ``developerCert.pem`` and finally **update the redirect link** to *point to the location of the latest version of the container* (i.e. set up ``http://mylibrary.it/downloads/mobile/latest`` to redirect to ``http://mylibrary.it/downloads/mobile/myLibrary-dex-1-9.jar``).
.. warning::
While *Grab'n Run* **supports redirect links for the container remote location**, this kind of link is arbitrarily not accepted for remote certificates!!! This is a **security-oriented choice** since redirect links may jump from an HTTPS link to an HTTP one making the whole system insecure in case that the attacker performs a **Man-In-The-Middle-Attack** and substitute the proper certificate for the verification with a different one generated by himself. That is the reason why **redirect links for remote certificates will not be followed** by Grab'n Run and so no certificate file will be found for the container signature verification.
On the other hand the **application developer**, who wants to make use of the classes provided by ``myLibrary`` can easily accomplish this by setting up a ``SecureDexClassLoader`` where the *location pointing to the remote container* is the **redirect link** provided by the library developer and the **certificate** used for the verification is the *one stored at the secure URL on the library developer domain*. Here is a snippet of code that summarizes this operational description::
ClassA classAInstance = null;
// The latest version of the library container is always found thanks to the redirect link
jarContainerRemotePath = "http://mylibrary.it/downloads/mobile/latest";
try {
Map<String, URL> packageNamesToCertMap = new HashMap<String, URL>();
// The package "com.example" is always signed by the library developer with
// the same private key and so it can always be verified with the same
// remote certificate.
packageNamesToCertMap.put( "com.example",
new URL("https://myLibrary.com/developerCert.pem"));
// The second parameter used here specifies how many days are counted before
// a cached copy of the remote library container is considered rotten
// and automatically discarded.
// Default value is 5 days, here the value is lowered to 3..
SecureLoaderFactory mSecureLoaderFactory = new SecureLoaderFactory(this, 3);
SecureDexClassLoader mSecureDexClassLoader =
mSecureLoaderFactory.createDexClassLoader( jarContainerRemotePath,
null,
packageNamesToCertMap,
getClass().getClassLoader());
Class<?> loadedClass = mSecureDexClassLoader.loadClass("com.example.ClassA");
// Check whether the signature verification process succeeds
if (loadedClass != null) {
// Class loading was successful and performed in a safe way.
// The last version of ClassA has been successfully retrieved!
classAInstance = (ClassA) loadedClass.newInstance();
// Do something with the loaded object classAInstance
// i.e. classAInstance.doSomething();
}
} catch (ClassNotFoundException e) {
// This exception will be raised when the container of the target class
// is genuine but this class file is missing..
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
// The previous URL used for the packageNamesToCertMap entry was a malformed one.
Log.e("Error", "A malformed URL was provided for a remote certificate location");
}
.. Library developer side:
.. * Read previous section.
.. * Use a redirect HTTP link to point to the last version of the signed jar library container
.. * Use an HTTPS link to make the certificate for verification public
.. Application developer side:
.. * Initialize SecureDexClassLoader with dexPath pointing to the redirect HTTP link for the updated container and associate the package name to the remote URL of the library developer certificate
.. DONE :)
================================================
FILE: docs/conf.py
================================================
# -*- coding: utf-8 -*-
#
# docgrabnrun documentation build configuration file, created by
# sphinx-quickstart on Tue Sep 23 09:59:33 2014.
#
# This file is execfile()d with the current directory set to its
# containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
import sys
import os
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
sys.path.insert(0, os.path.abspath('../../grab-n-run/gnr/src/'))
# -- General configuration ------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.doctest',
#'javasphinx',
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix of source filenames.
source_suffix = '.rst'
# The encoding of source files.
#source_encoding = 'utf-8-sig'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = u'docgrabnrun'
copyright = u'2014, Luca Falsina'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = '1.0'
# The full version, including alpha/beta/rc tags.
release = '1.0'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#language = None
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
#today_fmt = '%B %d, %Y'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = ['_build']
# The reST default role (used for this markup: `text`) to use for all
# documents.
#default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
#add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
#show_authors = False
# The language used in code block to set keywords highlight.
highlight_language = 'java'
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# A list of ignored prefixes for module index sorting.
#modindex_common_prefix = []
# If true, keep warnings as "system message" paragraphs in the built documents.
#keep_warnings = False
# -- Options for HTML output ----------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
html_theme = 'default'
# Haiku theme
# html_theme = 'haiku'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#html_theme_options = {}
# Add any paths that contain custom themes here, relative to this directory.
#html_theme_path = []
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
#html_title = None
# A shorter title for the navigation bar. Default is the same as html_title.
#html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
#html_logo = None
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
#html_favicon = None
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# Add any extra paths that contain custom files (such as robots.txt or
# .htaccess) here, relative to this directory. These files are copied
# directly to the root of the documentation.
#html_extra_path = []
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
#html_additional_pages = {}
# If false, no module index is generated.
#html_domain_indices = True
# If false, no index is generated.
#html_use_index = True
# If true, the index is split into individual pages for each letter.
#html_split_index = False
# If true, links to the reST sources are added to the pages.
#html_show_sourcelink = True
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
#html_show_sphinx = True
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
#html_show_copyright = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
#html_use_opensearch = ''
# This is the file name suffix for HTML files (e.g. ".xhtml").
#html_file_suffix = None
# Output file base name for HTML help builder.
htmlhelp_basename = 'docgrabnrundoc'
# -- Options for LaTeX output ---------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#'preamble': '',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
('index', 'docgrabnrun.tex', u'docgrabnrun Documentation',
u'Luca Falsina', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
#latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#latex_use_parts = False
# If true, show page references after internal links.
#latex_show_pagerefs = False
# If true, show URL addresses after external links.
#latex_show_urls = False
# Documents to append as an appendix to all manuals.
#latex_appendices = []
# If false, no module index is generated.
#latex_domain_indices = True
# -- Options for manual page output ---------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
('index', 'docgrabnrun', u'docgrabnrun Documentation',
[u'Luca Falsina'], 1)
]
# If true, show URL addresses after external links.
#man_show_urls = False
# -- Options for Texinfo output -------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
('index', 'docgrabnrun', u'docgrabnrun Documentation',
u'Luca Falsina', 'docgrabnrun', 'One line description of project.',
'Miscellaneous'),
]
# Documents to append as an appendix to all manuals.
#texinfo_appendices = []
# If false, no module index is generated.
#texinfo_domain_indices = True
# How to display URL addresses: 'footnote', 'no', or 'inline'.
#texinfo_show_urls = 'footnote'
# If true, do not generate a @detailmenu in the "Top" node's menu.
#texinfo_no_detailmenu = False
================================================
FILE: docs/example.rst
================================================
Discussion of an example project
================================
Before digging into this section, you are **strongly** encouraged to read :doc:`tutorial` for an **introductory description** on the features of Grab`n Run library.
The **aim of the sample application** is to give you some *hints on how to use the classes in Grab'n Run and how they will behave across different contexts*. The **source code** of the example can be found in the ``example`` folder of *Grab'n Run* repository.
Different extracts of code will be considered and explained in the following sections of this page but before analyzing the code it may be convenient to retrieve it and to set up an **already prepared Android smart phone emulator** that contains all the containers needed to run the example code..
Retrieve the example code and the emulator
------------------------------------------
Retrieve Grab'n Run full repository
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
At first you will need to recover *Grab'n Run* example code. In order to do so you need to have **Git** installed on your machine.
The latest version can be found at Git download `page <http://git-scm.com/downloads>`_.
.. highlight:: bash
Next open a terminal and **clone** the example repository into ``grab-n-run``, a local folder located at ``absolute_path_to_gnr_repo``, through Git::
$ cd <absolute_path_to_gnr_repo>
$ mkdir grab-n-run
$ cd grab-n-run
$ git clone "https://github.com/lukeFalsina/Grab-n-Run.git"
.. highlight:: java
At the end of the process you will have all the GNR code locally including a copy of the *example application* and of the *documentation*.
Include Grab'n Run example code in your IDE
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The next step is *importing the example sources* into an **IDE**. The process will be now described for both **Android Studio (AS)** and **Android Development Tool (ADT)**.
a. **Android Studio (AS)**
In the welcome window of Android Studio select from the *Quick Start* menu the option "Open an existing Android Studio project".
.. image:: images/ASImportGNR1.png
Next navigate to the ``grab-n-run`` folder in which you previously cloned the repository and then pick the project ``AS`` from the ``example`` subfolder as shown in the image below.
.. image:: images/ASImportGNR2.png
The example project should have been now successfully imported! It may be necessary to rebulit it again by picking the option "Make Project".
.. image:: images/ASImportGNR3.png
**P.S.** Notice that you can open in *Android Studio* also the **original GNR library project** by using the very same procedure but by picking the ``gnr`` Studio project from the main ``grab-n-run`` folder in stead of the ``example/AS`` one.
.. image:: images/ASImportGNR4.png
b. **Android Development Tool (ADT)**
At first right click in the *Package Explorer* and select "Import.."
.. image:: images/ADTImportGNR1.png
Next select under the *Android* folder "Existing Android Code Into Workspace" and then "Next >"
.. image:: images/ADTImportGNR2.png
By pressing the "Browse..." button point the *Root Directory* to the ``grab-n-run`` folder in which you previously cloned the repository and then to the subfolder ``grab-n-run/example/ADT``. You should be now able to the see and select the candidate project ``ExampleAppGNR`` (*an example application which makes use of GNR*). In the end press "Finish" to import the example project. Below you can see a screenshot which summarizes all the settings before the "Finish" button is clicked.
.. image:: images/ADTImportGNR3.png
At the end of this process you should have been able to **correctly import** the example application!
.. image:: images/ADTImportGNR4.png
Retrieve and set up the emulator
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. highlight:: bash
Then it is time to retrieve the **emulator** used to run the example application. You can easily find it in the ``assets`` folder of the ``example`` repository.
So once that you have located the compressed file ``ExampleAppGNREmu.tar.gz`` containing the emulator, open a terminal and at first copy this file into your *home* folder::
$ cd <absolute_path_to_gnr_repo>/example/
$ cp ExampleAppGNREmu.tar.gz ~
Next decompress this container::
$ cd ~
$ tar xzf ExampleAppGNREmu.tar.gz
This operation will generate two files, a folder called ``ExampleAppGNREmu.avd`` and a configuration file ``ExampleAppGNREmu.ini``. In the end move these two files into the Android emulator folder, normally located at ``/home/<your_username>/.android/avd``::
$ mv ExampleAppGNREmu.avd ExampleAppGNREmu.ini .android/avd
The last step consist in editing the ``path`` variable stored in the configuration file. So open ``ExampleAppGNREmu.ini`` at the final location with a text editor and change the path variable in order to match the current location of the ``ExampleAppGNREmu.avd`` folder. So if my user name is for example *bill90*, I need to change the path variable from ``path=/home/<USER_NAME>/.android/avd/ExampleAppGNREmu.avd`` to ``path=/home/bill90/.android/avd/ExampleAppGNREmu.avd``.
.. highlight:: java
Before starting the emulator in your **IDE**, remember to **verify that the SDK version 17** is installed on your machine since the emulator targets that version. Otherwise you can *also edit the emulator configuration* from your IDE to target a different and **more recent** version of the SDK which is installed on your machine.
.. note::
Android emulator is unfortunately pretty slow and requires also a big bunch of resources and that is the reason why it may be not supported by different machines. A couple of empirical suggestions in this direction are the following:
* If possible, try to target directly **SDK version 17**, as it results to me that the more recent SDK version you target, the more time the emulator requires before setting up.
* It is a really good idea to enable the **snapshot feature**. This lets the system frame the current situation of the emulator when you turn it off and load it back whenever you restart the emulator with a *significant reduction of the waiting time*. This `post <http://stackoverflow.com/questions/1554099/why-is-the-android-emulator-so-slow>`_ explains how to enable the feature.
* Emulator can be switched between landscape and portrait view by pressing ``ctrl + F12``. This can be useful to interact properly with the example application.
When the emulator is finally set up, you can start it in either **ADT Eclipse** or **Android Studio** (it may take time depending on your machine..). Next, whenever you want to run the example code and the IDE asks which device should be used, remember to **select this emulator as the running Android device**.
In case you need to integrate this previous concise walk-through, please give a look at these other resources:
* https://blahti.wordpress.com/2011/08/24/how-to-export-and-import-android-virtual-device-avd-files/
* http://stackoverflow.com/questions/4575167/android-how-to-copy-the-emulator-to-a-friend-for-testing
List of example containers
--------------------------
In order to understand correctly the following detailed discussion, it is fundamental to first introduce the containers (*jar* and *apk* archives), retrieved for the code loading in the example code. Here is a list of the string variables that store the path to various containers:
* ``exampleSignedAPKPath``: URI of a **benign** toy *apk* container signed with a valid *developer certificate*.
* ``exampleTestAPKPath``: path location pointing to the same **benign** *apk* container but this time signed with the *Android Debug Certificate*.
* ``exampleSignedChangedAPKPath``: URI pointing to a **handled version** of the same container stored at ``exampleSignedAPKPath`` in which a part of the signatures has been modified.
* ``jarContainerPath``: path location to the **benign** *jar* container used to customize the view elements inside an example activity.
* ``jarContainerRepackPath``: URI pointing to a **malicious repackaged** version of the original container stored at ``jarContainerPath``.
MainActivity.java
-----------------
`MainActivity <https://github.com/lukeFalsina/Grab-n-Run/blob/master/example/src/it/polimi/poccodeloading/MainActivity.java>`_ is the **entry point** of the sample application. In its overloaded method ``onCreate()`` it initializes through a ``ListView`` a set of buttons used to select the *different test cases* present in the application.
DexClassLoader (apk) vs SecureDexClassLoader (apk)
----------------------------------------------------
In this first scenario you will consider how to retrieve an `Activity <http://developer.android.com/reference/android/app/Activity.html>`_ class, whose name is ``NasaDailyImage``, stored in the *apk* container, called *test.apk*, through the use of `DexClassLoader <http://developer.android.com/reference/dalvik/system/DexClassLoader.html>`_ and ``SecureDexClassLoader``.
The relevant **code** in this case is the one of the two methods ``setUpDexClassLoader()`` and ``setUpSecureDexClassLoader()``, which are triggered by tapping the related two buttons on the ``MainActivity`` view.
setUpDexClassLoader()
~~~~~~~~~~~~~~~~~~~~~
In this method a standard initialization of a ``DexClassLoader`` is applied.
So at first the usual **application-private, writable directory** for caching loaded *.dex* classes must be set up.
Then a ``DexClassLoader`` object is initialized using *test.apk*, a container located directly in the phone external storage ( as described by ``exampleTestAPKPath``), as its *jar path* for the classes to load.
Finally the ``NasaDailyImage`` Activity is loaded. If such an operation is successful the **simple name** of the **loaded class** is shown to the user through a *toast message*; otherwise different **exceptions** are raised and show again through a toast message an appropriate helper message.
setUpSecureDexClassLoader()
~~~~~~~~~~~~~~~~~~~~~~~~~~~
In this method **repeated** ``loadClass()`` **calls** are performed on differently initialized ``SecureDexClassLoader`` instances in order to *show different behaviors* of the loader class while retrieving the usual ``NasaDailyImage`` Activity.
At first a ``SecureLoaderFactory`` object is created. Then this instance is used to generate three ``SecureDexClassLoader`` that covers different cases and ends up with different results on the load operation:
1. **Test case 1:** Load a class through ``SecureDexClassLoader`` without providing an associative map for certificates location
This first test case shows a **possible error** that a developer may encounter when using this library for the first time.
If you want to have the location of the certificate being computed by reversing the package name, as explained in :ref:`Reverse package name to obtain remote certificate URL`, you still need to **populate an associative map** with entries like (*"any.package.name"*, **null**) and use it as a parameter of the method ``createDexClassLoader()``. To understand why the class works in this way think of this system as a kind of `white listing <http://en.wikipedia.org/wiki/Whitelist>`_. Only those classes inside package names which are *declared into the associative map* or *directly descend* from one of the declared package names will be considered as possible valid ones, while all classes belonging to a **not listed package name or not a descendant of the declared ones** will be **immediately rejected**.
And this is exactly what happens in this test case where **no associative map is provided** and so all the classes in the two containers, including the target ``NasaDailyImage``, are **prevented from being loaded** since there is *no clue on the certificate location*.
2. **Test case 2:** Unsuccessful load of a class through ``SecureDexClassLoader`` with an associative map *(Debug certificate)*
In the second test case you can see different ways to **populate** the associative map ``packageNamesToCertMap``, used to *link packages with certificates location*.
.. warning::
Always keep in mind that **prior** to **downloading** a certificate from the **web** the certificate for that package will be **searched inside the application-private directory** reserved for certificates and then possibly at the remote location. If you wish to *just look at the remote URL* without considering cached certificates, always remember to **wipe out private application data** through the invocation of the method ``wipeOutPrivateAppCachedData()`` **before dismissing** your ``SecureDexClassLoader`` instances. In such a way every time that a new ``SecureDexClassLoader`` is created, you will be sure that no cached resource will be associated with it.
The first ``put()`` *call* inserts the package name *headfirstlab.nasadailyimage* of the class that we would like to load later in the example and associates it with a **valid remote URL**. What you can immediately notice by pointing your browser to that URL is that the *remote certificate* in this case is a **self-signed developer** one since the **subject** of the certificate is **also** the **issuer** of it but, as it is mentioned in the :doc:`tutorial`, this is perfectly fine in the **Android** environment.
The *second entry* inserted into the associative map provides a *remote URL* to an **inexistent certificate** (once again you can try to point there your browser to easy spot this out). More over since *no certificate for the package name ``it.polimi.example`` has been already cached into the application-private certificate directory*, then **no certificate** is **available** for it and that is the reason why *any class* belonging to the ``it.polimi.example`` package will be **rejected and prevented from being loaded** by ``SecureDexClassLoader``.
Lastly the third ``put()`` call on the associative map will insert a package name that will be also used to *construct the remote certificate URL* (**reverse package name**). Once again the final remote URL (``https://polimi.it/example3/certificate.pem``) points to no certificate so any class, whose package name is *it.polimi.example3*, will be rejected from being loaded.
In the end a ``SecureDexClassLoader`` is generated using as a container file a valid *apk* containing the target class but **signed with a certificate**, the *Debug Android Certificate*, which is different from the one issued by the developer. For such a reason the result of the ``loadClass()`` method will be that *no class object is going to be returned* since the apk is **not signed** with the **required certificate**.
3. **Test case 3:** Unsuccessful load of a class through ``SecureDexClassLoader`` with an associative map *(Failed signatures verification of some container's entries)*
In the third test case you can immediately notice that all the settings for the invocation of ``SecureDexClassLoader`` are equals to those of the previous case except for the chosen *apk* container. In fact, while before the container was signed with a non valid certificate, this time the container is signed with the **right certificate** but someone **modified** a couple of the **entries signature**, which do not match anymore with the one obtained during the signing procedure. To sum up also in this case *no class will be loaded* since this container results to be **partially corrupted** and so not safe.
4. **Test case 4:** Successful load of a class through ``SecureDexClassLoader`` with an associative map
In this last test case a **successful example** of dynamic code loading is shown. This time ``SecureDexClassLoader`` is initialized with a **valid** *apk* container, **signed** with the **correct developer certificate**, and with the associative map previously initialized in *Test case 2*. The whole process works fine since this associative map contains the necessary key entry *headfirstlab.nasadailyimage* and the related developer **certificate** has been **already cached** during *Test case 2*. Finally during the **signature verification step** inside the ``loadClass()`` method all the entries inside the container match properly with their signature and the certificate used for that signing process is exactly the one linked to *headfirstlab.nasadailyimage* package. That is the reason why *dynamic loading* of ``NasaDailyImage`` activity is **allowed**.
DexClassLoader (jar) vs SecureDexClassLoader (jar)
----------------------------------------------------
A different scenario to show the power of *dynamic code* loading and the **security weakness** of the standard ``DexClassLoader`` is represented by the following example. In this case another activity (the source code is contained into *DexClassSampleActivity.java*) instantiates a certain number of **GUI components** (a couple of buttons, a text view, a switch..) and then **customizes** them according to the methods of an object belonging to the **external** class ``ComponentModifier``, which is **dynamically loaded** at run time.
Depending on the user choice (tapping the first button in stead of the second one) a different extension class of ``ComponentModifier`` is loaded and a different behavior is shown to the user even if the static code shown in ``DexClassSampleActivity`` is exactly the same (as you can easily check by inspecting the method ``onBtnClick()``). This loading operation can be realized easily by means of ``DexClassLoader`` as shown in the method ``retrieveComponentModifier()`` of the source code..
That's just a pity that the container used to load dynamically the class by ``DexClassLoader`` in this example is actually *randomly selected at run time* between either a benign version or a **repackaged one** of the original *apk* and so **malicious code** could potentially have been **executed** *without the user even notice it*!
But let's explain how this could possibly happen: in ``DexClassSampleActivity`` there is a simple private method called ``randomContainerPathChoice()``, which in this case is invoked before the instantiation of both ``DexClassLoader`` and ``SecureDexClassLoader`` and which **select randomly the path** of either the **benign** version of the ``ComponentModifier`` container, stored in the string ``jarContainerPath``, or the path of the **repackaged** one with the string ``jarContainerRepackPath``.
``DexClassLoader`` *won't notice and care* about this difference as long as in both the containers there is an implementation of the required **target class** to load and that is the reason why repeating tapping on the first button ''Click me!'' in the Activity screen multiple times will end up in executing two different version of the same ``FirstComponentModifierImpl`` class.
On the other hand if you perform the same experiment with ``SecureDexClassLoader`` the repackaged *apk* container choice this time will be detected and blocked during the **signature verification procedure** against the developer certificate in the ``loadClass()`` method. This is possible since *malicious modified entries will not succeed in the signature verification check computed by considering both the initial signature stored inside the container and the developer certificate* retrieved from the associative map used to initialize the ``SecureDexClassLoader`` instance. Thanks to this, ``SecureDexClassLoader`` **won't load** the customization classes inside the *repackaged container* and it will just **end up the activity**, which is exactly the **secure** behavior that you, *as a developer*, would like to obtain :)
.. Create PackageContext
.. ---------------------
.. Coming soon.. More or less ;)
================================================
FILE: docs/index.rst
================================================
.. docgrabnrun documentation master file, created by
sphinx-quickstart on Tue Sep 23 09:59:33 2014.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to Grab'n Run documentation!
====================================
*Grab'n Run* (aka **GNR**) is a **simple** and **effective** Java Library that you can add to your Android projects to secure *dynamic class loading* operations.
For a **quick start** on how to include the library and how to use it in your projects give a look at :doc:`tutorial`.
For a brief explanation on the **issue** of *insecure dynamic class loading* and on Grab'n Run purpose check the :doc:`security` section.
A concise **example** of use of the library is provided into an Android toy-application `here <https://github.com/lukeFalsina/Grab-n-Run/tree/master/example>`_. A *full explanation* of key extracts of this code is given into the :doc:`example` section.
For a description on Grab'n Run **API** in *JavaDoc* style please refer to the `API documentation <https://rawgit.com/lukeFalsina/Grab-n-Run/master/docs/javaDoc/index.html>`_.
For those willing for more **technicalities** and **advanced features** implemented in *Grab'n Run*, the section on :doc:`complementary` is a *must-read*. This part of the documentation can also be used for **reference** as it presents how to handle properly some **tricky situations** that may occur while using *GNR*.
For an introduction on how to use the POC script for rewriting your application automatically to use the secure Grab'n Run API instead of the regualr ones for dynamic
code loading, check out the :doc:`repackaging` section.
.. toctree::
:maxdepth: 2
tutorial
security
example
complementary
repackaging
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
================================================
FILE: docs/javaDoc/allclasses-frame.html
================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- NewPage -->
<html lang="en">
<head>
<!-- Generated by javadoc (version 1.7.0_72) on Mon Nov 17 19:29:57 CET 2014 -->
<title>All Classes</title>
<meta name="date" content="2014-11-17">
<link rel="stylesheet" type="text/css" href="stylesheet.css" title="Style">
</head>
<body>
<h1 class="bar">All Classes</h1>
<div class="indexContainer">
<ul>
<li><a href="it/necst/grabnrun/SecureDexClassLoader.html" title="class in it.necst.grabnrun" target="classFrame">SecureDexClassLoader</a></li>
<li><a href="it/necst/grabnrun/SecureLoaderFactory.html" title="class in it.necst.grabnrun" target="classFrame">SecureLoaderFactory</a></li>
</ul>
</div>
</body>
</html>
================================================
FILE: docs/javaDoc/allclasses-noframe.html
================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- NewPage -->
<html lang="en">
<head>
<!-- Generated by javadoc (version 1.7.0_72) on Mon Nov 17 19:29:57 CET 2014 -->
<title>All Classes</title>
<meta name="date" content="2014-11-17">
<link rel="stylesheet" type="text/css" href="stylesheet.css" title="Style">
</head>
<body>
<h1 class="bar">All Classes</h1>
<div class="indexContainer">
<ul>
<li><a href="it/necst/grabnrun/SecureDexClassLoader.html" title="class in it.necst.grabnrun">SecureDexClassLoader</a></li>
<li><a href="it/necst/grabnrun/SecureLoaderFactory.html" title="class in it.necst.grabnrun">SecureLoaderFactory</a></li>
</ul>
</div>
</body>
</html>
================================================
FILE: docs/javaDoc/constant-values.html
================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- NewPage -->
<html lang="en">
<head>
<!-- Generated by javadoc (version 1.7.0_72) on Mon Nov 17 19:29:57 CET 2014 -->
<title>Constant Field Values</title>
<meta name="date" content="2014-11-17">
<link rel="stylesheet" type="text/css" href="stylesheet.css" title="Style">
</head>
<body>
<script type="text/javascript"><!--
if (location.href.indexOf('is-external=true') == -1) {
parent.document.title="Constant Field Values";
}
//-->
</script>
<noscript>
<div>JavaScript is disabled on your browser.</div>
</noscript>
<!-- ========= START OF TOP NAVBAR ======= -->
<div class="topNav"><a name="navbar_top">
<!-- -->
</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
<!-- -->
</a>
<ul class="navList" title="Navigation">
<li><a href="it/necst/grabnrun/package-summary.html">Package</a></li>
<li>Class</li>
<li>Use</li>
<li><a href="overview-tree.html">Tree</a></li>
<li><a href="deprecated-list.html">Deprecated</a></li>
<li><a href="index-files/index-1.html">Index</a></li>
<li><a href="help-doc.html">Help</a></li>
</ul>
</div>
<div class="subNav">
<ul class="navList">
<li>Prev</li>
<li>Next</li>
</ul>
<ul class="navList">
<li><a href="index.html?constant-values.html" target="_top">Frames</a></li>
<li><a href="constant-values.html" target="_top">No Frames</a></li>
</ul>
<ul class="navList" id="allclasses_navbar_top">
<li><a href="allclasses-noframe.html">All Classes</a></li>
</ul>
<div>
<script type="text/javascript"><!--
allClassesLink = document.getElementById("allclasses_navbar_top");
if(window==top) {
allClassesLink.style.display = "block";
}
else {
allClassesLink.style.display = "none";
}
//-->
</script>
</div>
<a name="skip-navbar_top">
<!-- -->
</a></div>
<!-- ========= END OF TOP NAVBAR ========= -->
<div class="header">
<h1 title="Constant Field Values" class="title">Constant Field Values</h1>
<h2 title="Contents">Contents</h2>
<ul>
<li><a href="#it.necst">it.necst.*</a></li>
</ul>
</div>
<div class="constantValuesContainer"><a name="it.necst">
<!-- -->
</a>
<h2 title="it.necst">it.necst.*</h2>
<ul class="blockList">
<li class="blockList">
<table border="0" cellpadding="3" cellspacing="0" summary="Constant Field Values table, listing constant fields, and values">
<caption><span>it.necst.grabnrun.<a href="it/necst/grabnrun/SecureLoaderFactory.html" title="class in it.necst.grabnrun">SecureLoaderFactory</a></span><span class="tabEnd"> </span></caption>
<tr>
<th class="colFirst" scope="col">Modifier and Type</th>
<th scope="col">Constant Field</th>
<th class="colLast" scope="col">Value</th>
</tr>
<tbody>
<tr class="altColor">
<td class="colFirst"><a name="it.necst.grabnrun.SecureLoaderFactory.DEFAULT_DAYS_BEFORE_CONTAINER_EXPIRACY">
<!-- -->
</a><code>public static final int</code></td>
<td><code><a href="it/necst/grabnrun/SecureLoaderFactory.html#DEFAULT_DAYS_BEFORE_CONTAINER_EXPIRACY">DEFAULT_DAYS_BEFORE_CONTAINER_EXPIRACY</a></code></td>
<td class="colLast"><code>5</code></td>
</tr>
</tbody>
</table>
</li>
</ul>
</div>
<!-- ======= START OF BOTTOM NAVBAR ====== -->
<div class="bottomNav"><a name="navbar_bottom">
<!-- -->
</a><a href="#skip-navbar_bottom" title="Skip navigation links"></a><a name="navbar_bottom_firstrow">
<!-- -->
</a>
<ul class="navList" title="Navigation">
<li><a href="it/necst/grabnrun/package-summary.html">Package</a></li>
<li>Class</li>
<li>Use</li>
<li><a href="overview-tree.html">Tree</a></li>
<li><a href="deprecated-list.html">Deprecated</a></li>
<li><a href="index-files/index-1.html">Index</a></li>
<li><a href="help-doc.html">Help</a></li>
</ul>
</div>
<div class="subNav">
<ul class="navList">
<li>Prev</li>
<li>Next</li>
</ul>
<ul class="navList">
<li><a href="index.html?constant-values.html" target="_top">Frames</a></li>
<li><a href="constant-values.html" target="_top">No Frames</a></li>
</ul>
<ul class="navList" id="allclasses_navbar_bottom">
<li><a href="allclasses-noframe.html">All Classes</a></li>
</ul>
<div>
<script type="text/javascript"><!--
allClassesLink = document.getElementById("allclasses_navbar_bottom");
if(window==top) {
allClassesLink.style.display = "block";
}
else {
allClassesLink.style.display = "none";
}
//-->
</script>
</div>
<a name="skip-navbar_bottom">
<!-- -->
</a></div>
<!-- ======== END OF BOTTOM NAVBAR ======= -->
</body>
</html>
================================================
FILE: docs/javaDoc/deprecated-list.html
================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- NewPage -->
<html lang="en">
<head>
<!-- Generated by javadoc (version 1.7.0_72) on Mon Nov 17 19:29:57 CET 2014 -->
<title>Deprecated List</title>
<meta name="date" content="2014-11-17">
<link rel="stylesheet" type="text/css" href="stylesheet.css" title="Style">
</head>
<body>
<script type="text/javascript"><!--
if (location.href.indexOf('is-external=true') == -1) {
parent.document.title="Deprecated List";
}
//-->
</script>
<noscript>
<div>JavaScript is disabled on your browser.</div>
</noscript>
<!-- ========= START OF TOP NAVBAR ======= -->
<div class="topNav"><a name="navbar_top">
<!-- -->
</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
<!-- -->
</a>
<ul class="navList" title="Navigation">
<li><a href="it/necst/grabnrun/package-summary.html">Package</a></li>
<li>Class</li>
<li>Use</li>
<li><a href="overview-tree.html">Tree</a></li>
<li class="navBarCell1Rev">Deprecated</li>
<li><a href="index-files/index-1.html">Index</a></li>
<li><a href="help-doc.html">Help</a></li>
</ul>
</div>
<div class="subNav">
<ul class="navList">
<li>Prev</li>
<li>Next</li>
</ul>
<ul class="navList">
<li><a href="index.html?deprecated-list.html" target="_top">Frames</a></li>
<li><a href="deprecated-list.html" target="_top">No Frames</a></li>
</ul>
<ul class="navList" id="allclasses_navbar_top">
<li><a href="allclasses-noframe.html">All Classes</a></li>
</ul>
<div>
<script type="text/javascript"><!--
allClassesLink = document.getElementById("allclasses_navbar_top");
if(window==top) {
allClassesLink.style.display = "block";
}
else {
allClassesLink.style.display = "none";
}
//-->
</script>
</div>
<a name="skip-navbar_top">
<!-- -->
</a></div>
<!-- ========= END OF TOP NAVBAR ========= -->
<div class="header">
<h1 title="Deprecated API" class="title">Deprecated API</h1>
<h2 title="Contents">Contents</h2>
</div>
<!-- ======= START OF BOTTOM NAVBAR ====== -->
<div class="bottomNav"><a name="navbar_bottom">
<!-- -->
</a><a href="#skip-navbar_bottom" title="Skip navigation links"></a><a name="navbar_bottom_firstrow">
<!-- -->
</a>
<ul class="navList" title="Navigation">
<li><a href="it/necst/grabnrun/package-summary.html">Package</a></li>
<li>Class</li>
<li>Use</li>
<li><a href="overview-tree.html">Tree</a></li>
<li class="navBarCell1Rev">Deprecated</li>
<li><a href="index-files/index-1.html">Index</a></li>
<li><a href="help-doc.html">Help</a></li>
</ul>
</div>
<div class="subNav">
<ul class="navList">
<li>Prev</li>
<li>Next</li>
</ul>
<ul class="navList">
<li><a href="index.html?deprecated-list.html" target="_top">Frames</a></li>
<li><a href="deprecated-list.html" target="_top">No Frames</a></li>
</ul>
<ul class="navList" id="allclasses_navbar_bottom">
<li><a href="allclasses-noframe.html">All Classes</a></li>
</ul>
<div>
<script type="text/javascript"><!--
allClassesLink = document.getElementById("allclasses_navbar_bottom");
if(window==top) {
allClassesLink.style.display = "block";
}
else {
allClassesLink.style.display = "none";
}
//-->
</script>
</div>
<a name="skip-navbar_bottom">
<!-- -->
</a></div>
<!-- ======== END OF BOTTOM NAVBAR ======= -->
</body>
</html>
================================================
FILE: docs/javaDoc/help-doc.html
================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- NewPage -->
<html lang="en">
<head>
<!-- Generated by javadoc (version 1.7.0_72) on Mon Nov 17 19:29:57 CET 2014 -->
<title>API Help</title>
<meta name="date" content="2014-11-17">
<link rel="stylesheet" type="text/css" href="stylesheet.css" title="Style">
</head>
<body>
<script type="text/javascript"><!--
if (location.href.indexOf('is-external=true') == -1) {
parent.document.title="API Help";
}
//-->
</script>
<noscript>
<div>JavaScript is disabled on your browser.</div>
</noscript>
<!-- ========= START OF TOP NAVBAR ======= -->
<div class="topNav"><a name="navbar_top">
<!-- -->
</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
<!-- -->
</a>
<ul class="navList" title="Navigation">
<li><a href="it/necst/grabnrun/package-summary.html">Package</a></li>
<li>Class</li>
<li>Use</li>
<li><a href="overview-tree.html">Tree</a></li>
<li><a href="deprecated-list.html">Deprecated</a></li>
<li><a href="index-files/index-1.html">Index</a></li>
<li class="navBarCell1Rev">Help</li>
</ul>
</div>
<div class="subNav">
<ul class="navList">
<li>Prev</li>
<li>Next</li>
</ul>
<ul class="navList">
<li><a href="index.html?help-doc.html" target="_top">Frames</a></li>
<li><a href="help-doc.html" target="_top">No Frames</a></li>
</ul>
<ul class="navList" id="allclasses_navbar_top">
<li><a href="allclasses-noframe.html">All Classes</a></li>
</ul>
<div>
<script type="text/javascript"><!--
allClassesLink = document.getElementById("allclasses_navbar_top");
if(window==top) {
allClassesLink.style.display = "block";
}
else {
allClassesLink.style.display = "none";
}
//-->
</script>
</div>
<a name="skip-navbar_top">
<!-- -->
</a></div>
<!-- ========= END OF TOP NAVBAR ========= -->
<div class="header">
<h1 class="title">How This API Document Is Organized</h1>
<div class="subTitle">This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.</div>
</div>
<div class="contentContainer">
<ul class="blockList">
<li class="blockList">
<h2>Package</h2>
<p>Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain six categories:</p>
<ul>
<li>Interfaces (italic)</li>
<li>Classes</li>
<li>Enums</li>
<li>Exceptions</li>
<li>Errors</li>
<li>Annotation Types</li>
</ul>
</li>
<li class="blockList">
<h2>Class/Interface</h2>
<p>Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:</p>
<ul>
<li>Class inheritance diagram</li>
<li>Direct Subclasses</li>
<li>All Known Subinterfaces</li>
<li>All Known Implementing Classes</li>
<li>Class/interface declaration</li>
<li>Class/interface description</li>
</ul>
<ul>
<li>Nested Class Summary</li>
<li>Field Summary</li>
<li>Constructor Summary</li>
<li>Method Summary</li>
</ul>
<ul>
<li>Field Detail</li>
<li>Constructor Detail</li>
<li>Method Detail</li>
</ul>
<p>Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.</p>
</li>
<li class="blockList">
<h2>Annotation Type</h2>
<p>Each annotation type has its own separate page with the following sections:</p>
<ul>
<li>Annotation Type declaration</li>
<li>Annotation Type description</li>
<li>Required Element Summary</li>
<li>Optional Element Summary</li>
<li>Element Detail</li>
</ul>
</li>
<li class="blockList">
<h2>Enum</h2>
<p>Each enum has its own separate page with the following sections:</p>
<ul>
<li>Enum declaration</li>
<li>Enum description</li>
<li>Enum Constant Summary</li>
<li>Enum Constant Detail</li>
</ul>
</li>
<li class="blockList">
<h2>Use</h2>
<p>Each documented package, class and interface has its own Use page. This page describes what packages, classes, methods, constructors and fields use any part of the given class or package. Given a class or interface A, its Use page includes subclasses of A, fields declared as A, methods that return A, and methods and constructors with parameters of type A. You can access this page by first going to the package, class or interface, then clicking on the "Use" link in the navigation bar.</p>
</li>
<li class="blockList">
<h2>Tree (Class Hierarchy)</h2>
<p>There is a <a href="overview-tree.html">Class Hierarchy</a> page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with <code>java.lang.Object</code>. The interfaces do not inherit from <code>java.lang.Object</code>.</p>
<ul>
<li>When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.</li>
<li>When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.</li>
</ul>
</li>
<li class="blockList">
<h2>Deprecated API</h2>
<p>The <a href="deprecated-list.html">Deprecated API</a> page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.</p>
</li>
<li class="blockList">
<h2>Index</h2>
<p>The <a href="index-files/index-1.html">Index</a> contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.</p>
</li>
<li class="blockList">
<h2>Prev/Next</h2>
<p>These links take you to the next or previous class, interface, package, or related page.</p>
</li>
<li class="blockList">
<h2>Frames/No Frames</h2>
<p>These links show and hide the HTML frames. All pages are available with or without frames.</p>
</li>
<li class="blockList">
<h2>All Classes</h2>
<p>The <a href="allclasses-noframe.html">All Classes</a> link shows all classes and interfaces except non-static nested types.</p>
</li>
<li class="blockList">
<h2>Serialized Form</h2>
<p>Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.</p>
</li>
<li class="blockList">
<h2>Constant Field Values</h2>
<p>The <a href="constant-values.html">Constant Field Values</a> page lists the static final fields and their values.</p>
</li>
</ul>
<em>This help file applies to API documentation generated using the standard doclet.</em></div>
<!-- ======= START OF BOTTOM NAVBAR ====== -->
<div class="bottomNav"><a name="navbar_bottom">
<!-- -->
</a><a href="#skip-navbar_bottom" title="Skip navigation links"></a><a name="navbar_bottom_firstrow">
<!-- -->
</a>
<ul class="navList" title="Navigation">
<li><a href="it/necst/grabnrun/package-summary.html">Package</a></li>
<li>Class</li>
<li>Use</li>
<li><a href="overview-tree.html">Tree</a></li>
<li><a href="deprecated-list.html">Deprecated</a></li>
<li><a href="index-files/index-1.html">Index</a></li>
<li class="navBarCell1Rev">Help</li>
</ul>
</div>
<div class="subNav">
<ul class="navList">
<li>Prev</li>
<li>Next</li>
</ul>
<ul class="navList">
<li><a href="index.html?help-doc.html" target="_top">Frames</a></li>
<li><a href="help-doc.html" target="_top">No Frames</a></li>
</ul>
<ul class="navList" id="allclasses_navbar_bottom">
<li><a href="allclasses-noframe.html">All Classes</a></li>
</ul>
<div>
<script type="text/javascript"><!--
allClassesLink = document.getElementById("allclasses_navbar_bottom");
if(window==top) {
allClassesLink.style.display = "block";
}
else {
allClassesLink.style.display = "none";
}
//-->
</script>
</div>
<a name="skip-navbar_bottom">
<!-- -->
</a></div>
<!-- ======== END OF BOTTOM NAVBAR ======= -->
</body>
</html>
================================================
FILE: docs/javaDoc/index-files/index-1.html
================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- NewPage -->
<html lang="en">
<head>
<!-- Generated by javadoc (version 1.7.0_72) on Mon Nov 17 19:29:57 CET 2014 -->
<title>C-Index</title>
<meta name="date" content="2014-11-17">
<link rel="stylesheet" type="text/css" href="../stylesheet.css" title="Style">
</head>
<body>
<script type="text/javascript"><!--
if (location.href.indexOf('is-external=true') == -1) {
parent.document.title="C-Index";
}
//-->
</script>
<noscript>
<div>JavaScript is disabled on your browser.</div>
</noscript>
<!-- ========= START OF TOP NAVBAR ======= -->
<div class="topNav"><a name="navbar_top">
<!-- -->
</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
<!-- -->
</a>
<ul class="navList" title="Navigation">
<li><a href="../it/necst/grabnrun/package-summary.html">Package</a></li>
<li>Class</li>
<li>Use</li>
<li><a href="../overview-tree.html">Tree</a></li>
<li><a href="../deprecated-list.html">Deprecated</a></li>
<li class="navBarCell1Rev">Index</li>
<li><a href="../help-doc.html">Help</a></li>
</ul>
</div>
<div class="subNav">
<ul class="navList">
<li>Prev Letter</li>
<li><a href="index-2.html">Next Letter</a></li>
</ul>
<ul class="navList">
<li><a href="../index.html?index-filesindex-1.html" target="_top">Frames</a></li>
<li><a href="index-1.html" target="_top">No Frames</a></li>
</ul>
<ul class="navList" id="allclasses_navbar_top">
<li><a href="../allclasses-noframe.html">All Classes</a></li>
</ul>
<div>
<script type="text/javascript"><!--
allClassesLink = document.getElementById("allclasses_navbar_top");
if(window==top) {
allClassesLink.style.display = "block";
}
else {
allClassesLink.style.display = "none";
}
//-->
</script>
</div>
<a name="skip-navbar_top">
<!-- -->
</a></div>
<!-- ========= END OF TOP NAVBAR ========= -->
<div class="contentContainer"><a href="index-1.html">C</a> <a href="index-2.html">D</a> <a href="index-3.html">I</a> <a href="index-4.html">L</a> <a href="index-5.html">S</a> <a href="index-6.html">W</a> <a name="_C_">
<!-- -->
</a>
<h2 class="title">C</h2>
<dl>
<dt><span class="strong"><a href="../it/necst/grabnrun/SecureLoaderFactory.html#createDexClassLoader(java.lang.String,%20java.lang.String,%20java.lang.ClassLoader,%20java.util.Map)">createDexClassLoader(String, String, ClassLoader, Map<String, URL>)</a></span> - Method in class it.necst.grabnrun.<a href="../it/necst/grabnrun/SecureLoaderFactory.html" title="class in it.necst.grabnrun">SecureLoaderFactory</a></dt>
<dd>
<div class="block">Creates a <a href="../it/necst/grabnrun/SecureDexClassLoader.html" title="class in it.necst.grabnrun"><code>SecureDexClassLoader</code></a> that finds interpreted and native code in a set of
provided locations (either local or remote via HTTP or HTTPS) in dexPath.</div>
</dd>
<dt><span class="strong"><a href="../it/necst/grabnrun/SecureLoaderFactory.html#createDexClassLoader(java.lang.String,%20java.lang.String,%20java.lang.ClassLoader,%20java.util.Map,%20boolean)">createDexClassLoader(String, String, ClassLoader, Map<String, URL>, boolean)</a></span> - Method in class it.necst.grabnrun.<a href="../it/necst/grabnrun/SecureLoaderFactory.html" title="class in it.necst.grabnrun">SecureLoaderFactory</a></dt>
<dd>
<div class="block">This method returns a <a href="../it/necst/grabnrun/SecureDexClassLoader.html" title="class in it.necst.grabnrun"><code>SecureDexClassLoader</code></a> instance in the same way as it is
explained in the <a href="../it/necst/grabnrun/SecureLoaderFactory.html#createDexClassLoader(java.lang.String,%20java.lang.String,%20java.lang.ClassLoader,%20java.util.Map)"><code>createDexClassLoader(String, String, ClassLoader, Map)</code></a>.</div>
</dd>
</dl>
<a href="index-1.html">C</a> <a href="index-2.html">D</a> <a href="index-3.html">I</a> <a href="index-4.html">L</a> <a href="index-5.html">S</a> <a href="index-6.html">W</a> </div>
<!-- ======= START OF BOTTOM NAVBAR ====== -->
<div class="bottomNav"><a name="navbar_bottom">
<!-- -->
</a><a href="#skip-navbar_bottom" title="Skip navigation links"></a><a name="navbar_bottom_firstrow">
<!-- -->
</a>
<ul class="navList" title="Navigation">
<li><a href="../it/necst/grabnrun/package-summary.html">Package</a></li>
<li>Class</li>
<li>Use</li>
<li><a href="../overview-tree.html">Tree</a></li>
<li><a href="../deprecated-list.html">Deprecated</a></li>
<li class="navBarCell1Rev">Index</li>
<li><a href="../help-doc.html">Help</a></li>
</ul>
</div>
<div class="subNav">
<ul class="navList">
<li>Prev Letter</li>
<li><a href="index-2.html">Next Letter</a></li>
</ul>
<ul class="navList">
<li><a href="../index.html?index-filesindex-1.html" target="_top">Frames</a></li>
<li><a href="index-1.html" target="_top">No Frames</a></li>
</ul>
<ul class="navList" id="allclasses_navbar_bottom">
<li><a href="../allclasses-noframe.html">All Classes</a></li>
</ul>
<div>
<script type="text/javascript"><!--
allClassesLink = document.getElementById("allclasses_navbar_bottom");
if(window==top) {
allClassesLink.style.display = "block";
}
else {
allClassesLink.style.display = "none";
}
//-->
</script>
</div>
<a name="skip-navbar_bottom">
<!-- -->
</a></div>
<!-- ======== END OF BOTTOM NAVBAR ======= -->
</body>
</html>
================================================
FILE: docs/javaDoc/index-files/index-2.html
================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- NewPage -->
<html lang="en">
<head>
<!-- Generated by javadoc (version 1.7.0_72) on Mon Nov 17 19:29:57 CET 2014 -->
<title>D-Index</title>
<meta name="date" content="2014-11-17">
<link rel="stylesheet" type="text/css" href="../stylesheet.css" title="Style">
</head>
<body>
<script type="text/javascript"><!--
if (location.href.indexOf('is-external=true') == -1) {
parent.document.title="D-Index";
}
//-->
</script>
<noscript>
<div>JavaScript is disabled on your browser.</div>
</noscript>
<!-- ========= START OF TOP NAVBAR ======= -->
<div class="topNav"><a name="navbar_top">
<!-- -->
</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
<!-- -->
</a>
<ul class="navList" title="Navigation">
<li><a href="../it/necst/grabnrun/package-summary.html">Package</a></li>
<li>Class</li>
<li>Use</li>
<li><a href="../overview-tree.html">Tree</a></li>
<li><a href="../deprecated-list.html">Deprecated</a></li>
<li class="navBarCell1Rev">Index</li>
<li><a href="../help-doc.html">Help</a></li>
</ul>
</div>
<div class="subNav">
<ul class="navList">
<li><a href="index-1.html">Prev Letter</a></li>
<li><a href="index-3.html">Next Letter</a></li>
</ul>
<ul class="navList">
<li><a href="../index.html?index-filesindex-2.html" target="_top">Frames</a></li>
<li><a href="index-2.html" target="_top">No Frames</a></li>
</ul>
<ul class="navList" id="allclasses_navbar_top">
<li><a href="../allclasses-noframe.html">All Classes</a></li>
</ul>
<div>
<script type="text/javascript"><!--
allClassesLink = document.getElementById("allclasses_navbar_top");
if(window==top) {
allClassesLink.style.display = "block";
}
else {
allClassesLink.style.display = "none";
}
//-->
</script>
</div>
<a name="skip-navbar_top">
<!-- -->
</a></div>
<!-- ========= END OF TOP NAVBAR ========= -->
<div class="contentContainer"><a href="index-1.html">C</a> <a href="index-2.html">D</a> <a href="index-3.html">I</a> <a href="index-4.html">L</a> <a href="index-5.html">S</a> <a href="index-6.html">W</a> <a name="_D_">
<!-- -->
</a>
<h2 class="title">D</h2>
<dl>
<dt><span class="strong"><a href="../it/necst/grabnrun/SecureLoaderFactory.html#DEFAULT_DAYS_BEFORE_CONTAINER_EXPIRACY">DEFAULT_DAYS_BEFORE_CONTAINER_EXPIRACY</a></span> - Static variable in class it.necst.grabnrun.<a href="../it/necst/grabnrun/SecureLoaderFactory.html" title="class in it.necst.grabnrun">SecureLoaderFactory</a></dt>
<dd>
<div class="block">When a remote container URL is encountered, this field specifies the default time interval,
expressed in days, before which a local copy of a remote container, stored in an
application-private directory, will be considered fresh and so acceptable to be cached.</div>
</dd>
</dl>
<a href="index-1.html">C</a> <a href="index-2.html">D</a> <a href="index-3.html">I</a> <a href="index-4.html">L</a> <a href="index-5.html">S</a> <a href="index-6.html">W</a> </div>
<!-- ======= START OF BOTTOM NAVBAR ====== -->
<div class="bottomNav"><a name="navbar_bottom">
<!-- -->
</a><a href="#skip-navbar_bottom" title="Skip navigation links"></a><a name="navbar_bottom_firstrow">
<!-- -->
</a>
<ul class="navList" title="Navigation">
<li><a href="../it/necst/grabnrun/package-summary.html">Package</a></li>
<li>Class</li>
<li>Use</li>
<li><a href="../overview-tree.html">Tree</a></li>
<li><a href="../deprecated-list.html">Deprecated</a></li>
<li class="navBarCell1Rev">Index</li>
<li><a href="../help-doc.html">Help</a></li>
</ul>
</div>
<div class="subNav">
<ul class="navList">
<li><a href="index-1.html">Prev Letter</a></li>
<li><a href="index-3.html">Next Letter</a></li>
</ul>
<ul class="navList">
<li><a href="../index.html?index-filesindex-2.html" target="_top">Frames</a></li>
<li><a href="index-2.html" target="_top">No Frames</a></li>
</ul>
<ul class="navList" id="allclasses_navbar_bottom">
<li><a href="../allclasses-noframe.html">All Classes</a></li>
</ul>
<div>
<script type="text/javascript"><!--
allClassesLink = document.getElementById("allclasses_navbar_bottom");
if(window==top) {
allClassesLink.style.display = "block";
}
else {
allClassesLink.style.display = "none";
}
//-->
</script>
</div>
<a name="skip-navbar_bottom">
<!-- -->
</a></div>
<!-- ======== END OF BOTTOM NAVBAR ======= -->
</body>
</html>
================================================
FILE: docs/javaDoc/index-files/index-3.html
================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- NewPage -->
<html lang="en">
<head>
<!-- Generated by javadoc (version 1.7.0_72) on Mon Nov 17 19:29:57 CET 2014 -->
<title>I-Index</title>
<meta name="date" content="2014-11-17">
<link rel="stylesheet" type="text/css" href="../stylesheet.css" title="Style">
</head>
<body>
<script type="text/javascript"><!--
if (location.href.indexOf('is-external=true') == -1) {
parent.document.title="I-Index";
}
//-->
</script>
<noscript>
<div>JavaScript is disabled on your browser.</div>
</noscript>
<!-- ========= START OF TOP NAVBAR ======= -->
<div class="topNav"><a name="navbar_top">
<!-- -->
</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
<!-- -->
</a>
<ul class="navList" title="Navigation">
<li><a href="../it/necst/grabnrun/package-summary.html">Package</a></li>
<li>Class</li>
<li>Use</li>
<li><a href="../overview-tree.html">Tree</a></li>
<li><a href="../deprecated-list.html">Deprecated</a></li>
<li class="navBarCell1Rev">Index</li>
<li><a href="../help-doc.html">Help</a></li>
</ul>
</div>
<div class="subNav">
<ul class="navList">
<li><a href="index-2.html">Prev Letter</a></li>
<li><a href="index-4.html">Next Letter</a></li>
</ul>
<ul class="navList">
<li><a href="../index.html?index-filesindex-3.html" target="_top">Frames</a></li>
<li><a href="index-3.html" target="_top">No Frames</a></li>
</ul>
<ul class="navList" id="allclasses_navbar_top">
<li><a href="../allclasses-noframe.html">All Classes</a></li>
</ul>
<div>
<script type="text/javascript"><!--
allClassesLink = document.getElementById("allclasses_navbar_top");
if(window==top) {
allClassesLink.style.display = "block";
}
else {
allClassesLink.style.display = "none";
}
//-->
</script>
</div>
<a name="skip-navbar_top">
<!-- -->
</a></div>
<!-- ========= END OF TOP NAVBAR ========= -->
<div class="contentContainer"><a href="index-1.html">C</a> <a href="index-2.html">D</a> <a href="index-3.html">I</a> <a href="index-4.html">L</a> <a href="index-5.html">S</a> <a href="index-6.html">W</a> <a name="_I_">
<!-- -->
</a>
<h2 class="title">I</h2>
<dl>
<dt><a href="../it/necst/grabnrun/package-summary.html">it.necst.grabnrun</a> - package it.necst.grabnrun</dt>
<dd> </dd>
</dl>
<a href="index-1.html">C</a> <a href="index-2.html">D</a> <a href="index-3.html">I</a> <a href="index-4.html">L</a> <a href="index-5.html">S</a> <a href="index-6.html">W</a> </div>
<!-- ======= START OF BOTTOM NAVBAR ====== -->
<div class="bottomNav"><a name="navbar_bottom">
<!-- -->
</a><a href="#skip-navbar_bottom" title="Skip navigation links"></a><a name="navbar_bottom_firstrow">
<!-- -->
</a>
<ul class="navList" title="Navigation">
<li><a href="../it/necst/grabnrun/package-summary.html">Package</a></li>
<li>Class</li>
<li>Use</li>
<li><a href="../overview-tree.html">Tree</a></li>
<li><a href="../deprecated-list.html">Deprecated</a></li>
<li class="navBarCell1Rev">Index</li>
<li><a href="../help-doc.html">Help</a></li>
</ul>
</div>
<div class="subNav">
<ul class="navList">
<li><a href="index-2.html">Prev Letter</a></li>
<li><a href="index-4.html">Next Letter</a></li>
</ul>
<ul class="navList">
<li><a href="../index.html?index-filesindex-3.html" target="_top">Frames</a></li>
<li><a href="index-3.html" target="_top">No Frames</a></li>
</ul>
<ul class="navList" id="allclasses_navbar_bottom">
<li><a href="../allclasses-noframe.html">All Classes</a></li>
</ul>
<div>
<script type="text/javascript"><!--
allClassesLink = document.getElementById("allclasses_navbar_bottom");
if(window==top) {
allClassesLink.style.display = "block";
}
else {
allClassesLink.style.display = "none";
}
//-->
</script>
</div>
<a name="skip-navbar_bottom">
<!-- -->
</a></div>
<!-- ======== END OF BOTTOM NAVBAR ======= -->
</body>
</html>
================================================
FILE: docs/javaDoc/index-files/index-4.html
================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- NewPage -->
<html lang="en">
<head>
<!-- Generated by javadoc (version 1.7.0_72) on Mon Nov 17 19:29:57 CET 2014 -->
<title>L-Index</title>
<meta name="date" content="2014-11-17">
<link rel="stylesheet" type="text/css" href="../stylesheet.css" title="Style">
</head>
<body>
<script type="text/javascript"><!--
if (location.href.indexOf('is-external=true') == -1) {
parent.document.title="L-Index";
}
//-->
</script>
<noscript>
<div>JavaScript is disabled on your browser.</div>
</noscript>
<!-- ========= START OF TOP NAVBAR ======= -->
<div class="topNav"><a name="navbar_top">
<!-- -->
</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
<!-- -->
</a>
<ul class="navList" title="Navigation">
<li><a href="../it/necst/grabnrun/package-summary.html">Package</a></li>
<li>Class</li>
<li>Use</li>
<li><a href="../overview-tree.html">Tree</a></li>
<li><a href="../deprecated-list.html">Deprecated</a></li>
<li class="navBarCell1Rev">Index</li>
<li><a href="../help-doc.html">Help</a></li>
</ul>
</div>
<div class="subNav">
<ul class="navList">
<li><a href="index-3.html">Prev Letter</a></li>
<li><a href="index-5.html">Next Letter</a></li>
</ul>
<ul class="navList">
<li><a href="../index.html?index-filesindex-4.html" target="_top">Frames</a></li>
<li><a href="index-4.html" target="_top">No Frames</a></li>
</ul>
<ul class="navList" id="allclasses_navbar_top">
<li><a href="../allclasses-noframe.html">All Classes</a></li>
</ul>
<div>
<script type="text/javascript"><!--
allClassesLink = document.getElementById("allclasses_navbar_top");
if(window==top) {
allClassesLink.style.display = "block";
}
else {
allClassesLink.style.display = "none";
}
//-->
</script>
</div>
<a name="skip-navbar_top">
<!-- -->
</a></div>
<!-- ========= END OF TOP NAVBAR ========= -->
<div class="contentContainer"><a href="index-1.html">C</a> <a href="index-2.html">D</a> <a href="index-3.html">I</a> <a href="index-4.html">L</a> <a href="index-5.html">S</a> <a href="index-6.html">W</a> <a name="_L_">
<!-- -->
</a>
<h2 class="title">L</h2>
<dl>
<dt><span class="strong"><a href="../it/necst/grabnrun/SecureDexClassLoader.html#loadClass(java.lang.String)">loadClass(String)</a></span> - Method in class it.necst.grabnrun.<a href="../it/necst/grabnrun/SecureDexClassLoader.html" title="class in it.necst.grabnrun">SecureDexClassLoader</a></dt>
<dd> </dd>
</dl>
<a href="index-1.html">C</a> <a href="index-2.html">D</a> <a href="index-3.html">I</a> <a href="index-4.html">L</a> <a href="index-5.html">S</a> <a href="index-6.html">W</a> </div>
<!-- ======= START OF BOTTOM NAVBAR ====== -->
<div class="bottomNav"><a name="navbar_bottom">
<!-- -->
</a><a href="#skip-navbar_bottom" title="Skip navigation links"></a><a name="navbar_bottom_firstrow">
<!-- -->
</a>
<ul class="navList" title="Navigation">
<li><a href="../it/necst/grabnrun/package-summary.html">Package</a></li>
<li>Class</li>
<li>Use</li>
<li><a href="../overview-tree.html">Tree</a></li>
<li><a href="../deprecated-list.html">Deprecated</a></li>
<li class="navBarCell1Rev">Index</li>
<li><a href="../help-doc.html">Help</a></li>
</ul>
</div>
<div class="subNav">
<ul class="navList">
<li><a href="index-3.html">Prev Letter</a></li>
<li><a href="index-5.html">Next Letter</a></li>
</ul>
<ul class="navList">
<li><a href="../index.html?index-filesindex-4.html" target="_top">Frames</a></li>
<li><a href="index-4.html" target="_top">No Frames</a></li>
</ul>
<ul class="navList" id="allclasses_navbar_bottom">
<li><a href="../allclasses-noframe.html">All Classes</a></li>
</ul>
<div>
<script type="text/javascript"><!--
allClassesLink = document.getElementById("allclasses_navbar_bottom");
if(window==top) {
allClassesLink.style.display = "block";
}
else {
allClassesLink.style.display = "none";
}
//-->
</script>
</div>
<a name="skip-navbar_bottom">
<!-- -->
</a></div>
<!-- ======== END OF BOTTOM NAVBAR ======= -->
</body>
</html>
================================================
FILE: docs/javaDoc/index-files/index-5.html
================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- NewPage -->
<html lang="en">
<head>
<!-- Generated by javadoc (version 1.7.0_72) on Mon Nov 17 19:29:57 CET 2014 -->
<title>S-Index</title>
<meta name="date" content="2014-11-17">
<link rel="stylesheet" type="text/css" href="../stylesheet.css" title="Style">
</head>
<body>
<script type="text/javascript"><!--
if (location.href.indexOf('is-external=true') == -1) {
parent.document.title="S-Index";
}
//-->
</script>
<noscript>
<div>JavaScript is disabled on your browser.</div>
</noscript>
<!-- ========= START OF TOP NAVBAR ======= -->
<div class="topNav"><a name="navbar_top">
<!-- -->
</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
<!-- -->
</a>
<ul class="navList" title="Navigation">
<li><a href="../it/necst/grabnrun/package-summary.html">Package</a></li>
<li>Class</li>
<li>Use</li>
<li><a href="../overview-tree.html">Tree</a></li>
<li><a href="../deprecated-list.html">Deprecated</a></li>
<li class="navBarCell1Rev">Index</li>
<li><a href="../help-doc.html">Help</a></li>
</ul>
</div>
<div class="subNav">
<ul class="navList">
<li><a href="index-4.html">Prev Letter</a></li>
<li><a href="index-6.html">Next Letter</a></li>
</ul>
<ul class="navList">
<li><a href="../index.html?index-filesindex-5.html" target="_top">Frames</a></li>
<li><a href="index-5.html" target="_top">No Frames</a></li>
</ul>
<ul class="navList" id="allclasses_navbar_top">
<li><a href="../allclasses-noframe.html">All Classes</a></li>
</ul>
<div>
<script type="text/javascript"><!--
allClassesLink = document.getElementById("allclasses_navbar_top");
if(window==top) {
allClassesLink.style.display = "block";
}
else {
allClassesLink.style.display = "none";
}
//-->
</script>
</div>
<a name="skip-navbar_top">
<!-- -->
</a></div>
<!-- ========= END OF TOP NAVBAR ========= -->
<div class="contentContainer"><a href="index-1.html">C</a> <a href="index-2.html">D</a> <a href="index-3.html">I</a> <a href="index-4.html">L</a> <a href="index-5.html">S</a> <a href="index-6.html">W</a> <a name="_S_">
<!-- -->
</a>
<h2 class="title">S</h2>
<dl>
<dt><a href="../it/necst/grabnrun/SecureDexClassLoader.html" title="class in it.necst.grabnrun"><span class="strong">SecureDexClassLoader</span></a> - Class in <a href="../it/necst/grabnrun/package-summary.html">it.necst.grabnrun</a></dt>
<dd>
<div class="block">A class that provides an extension of default <a href="http://d.android.com/reference/dalvik/system/DexClassLoader.html?is-external=true" title="class or interface in dalvik.system"><code>DexClassLoader</code></a>
provided by the Android system and it is used to load classes
from jar and apk container files including a classes.dex entry in a secure way.</div>
</dd>
<dt><a href="../it/necst/grabnrun/SecureLoaderFactory.html" title="class in it.necst.grabnrun"><span class="strong">SecureLoaderFactory</span></a> - Class in <a href="../it/necst/grabnrun/package-summary.html">it.necst.grabnrun</a></dt>
<dd>
<div class="block">A Factory class that generates instances of classes used to
retrieve dynamic code in a secure way at run time.</div>
</dd>
<dt><span class="strong"><a href="../it/necst/grabnrun/SecureLoaderFactory.html#SecureLoaderFactory(ContextWrapper)">SecureLoaderFactory(ContextWrapper)</a></span> - Constructor for class it.necst.grabnrun.<a href="../it/necst/grabnrun/SecureLoaderFactory.html" title="class in it.necst.grabnrun">SecureLoaderFactory</a></dt>
<dd>
<div class="block">Creates a <a href="../it/necst/grabnrun/SecureLoaderFactory.html" title="class in it.necst.grabnrun"><code>SecureLoaderFactory</code></a> used to check and generate instances
from secure dynamic code loader classes.</div>
</dd>
<dt><span class="strong"><a href="../it/necst/grabnrun/SecureLoaderFactory.html#SecureLoaderFactory(ContextWrapper,%20int)">SecureLoaderFactory(ContextWrapper, int)</a></span> - Constructor for class it.necst.grabnrun.<a href="../it/necst/grabnrun/SecureLoaderFactory.html" title="class in it.necst.grabnrun">SecureLoaderFactory</a></dt>
<dd>
<div class="block">This constructor works exactly as the previous one but it also allows to
decide the time interval in days before which a local copy of a remote container, stored in an
application-private directory, will be considered fresh and so acceptable to be cached.</div>
</dd>
</dl>
<a href="index-1.html">C</a> <a href="index-2.html">D</a> <a href="index-3.html">I</a> <a href="index-4.html">L</a> <a href="index-5.html">S</a> <a href="index-6.html">W</a> </div>
<!-- ======= START OF BOTTOM NAVBAR ====== -->
<div class="bottomNav"><a name="navbar_bottom">
<!-- -->
</a><a href="#skip-navbar_bottom" title="Skip navigation links"></a><a name="navbar_bottom_firstrow">
<!-- -->
</a>
<ul class="navList" title="Navigation">
<li><a href="../it/necst/grabnrun/package-summary.html">Package</a></li>
<li>Class</li>
<li>Use</li>
<li><a href="../overview-tree.html">Tree</a></li>
<li><a href="../deprecated-list.html">Deprecated</a></li>
<li class="navBarCell1Rev">Index</li>
<li><a href="../help-doc.html">Help</a></li>
</ul>
</div>
<div class="subNav">
<ul class="navList">
<li><a href="index-4.html">Prev Letter</a></li>
<li><a href="index-6.html">Next Letter</a></li>
</ul>
<ul class="navList">
<li><a href="../index.html?index-filesindex-5.html" target="_top">Frames</a></li>
<li><a href="index-5.html" target="_top">No Frames</a></li>
</ul>
<ul class="navList" id="allclasses_navbar_bottom">
<li><a href="../allclasses-noframe.html">All Classes</a></li>
</ul>
<div>
<script type="text/javascript"><!--
allClassesLink = document.getElementById("allclasses_navbar_bottom");
if(window==top) {
allClassesLink.style.display = "block";
}
else {
allClassesLink.style.display = "none";
}
//-->
</script>
</div>
<a name="skip-navbar_bottom">
<!-- -->
</a></div>
<!-- ======== END OF BOTTOM NAVBAR ======= -->
</body>
</html>
================================================
FILE: docs/javaDoc/index-files/index-6.html
================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- NewPage -->
<html lang="en">
<head>
<!-- Generated by javadoc (version 1.7.0_72) on Mon Nov 17 19:29:57 CET 2014 -->
<title>W-Index</title>
<meta name="date" content="2014-11-17">
<link rel="stylesheet" type="text/css" href="../stylesheet.css" title="Style">
</head>
<body>
<script type="text/javascript"><!--
if (location.href.indexOf('is-external=true') == -1) {
parent.document.title="W-Index";
}
//-->
</script>
<noscript>
<div>JavaScript is disabled on your browser.</div>
</noscript>
<!-- ========= START OF TOP NAVBAR ======= -->
<div class="topNav"><a name="navbar_top">
<!-- -->
</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
<!-- -->
</a>
<ul class="navList" title="Navigation">
<li><a href="../it/necst/grabnrun/package-summary.html">Package</a></li>
<li>Class</li>
<li>Use</li>
<li><a href="../overview-tree.html">Tree</a></li>
<li><a href="../deprecated-list.html">Deprecated</a></li>
<li class="navBarCell1Rev">Index</li>
<li><a href="../help-doc.html">Help</a></li>
</ul>
</div>
<div class="subNav">
<ul class="navList">
<li><a href="index-5.html">Prev Letter</a></li>
<li>Next Letter</li>
</ul>
<ul class="navList">
<li><a href="../index.html?index-filesindex-6.html" target="_top">Frames</a></li>
<li><a href="index-6.html" target="_top">No Frames</a></li>
</ul>
<ul class="navList" id="allclasses_navbar_top">
<li><a href="../allclasses-noframe.html">All Classes</a></li>
</ul>
<div>
<script type="text/javascript"><!--
allClassesLink = document.getElementById("allclasses_navbar_top");
if(window==top) {
allClassesLink.style.display = "block";
}
else {
allClassesLink.style.display = "none";
}
//-->
</script>
</div>
<a name="skip-navbar_top">
<!-- -->
</a></div>
<!-- ========= END OF TOP NAVBAR ========= -->
<div class="contentContainer"><a href="index-1.html">C</a> <a href="index-2.html">D</a> <a href="index-3.html">I</a> <a href="index-4.html">L</a> <a href="index-5.html">S</a> <a href="index-6.html">W</a> <a name="_W_">
<!-- -->
</a>
<h2 class="title">W</h2>
<dl>
<dt><span class="strong"><a href="../it/necst/grabnrun/SecureDexClassLoader.html#wipeOutPrivateAppCachedData(boolean,%20boolean)">wipeOutPrivateAppCachedData(boolean, boolean)</a></span> - Method in class it.necst.grabnrun.<a href="../it/necst/grabnrun/SecureDexClassLoader.html" title="class in it.necst.grabnrun">SecureDexClassLoader</a></dt>
<dd>
<div class="block">Sometimes it may be useful to remove those data that have been cached in
the private application folders (basically for performance reason or for making
<a href="../it/necst/grabnrun/SecureDexClassLoader.html" title="class in it.necst.grabnrun"><code>SecureDexClassLoader</code></a> works also partially offline).</div>
</dd>
</dl>
<a href="index-1.html">C</a> <a href="index-2.html">D</a> <a href="index-3.html">I</a> <a href="index-4.html">L</a> <a href="index-5.html">S</a> <a href="index-6.html">W</a> </div>
<!-- ======= START OF BOTTOM NAVBAR ====== -->
<div class="bottomNav"><a name="navbar_bottom">
<!-- -->
</a><a href="#skip-navbar_bottom" title="Skip navigation links"></a><a name="navbar_bottom_firstrow">
<!-- -->
</a>
<ul class="navList" title="Navigation">
<li><a href="../it/necst/grabnrun/package-summary.html">Package</a></li>
<li>Class</li>
<li>Use</li>
<li><a href="../overview-tree.html">Tree</a></li>
<li><a href="../deprecated-list.html">Deprecated</a></li>
<li class="navBarCell1Rev">Index</li>
<li><a href="../help-doc.html">Help</a></li>
</ul>
</div>
<div class="subNav">
<ul class="navList">
<li><a href="index-5.html">Prev Letter</a></li>
<li>Next Letter</li>
</ul>
<ul class="navList">
<li><a href="../index.html?index-filesindex-6.html" target="_top">Frames</a></li>
<li><a href="index-6.html" target="_top">No Frames</a></li>
</ul>
<ul class="navList" id="allclasses_navbar_bottom">
<li><a href="../allclasses-noframe.html">All Classes</a></li>
</ul>
<div>
<script type="text/javascript"><!--
allClassesLink = document.getElementById("allclasses_navbar_bottom");
if(window==top) {
allClassesLink.style.display = "block";
}
else {
allClassesLink.style.display = "none";
}
//-->
</script>
</div>
<a name="skip-navbar_bottom">
<!-- -->
</a></div>
<!-- ======== END OF BOTTOM NAVBAR ======= -->
</body>
</html>
================================================
FILE: docs/javaDoc/index.html
================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
<!-- NewPage -->
<html lang="en">
<head>
<!-- Generated by javadoc on Mon Nov 17 19:29:57 CET 2014 -->
<title>Generated Documentation (Untitled)</title>
<script type="text/javascript">
targetPage = "" + window.location.search;
if (targetPage != "" && targetPage != "undefined")
targetPage = targetPage.substring(1);
if (targetPage.indexOf(":") != -1 || (targetPage != "" && !validURL(targetPage)))
targetPage = "undefined";
function validURL(url) {
try {
url = decodeURIComponent(url);
}
catch (error) {
return false;
}
var pos = url.indexOf(".html");
if (pos == -1 || pos != url.length - 5)
return false;
var allowNumber = false;
var allowSep = false;
var seenDot = false;
for (var i = 0; i < url.length - 5; i++) {
var ch = url.charAt(i);
if ('a' <= ch && ch <= 'z' ||
'A' <= ch && ch <= 'Z' ||
ch == '$' ||
ch == '_' ||
ch.charCodeAt(0) > 127) {
allowNumber = true;
allowSep = true;
} else if ('0' <= ch && ch <= '9'
|| ch == '-') {
if (!allowNumber)
return false;
} else if (ch == '/' || ch == '.') {
if (!allowSep)
return false;
allowNumber = false;
allowSep = false;
if (ch == '.')
seenDot = true;
if (ch == '/' && seenDot)
return false;
} else {
return false;
}
}
return true;
}
function loadFrames() {
if (targetPage != "" && targetPage != "undefined")
top.classFrame.location = top.targetPage;
}
</script>
</head>
<frameset cols="20%,80%" title="Documentation frame" onload="top.loadFrames()">
<frame src="allclasses-frame.html" name="packageFrame" title="All classes and interfaces (except non-static nested types)">
<frame src="it/necst/grabnrun/package-summary.html" name="classFrame" title="Package, class and interface descriptions" scrolling="yes">
<noframes>
<noscript>
<div>JavaScript is disabled on your browser.</div>
</noscript>
<h2>Frame Alert</h2>
<p>This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. Link to <a href="it/necst/grabnrun/package-summary.html">Non-frame version</a>.</p>
</noframes>
</frameset>
</html>
================================================
FILE: docs/javaDoc/it/necst/grabnrun/SecureDexClassLoader.html
================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- NewPage -->
<html lang="en">
<head>
<!-- Generated by javadoc (version 1.7.0_72) on Mon Nov 17 19:29:57 CET 2014 -->
<title>SecureDexClassLoader</title>
<meta name="date" content="2014-11-17">
<link rel="stylesheet" type="text/css" href="../../../stylesheet.css" title="Style">
</head>
<body>
<script type="text/javascript"><!--
if (location.href.indexOf('is-external=true') == -1) {
parent.document.title="SecureDexClassLoader";
}
//-->
</script>
<noscript>
<div>JavaScript is disabled on your browser.</div>
</noscript>
<!-- ========= START OF TOP NAVBAR ======= -->
<div class="topNav"><a name="navbar_top">
<!-- -->
</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
<!-- -->
</a>
<ul class="navList" title="Navigation">
<li><a href="../../../it/necst/grabnrun/package-summary.html">Package</a></li>
<li class="navBarCell1Rev">Class</li>
<li><a href="class-use/SecureDexClassLoader.html">Use</a></li>
<li><a href="package-tree.html">Tree</a></li>
<li><a href="../../../deprecated-list.html">Deprecated</a></li>
<li><a href="../../../index-files/index-1.html">Index</a></li>
<li><a href="../../../help-doc.html">Help</a></li>
</ul>
</div>
<div class="subNav">
<ul class="navList">
<li>Prev Class</li>
<li><a href="../../../it/necst/grabnrun/SecureLoaderFactory.html" title="class in it.necst.grabnrun"><span class="strong">Next Class</span></a></li>
</ul>
<ul class="navList">
<li><a href="../../../index.html?it/necst/grabnrun/SecureDexClassLoader.html" target="_top">Frames</a></li>
<li><a href="SecureDexClassLoader.html" target="_top">No Frames</a></li>
</ul>
<ul class="navList" id="allclasses_navbar_top">
<li><a href="../../../allclasses-noframe.html">All Classes</a></li>
</ul>
<div>
<script type="text/javascript"><!--
allClassesLink = document.getElementById("allclasses_navbar_top");
if(window==top) {
allClassesLink.style.display = "block";
}
else {
allClassesLink.style.display = "none";
}
//-->
</script>
</div>
<div>
<ul class="subNavList">
<li>Summary: </li>
<li>Nested | </li>
<li>Field | </li>
<li>Constr | </li>
<li><a href="#method_summary">Method</a></li>
</ul>
<ul class="subNavList">
<li>Detail: </li>
<li>Field | </li>
<li>Constr | </li>
<li><a href="#method_detail">Method</a></li>
</ul>
</div>
<a name="skip-navbar_top">
<!-- -->
</a></div>
<!-- ========= END OF TOP NAVBAR ========= -->
<!-- ======== START OF CLASS DATA ======== -->
<div class="header">
<div class="subTitle">it.necst.grabnrun</div>
<h2 title="Class SecureDexClassLoader" class="title">Class SecureDexClassLoader</h2>
</div>
<div class="contentContainer">
<ul class="inheritance">
<li><a href="http://d.android.com/reference/java/lang/Object.html?is-external=true" title="class or interface in java.lang">java.lang.Object</a></li>
<li>
<ul class="inheritance">
<li>it.necst.grabnrun.SecureDexClassLoader</li>
</ul>
</li>
</ul>
<div class="description">
<ul class="blockList">
<li class="blockList">
<hr>
<br>
<pre>public class <span class="strong">SecureDexClassLoader</span>
extends <a href="http://d.android.com/reference/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</a></pre>
<div class="block">A class that provides an extension of default <a href="http://d.android.com/reference/dalvik/system/DexClassLoader.html?is-external=true" title="class or interface in dalvik.system"><code>DexClassLoader</code></a>
provided by the Android system and it is used to load classes
from jar and apk container files including a classes.dex entry in a secure way.
<p>
In order to instantiate this class a call to
<a href="../../../it/necst/grabnrun/SecureLoaderFactory.html#createDexClassLoader(java.lang.String,%20java.lang.String,%20java.lang.ClassLoader,%20java.util.Map)"><code>SecureLoaderFactory.createDexClassLoader(String, String, ClassLoader, Map)</code></a>
must be performed.
<p>
<a href="../../../it/necst/grabnrun/SecureDexClassLoader.html" title="class in it.necst.grabnrun"><code>SecureDexClassLoader</code></a> ensures integrity of loaded external remote
classes by comparing them with the developer certificate, which
is retrieved either by a provided associative map between package names
and certificate remote URL or by simply reverting the
first two words of the package name of the loaded class and then
by adding each following word in the same order and separated by
a slash "/".
<p>
Package name reversion example:<br>
Class name = it.necst.grabnrun.example.TestClassImpl<br>
Constructed URL = https://necst.it/grabnrun/example<br>
Final certificate location = https://necst.it/grabnrun/example/certificate.pem<br>
<p>
A request is pointed to the final certificate location and if
the file is found, it is imported in the local private
application directory.
<p>
Please note that in the current implementation certificates obtained
by reverting package name must have been saved at the described
location as "certificate.pem". Moreover all the certificates must
fit requirements of a standard <a href="http://d.android.com/reference/java/security/cert/X509Certificate.html?is-external=true" title="class or interface in java.security.cert"><code>X509Certificate</code></a>,
they must be valid in the current time frame and of course they must have been
used to sign the jar or apk, which contains the classes to be loaded.
<p>
If any of these previous requirements is violated no class is loaded
and this class returns without executing any class loading operation.</div>
<dl><dt><span class="strong">Author:</span></dt>
<dd>Luca Falsina</dd></dl>
</li>
</ul>
</div>
<div class="summary">
<ul class="blockList">
<li class="blockList">
<!-- ========== METHOD SUMMARY =========== -->
<ul class="blockList">
<li class="blockList"><a name="method_summary">
<!-- -->
</a>
<h3>Method Summary</h3>
<table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Method Summary table, listing methods, and an explanation">
<caption><span>Methods</span><span class="tabEnd"> </span></caption>
<tr>
<th class="colFirst" scope="col">Modifier and Type</th>
<th class="colLast" scope="col">Method and Description</th>
</tr>
<tr class="altColor">
<td class="colFirst"><code><a href="http://d.android.com/reference/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</a><?></code></td>
<td class="colLast"><code><strong><a href="../../../it/necst/grabnrun/SecureDexClassLoader.html#loadClass(java.lang.String)">loadClass</a></strong>(<a href="http://d.android.com/reference/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> className)</code> </td>
</tr>
<tr class="rowColor">
<td class="colFirst"><code>void</code></td>
<td class="colLast"><code><strong><a href="../../../it/necst/grabnrun/SecureDexClassLoader.html#wipeOutPrivateAppCachedData(boolean,%20boolean)">wipeOutPrivateAppCachedData</a></strong>(boolean containerPrivateFolder,
boolean certificatePrivateFolder)</code>
<div class="block">Sometimes it may be useful to remove those data that have been cached in
the private application folders (basically for performance reason or for making
<a href="../../../it/necst/grabnrun/SecureDexClassLoader.html" title="class in it.necst.grabnrun"><code>SecureDexClassLoader</code></a> works also partially offline).</div>
</td>
</tr>
</table>
<ul class="blockList">
<li class="blockList"><a name="methods_inherited_from_class_java.lang.Object">
<!-- -->
</a>
<h3>Methods inherited from class java.lang.<a href="http://d.android.com/reference/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</a></h3>
<code><a href="http://d.android.com/reference/java/lang/Object.html?is-external=true#equals(java.lang.Object)" title="class or interface in java.lang">equals</a>, <a href="http://d.android.com/reference/java/lang/Object.html?is-external=true#getClass()" title="class or interface in java.lang">getClass</a>, <a href="http://d.android.com/reference/java/lang/Object.html?is-external=true#hashCode()" title="class or interface in java.lang">hashCode</a>, <a href="http://d.android.com/reference/java/lang/Object.html?is-external=true#notify()" title="class or interface in java.lang">notify</a>, <a href="http://d.android.com/reference/java/lang/Object.html?is-external=true#notifyAll()" title="class or interface in java.lang">notifyAll</a>, <a href="http://d.android.com/reference/java/lang/Object.html?is-external=true#toString()" title="class or interface in java.lang">toString</a>, <a href="http://d.android.com/reference/java/lang/Object.html?is-external=true#wait()" title="class or interface in java.lang">wait</a>, <a href="http://d.android.com/reference/java/lang/Object.html?is-external=true#wait(long)" title="class or interface in java.lang">wait</a>, <a href="http://d.android.com/reference/java/lang/Object.html?is-external=true#wait(long,%20int)" title="class or interface in java.lang">wait</a></code></li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
<div class="details">
<ul class="blockList">
<li class="blockList">
<!-- ============ METHOD DETAIL ========== -->
<ul class="blockList">
<li class="blockList"><a name="method_detail">
<!-- -->
</a>
<h3>Method Detail</h3>
<a name="loadClass(java.lang.String)">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>loadClass</h4>
<pre>public <a href="http://d.android.com/reference/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</a><?> loadClass(<a href="http://d.android.com/reference/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> className)
throws <a href="http://d.android.com/reference/java/lang/ClassNotFoundException.html?is-external=true" title="class or interface in java.lang">ClassNotFoundException</a></pre>
<dl><dt><span class="strong">Parameters:</span></dt><dd><code>className</code> - the full class name to load. It must fit the form "package name + . + class name".
A valid full class name is for example "it.polimi.myapplication.classA"; while "classA" is not
enough since it misses the package name and so <a href="../../../it/necst/grabnrun/SecureDexClassLoader.html" title="class in it.necst.grabnrun"><code>SecureDexClassLoader</code></a> will not find any
class to load.</dd>
<dt><span class="strong">Returns:</span></dt><dd>Either a class that needs to be casted at runtime accordingly to className if the verification
process succeeds or a <code>null</code> pointer in case that at least one of the security
constraints for secure dynamic class loading is violated.</dd>
<dt><span class="strong">Throws:</span></dt>
<dd><code><a href="http://d.android.com/reference/java/lang/ClassNotFoundException.html?is-external=true" title="class or interface in java.lang">ClassNotFoundException</a></code> - this exception is raised whenever no security constraint is violated but still the target class is
not found in any of the available containers used to instantiate this <a href="../../../it/necst/grabnrun/SecureDexClassLoader.html" title="class in it.necst.grabnrun"><code>SecureDexClassLoader</code></a> object.</dd><dt><span class="strong">See Also:</span></dt><dd><a href="http://d.android.com/reference/java/lang/ClassLoader.html?is-external=true#loadClass(java.lang.String)" title="class or interface in java.lang"><code>ClassLoader.loadClass(java.lang.String)</code></a></dd></dl>
</li>
</ul>
<a name="wipeOutPrivateAppCachedData(boolean, boolean)">
<!-- -->
</a>
<ul class="blockListLast">
<li class="blockList">
<h4>wipeOutPrivateAppCachedData</h4>
<pre>public void wipeOutPrivateAppCachedData(boolean containerPrivateFolder,
boolean certificatePrivateFolder)</pre>
<div class="block">Sometimes it may be useful to remove those data that have been cached in
the private application folders (basically for performance reason or for making
<a href="../../../it/necst/grabnrun/SecureDexClassLoader.html" title="class in it.necst.grabnrun"><code>SecureDexClassLoader</code></a> works also partially offline). A call to this method solves the issue.
<p>
Please notice that a call to this method with both the parameters set to false
has no effect.
<p>
In any of the other cases the content of the related folder(s) will be erased and
since some of the data may have been used by <a href="../../../it/necst/grabnrun/SecureDexClassLoader.html" title="class in it.necst.grabnrun"><code>SecureDexClassLoader</code></a> instances, it is
required to the caller to create a new <a href="../../../it/necst/grabnrun/SecureDexClassLoader.html" title="class in it.necst.grabnrun"><code>SecureDexClassLoader</code></a> object through
<a href="../../../it/necst/grabnrun/SecureLoaderFactory.html" title="class in it.necst.grabnrun"><code>SecureLoaderFactory</code></a> since the already present object is going to be disabled
from loading classes dynamically.</div>
<dl><dt><span class="strong">Parameters:</span></dt><dd><code>containerPrivateFolder</code> - if the private folder where jar and apk containers downloaded from remote URL or imported from local storage needs to be wiped out.</dd><dd><code>certificatePrivateFolder</code> - if the private folder containing certificates needs to be wiped out.</dd></dl>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
</div>
<!-- ========= END OF CLASS DATA ========= -->
<!-- ======= START OF BOTTOM NAVBAR ====== -->
<div class="bottomNav"><a name="navbar_bottom">
<!-- -->
</a><a href="#skip-navbar_bottom" title="Skip navigation links"></a><a name="navbar_bottom_firstrow">
<!-- -->
</a>
<ul class="navList" title="Navigation">
<li><a href="../../../it/necst/grabnrun/package-summary.html">Package</a></li>
<li class="navBarCell1Rev">Class</li>
<li><a href="class-use/SecureDexClassLoader.html">Use</a></li>
<li><a href="package-tree.html">Tree</a></li>
<li><a href="../../../deprecated-list.html">Deprecated</a></li>
<li><a href="../../../index-files/index-1.html">Index</a></li>
<li><a href="../../../help-doc.html">Help</a></li>
</ul>
</div>
<div class="subNav">
<ul class="navList">
<li>Prev Class</li>
<li><a href="../../../it/necst/grabnrun/SecureLoaderFactory.html" title="class in it.necst.grabnrun"><span class="strong">Next Class</span></a></li>
</ul>
<ul class="navList">
<li><a href="../../../index.html?it/necst/grabnrun/SecureDexClassLoader.html" target="_top">Frames</a></li>
<li><a href="SecureDexClassLoader.html" target="_top">No Frames</a></li>
</ul>
<ul class="navList" id="allclasses_navbar_bottom">
<li><a href="../../../allclasses-noframe.html">All Classes</a></li>
</ul>
<div>
<script type="text/javascript"><!--
allClassesLink = document.getElementById("allclasses_navbar_bottom");
if(window==top) {
allClassesLink.style.display = "block";
}
else {
allClassesLink.style.display = "none";
}
//-->
</script>
</div>
<div>
<ul class="subNavList">
<li>Summary: </li>
<li>Nested | </li>
<li>Field | </li>
<li>Constr | </li>
<li><a href="#method_summary">Method</a></li>
</ul>
<ul class="subNavList">
<li>Detail: </li>
<li>Field | </li>
<li>Constr | </li>
<li><a href="#method_detail">Method</a></li>
</ul>
</div>
<a name="skip-navbar_bottom">
<!-- -->
</a></div>
<!-- ======== END OF BOTTOM NAVBAR ======= -->
</body>
</html>
================================================
FILE: docs/javaDoc/it/necst/grabnrun/SecureLoaderFactory.html
================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- NewPage -->
<html lang="en">
<head>
<!-- Generated by javadoc (version 1.7.0_72) on Mon Nov 17 19:29:57 CET 2014 -->
<title>SecureLoaderFactory</title>
<meta name="date" content="2014-11-17">
<link rel="stylesheet" type="text/css" href="../../../stylesheet.css" title="Style">
</head>
<body>
<script type="text/javascript"><!--
if (location.href.indexOf('is-external=true') == -1) {
parent.document.title="SecureLoaderFactory";
}
//-->
</script>
<noscript>
<div>JavaScript is disabled on your browser.</div>
</noscript>
<!-- ========= START OF TOP NAVBAR ======= -->
<div class="topNav"><a name="navbar_top">
<!-- -->
</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
<!-- -->
</a>
<ul class="navList" title="Navigation">
<li><a href="../../../it/necst/grabnrun/package-summary.html">Package</a></li>
<li class="navBarCell1Rev">Class</li>
<li><a href="class-use/SecureLoaderFactory.html">Use</a></li>
<li><a href="package-tree.html">Tree</a></li>
<li><a href="../../../deprecated-list.html">Deprecated</a></li>
<li><a href="../../../index-files/index-1.html">Index</a></li>
<li><a href="../../../help-doc.html">Help</a></li>
</ul>
</div>
<div class="subNav">
<ul class="navList">
<li><a href="../../../it/necst/grabnrun/SecureDexClassLoader.html" title="class in it.necst.grabnrun"><span class="strong">Prev Class</span></a></li>
<li>Next Class</li>
</ul>
<ul class="navList">
<li><a href="../../../index.html?it/necst/grabnrun/SecureLoaderFactory.html" target="_top">Frames</a></li>
<li><a href="SecureLoaderFactory.html" target="_top">No Frames</a></li>
</ul>
<ul class="navList" id="allclasses_navbar_top">
<li><a href="../../../allclasses-noframe.html">All Classes</a></li>
</ul>
<div>
<script type="text/javascript"><!--
allClassesLink = document.getElementById("allclasses_navbar_top");
if(window==top) {
allClassesLink.style.display = "block";
}
else {
allClassesLink.style.display = "none";
}
//-->
</script>
</div>
<div>
<ul class="subNavList">
<li>Summary: </li>
<li>Nested | </li>
<li><a href="#field_summary">Field</a> | </li>
<li><a href="#constructor_summary">Constr</a> | </li>
<li><a href="#method_summary">Method</a></li>
</ul>
<ul class="subNavList">
<li>Detail: </li>
<li><a href="#field_detail">Field</a> | </li>
<li><a href="#constructor_detail">Constr</a> | </li>
<li><a href="#method_detail">Method</a></li>
</ul>
</div>
<a name="skip-navbar_top">
<!-- -->
</a></div>
<!-- ========= END OF TOP NAVBAR ========= -->
<!-- ======== START OF CLASS DATA ======== -->
<div class="header">
<div class="subTitle">it.necst.grabnrun</div>
<h2 title="Class SecureLoaderFactory" class="title">Class SecureLoaderFactory</h2>
</div>
<div class="contentContainer">
<ul class="inheritance">
<li><a href="http://d.android.com/reference/java/lang/Object.html?is-external=true" title="class or interface in java.lang">java.lang.Object</a></li>
<li>
<ul class="inheritance">
<li>it.necst.grabnrun.SecureLoaderFactory</li>
</ul>
</li>
</ul>
<div class="description">
<ul class="blockList">
<li class="blockList">
<hr>
<br>
<pre>public class <span class="strong">SecureLoaderFactory</span>
extends <a href="http://d.android.com/reference/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</a></pre>
<div class="block">A Factory class that generates instances of classes used to
retrieve dynamic code in a secure way at run time.</div>
<dl><dt><span class="strong">Author:</span></dt>
<dd>Luca Falsina</dd></dl>
</li>
</ul>
</div>
<div class="summary">
<ul class="blockList">
<li class="blockList">
<!-- =========== FIELD SUMMARY =========== -->
<ul class="blockList">
<li class="blockList"><a name="field_summary">
<!-- -->
</a>
<h3>Field Summary</h3>
<table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Field Summary table, listing fields, and an explanation">
<caption><span>Fields</span><span class="tabEnd"> </span></caption>
<tr>
<th class="colFirst" scope="col">Modifier and Type</th>
<th class="colLast" scope="col">Field and Description</th>
</tr>
<tr class="altColor">
<td class="colFirst"><code>static int</code></td>
<td class="colLast"><code><strong><a href="../../../it/necst/grabnrun/SecureLoaderFactory.html#DEFAULT_DAYS_BEFORE_CONTAINER_EXPIRACY">DEFAULT_DAYS_BEFORE_CONTAINER_EXPIRACY</a></strong></code>
<div class="block">When a remote container URL is encountered, this field specifies the default time interval,
expressed in days, before which a local copy of a remote container, stored in an
application-private directory, will be considered fresh and so acceptable to be cached.</div>
</td>
</tr>
</table>
</li>
</ul>
<!-- ======== CONSTRUCTOR SUMMARY ======== -->
<ul class="blockList">
<li class="blockList"><a name="constructor_summary">
<!-- -->
</a>
<h3>Constructor Summary</h3>
<table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Constructor Summary table, listing constructors, and an explanation">
<caption><span>Constructors</span><span class="tabEnd"> </span></caption>
<tr>
<th class="colOne" scope="col">Constructor and Description</th>
</tr>
<tr class="altColor">
<td class="colOne"><code><strong><a href="../../../it/necst/grabnrun/SecureLoaderFactory.html#SecureLoaderFactory(ContextWrapper)">SecureLoaderFactory</a></strong>(ContextWrapper parentContextWrapper)</code>
<div class="block">Creates a <a href="../../../it/necst/grabnrun/SecureLoaderFactory.html" title="class in it.necst.grabnrun"><code>SecureLoaderFactory</code></a> used to check and generate instances
from secure dynamic code loader classes.</div>
</td>
</tr>
<tr class="rowColor">
<td class="colOne"><code><strong><a href="../../../it/necst/grabnrun/SecureLoaderFactory.html#SecureLoaderFactory(ContextWrapper,%20int)">SecureLoaderFactory</a></strong>(ContextWrapper parentContextWrapper,
int daysBeforeContainerCacheExpiration)</code>
<div class="block">This constructor works exactly as the previous one but it also allows to
decide the time interval in days before which a local copy of a remote container, stored in an
application-private directory, will be considered fresh and so acceptable to be cached.</div>
</td>
</tr>
</table>
</li>
</ul>
<!-- ========== METHOD SUMMARY =========== -->
<ul class="blockList">
<li class="blockList"><a name="method_summary">
<!-- -->
</a>
<h3>Method Summary</h3>
<table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Method Summary table, listing methods, and an explanation">
<caption><span>Methods</span><span class="tabEnd"> </span></caption>
<tr>
<th class="colFirst" scope="col">Modifier and Type</th>
<th class="colLast" scope="col">Method and Description</th>
</tr>
<tr class="altColor">
<td class="colFirst"><code><a href="../../../it/necst/grabnrun/SecureDexClassLoader.html" title="class in it.necst.grabnrun">SecureDexClassLoader</a></code></td>
<td class="colLast"><code><strong><a href="../../../it/necst/grabnrun/SecureLoaderFactory.html#createDexClassLoader(java.lang.String,%20java.lang.String,%20java.lang.ClassLoader,%20java.util.Map)">createDexClassLoader</a></strong>(<a href="http://d.android.com/reference/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> dexPath,
<a href="http://d.android.com/reference/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> libraryPath,
<a href="http://d.android.com/reference/java/lang/ClassLoader.html?is-external=true" title="class or interface in java.lang">ClassLoader</a> parent,
<a href="http://d.android.com/reference/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</a><<a href="http://d.android.com/reference/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>,<a href="http://d.android.com/reference/java/net/URL.html?is-external=true" title="class or interface in java.net">URL</a>> packageNameToCertificateMap)</code>
<div class="block">Creates a <a href="../../../it/necst/grabnrun/SecureDexClassLoader.html" title="class in it.necst.grabnrun"><code>SecureDexClassLoader</code></a> that finds interpreted and native code in a set of
provided locations (either local or remote via HTTP or HTTPS) in dexPath.</div>
</td>
</tr>
<tr class="rowColor">
<td class="colFirst"><code><a href="../../../it/necst/grabnrun/SecureDexClassLoader.html" title="class in it.necst.grabnrun">SecureDexClassLoader</a></code></td>
<td class="colLast"><code><strong><a href="../../../it/necst/grabnrun/SecureLoaderFactory.html#createDexClassLoader(java.lang.String,%20java.lang.String,%20java.lang.ClassLoader,%20java.util.Map,%20boolean)">createDexClassLoader</a></strong>(<a href="http://d.android.com/reference/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> dexPath,
<a href="http://d.android.com/reference/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> libraryPath,
<a href="http://d.android.com/reference/java/lang/ClassLoader.html?is-external=true" title="class or interface in java.lang">ClassLoader</a> parent,
<a href="http://d.android.com/reference/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</a><<a href="http://d.android.com/reference/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>,<a href="http://d.android.com/reference/java/net/URL.html?is-external=true" title="class or interface in java.net">URL</a>> packageNameToCertificateMap,
boolean performLazyEvaluation)</code>
<div class="block">This method returns a <a href="../../../it/necst/grabnrun/SecureDexClassLoader.html" title="class in it.necst.grabnrun"><code>SecureDexClassLoader</code></a> instance in the same way as it is
explained in the <a href="../../../it/necst/grabnrun/SecureLoaderFactory.html#createDexClassLoader(java.lang.String,%20java.lang.String,%20java.lang.ClassLoader,%20java.util.Map)"><code>createDexClassLoader(String, String, ClassLoader, Map)</code></a>.</div>
</td>
</tr>
</table>
<ul class="blockList">
<li class="blockList"><a name="methods_inherited_from_class_java.lang.Object">
<!-- -->
</a>
<h3>Methods inherited from class java.lang.<a href="http://d.android.com/reference/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</a></h3>
<code><a href="http://d.android.com/reference/java/lang/Object.html?is-external=true#equals(java.lang.Object)" title="class or interface in java.lang">equals</a>, <a href="http://d.android.com/reference/java/lang/Object.html?is-external=true#getClass()" title="class or interface in java.lang">getClass</a>, <a href="http://d.android.com/reference/java/lang/Object.html?is-external=true#hashCode()" title="class or interface in java.lang">hashCode</a>, <a href="http://d.android.com/reference/java/lang/Object.html?is-external=true#notify()" title="class or interface in java.lang">notify</a>, <a href="http://d.android.com/reference/java/lang/Object.html?is-external=true#notifyAll()" title="class or interface in java.lang">notifyAll</a>, <a href="http://d.android.com/reference/java/lang/Object.html?is-external=true#toString()" title="class or interface in java.lang">toString</a>, <a href="http://d.android.com/reference/java/lang/Object.html?is-external=true#wait()" title="class or interface in java.lang">wait</a>, <a href="http://d.android.com/reference/java/lang/Object.html?is-external=true#wait(long)" title="class or interface in java.lang">wait</a>, <a href="http://d.android.com/reference/java/lang/Object.html?is-external=true#wait(long,%20int)" title="class or interface in java.lang">wait</a></code></li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
<div class="details">
<ul class="blockList">
<li class="blockList">
<!-- ============ FIELD DETAIL =========== -->
<ul class="blockList">
<li class="blockList"><a name="field_detail">
<!-- -->
</a>
<h3>Field Detail</h3>
<a name="DEFAULT_DAYS_BEFORE_CONTAINER_EXPIRACY">
<!-- -->
</a>
<ul class="blockListLast">
<li class="blockList">
<h4>DEFAULT_DAYS_BEFORE_CONTAINER_EXPIRACY</h4>
<pre>public static final int DEFAULT_DAYS_BEFORE_CONTAINER_EXPIRACY</pre>
<div class="block">When a remote container URL is encountered, this field specifies the default time interval,
expressed in days, before which a local copy of a remote container, stored in an
application-private directory, will be considered fresh and so acceptable to be cached.
<p>
On the other hand, all of those containers, whose life time is greater than this
field value, will be immediately erased from the device storage in stead of being cached.
<p>
You can change this duration by generating the <a href="../../../it/necst/grabnrun/SecureLoaderFactory.html" title="class in it.necst.grabnrun"><code>SecureLoaderFactory</code></a> instance
with <code>SecureLoaderFactory#SecureLoaderFactory(android.content.ContextWrapper, int)</code>.</div>
<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../constant-values.html#it.necst.grabnrun.SecureLoaderFactory.DEFAULT_DAYS_BEFORE_CONTAINER_EXPIRACY">Constant Field Values</a></dd></dl>
</li>
</ul>
</li>
</ul>
<!-- ========= CONSTRUCTOR DETAIL ======== -->
<ul class="blockList">
<li class="blockList"><a name="constructor_detail">
<!-- -->
</a>
<h3>Constructor Detail</h3>
<a name="SecureLoaderFactory(ContextWrapper)">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>SecureLoaderFactory</h4>
<pre>public SecureLoaderFactory(ContextWrapper parentContextWrapper)</pre>
<div class="block">Creates a <a href="../../../it/necst/grabnrun/SecureLoaderFactory.html" title="class in it.necst.grabnrun"><code>SecureLoaderFactory</code></a> used to check and generate instances
from secure dynamic code loader classes.
<p>
It requires a <a href="http://d.android.com/reference/android/content/ContextWrapper.html?is-external=true" title="class or interface in android.content"><code>ContextWrapper</code></a> (i.e. the launching activity) which
should be used to manage and retrieve internal directories
of the application.</div>
<dl><dt><span class="strong">Parameters:</span></dt><dd><code>parentContextWrapper</code> - The content wrapper coming from the launching Activity.</dd></dl>
</li>
</ul>
<a name="SecureLoaderFactory(ContextWrapper, int)">
<!-- -->
</a>
<ul class="blockListLast">
<li class="blockList">
<h4>SecureLoaderFactory</h4>
<pre>public SecureLoaderFactory(ContextWrapper parentContextWrapper,
int daysBeforeContainerCacheExpiration)</pre>
<div class="block">This constructor works exactly as the previous one but it also allows to
decide the time interval in days before which a local copy of a remote container, stored in an
application-private directory, will be considered fresh and so acceptable to be cached.
<p>
If a negative value is provided for the second parameter, <a href="../../../it/necst/grabnrun/SecureLoaderFactory.html" title="class in it.necst.grabnrun"><code>SecureLoaderFactory</code></a> will be
instantiated with the time interval in days equal to <a href="../../../it/necst/grabnrun/SecureLoaderFactory.html#DEFAULT_DAYS_BEFORE_CONTAINER_EXPIRACY"><code>DEFAULT_DAYS_BEFORE_CONTAINER_EXPIRACY</code></a>.</div>
<dl><dt><span class="strong">Parameters:</span></dt><dd><code>parentContextWrapper</code> - The content wrapper coming from the launching Activity.</dd><dd><code>daysBeforeContainerCacheExpiration</code> - The non negative value of days for which a local copy of a remote container imported into
an application private folder is considered fresh and so acceptable to be cached.</dd></dl>
</li>
</ul>
</li>
</ul>
<!-- ============ METHOD DETAIL ========== -->
<ul class="blockList">
<li class="blockList"><a name="method_detail">
<!-- -->
</a>
<h3>Method Detail</h3>
<a name="createDexClassLoader(java.lang.String, java.lang.String, java.lang.ClassLoader, java.util.Map)">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>createDexClassLoader</h4>
<pre>public <a href="../../../it/necst/grabnrun/SecureDexClassLoader.html" title="class in it.necst.grabnrun">SecureDexClassLoader</a> createDexClassLoader(<a href="http://d.android.com/reference/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> dexPath,
<a href="http://d.android.com/reference/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> libraryPath,
<a href="http://d.android.com/reference/java/lang/ClassLoader.html?is-external=true" title="class or interface in java.lang">ClassLoader</a> parent,
<a href="http://d.android.com/reference/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</a><<a href="http://d.android.com/reference/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>,<a href="http://d.android.com/reference/java/net/URL.html?is-external=true" title="class or interface in java.net">URL</a>> packageNameToCertificateMap)</pre>
<div class="block">Creates a <a href="../../../it/necst/grabnrun/SecureDexClassLoader.html" title="class in it.necst.grabnrun"><code>SecureDexClassLoader</code></a> that finds interpreted and native code in a set of
provided locations (either local or remote via HTTP or HTTPS) in dexPath.
Interpreted classes are found in a set of DEX files contained in Jar or Apk files and
stored into an application-private, writable directory.
<p>
Before executing one of these classes the signature of the target class is
verified against the certificate associated with its package name.
Certificates location are provided by filling appropriately packageNameToCertificateMap;
each package name must be linked with the remote location of the certificate that
should be used to validate all the classes of that package. It's important
that each one of these locations uses HTTPS as its protocol; otherwise this
choice will be enforced!
If a class package name do not match any of the provided entries in the map,
certificate location will be constructed by simply reverting package name and
transforming it into a web-based URL using HTTPS.
<p>
Note that this method returns <code>null</code> if no matching Jar or Apk file is found at the
provided dexPath parameter; otherwise a <a href="../../../it/necst/grabnrun/SecureDexClassLoader.html" title="class in it.necst.grabnrun"><code>SecureDexClassLoader</code></a> instance is returned.
<p>
Dynamic class loading with the returned <a href="../../../it/necst/grabnrun/SecureDexClassLoader.html" title="class in it.necst.grabnrun"><code>SecureDexClassLoader</code></a> will fail whether
at least one of these conditions is not accomplished: target class is not found in dexPath
or is in a missing remote container (i.e. Internet connectivity is not present), missing or
invalid (i.e. expired) certificate is associated with the package name of the target class,
target class signature check fails against the associated certificate.</div>
<dl><dt><span class="strong">Parameters:</span></dt><dd><code>dexPath</code> - the list of jar/apk files containing classes and resources; these paths could
be either local URLs pointing to a location in the device or URLs that links
to a resource stored in the web via HTTP/HTTPS. In the latter case, if Internet
connectivity is available, the resource will be imported in a private-application
directory before being used.</dd><dd><code>libraryPath</code> - the list of directories containing native libraries; it may be <code>null</code>.</dd><dd><code>parent</code> - the parent class loader.</dd><dd><code>packageNameToCertificateMap</code> - a map that couples each package name to a URL which contains the certificate
that must be used to validate all the classes that belong to that package
before launching them at run time. Please notice that any URL in this map
using HTTP protocol will be enforced to use HTTPS in stead.</dd>
<dt><span class="strong">Returns:</span></dt><dd>a <a href="../../../it/necst/grabnrun/SecureDexClassLoader.html" title="class in it.necst.grabnrun"><code>SecureDexClassLoader</code></a> object which can be used to load dynamic code securely and
uses a Eager strategy for container signature verification.</dd></dl>
</li>
</ul>
<a name="createDexClassLoader(java.lang.String, java.lang.String, java.lang.ClassLoader, java.util.Map, boolean)">
<!-- -->
</a>
<ul class="blockListLast">
<li class="blockList">
<h4>createDexClassLoader</h4>
<pre>public <a href="../../../it/necst/grabnrun/SecureDexClassLoader.html" title="class in it.necst.grabnrun">SecureDexClassLoader</a> createDexClassLoader(<a href="http://d.android.com/reference/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> dexPath,
<a href="http://d.android.com/reference/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> libraryPath,
<a href="http://d.android.com/reference/java/lang/ClassLoader.html?is-external=true" title="class or interface in java.lang">ClassLoader</a> parent,
<a href="http://d.android.com/reference/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</a><<a href="http://d.android.com/reference/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>,<a href="http://d.android.com/reference/java/net/URL.html?is-external=true" title="class or interface in java.net">URL</a>> packageNameToCertificateMap,
boolean performLazyEvaluation)</pre>
<div class="block">This method returns a <a href="../../../it/necst/grabnrun/SecureDexClassLoader.html" title="class in it.necst.grabnrun"><code>SecureDexClassLoader</code></a> instance in the same way as it is
explained in the <a href="../../../it/necst/grabnrun/SecureLoaderFactory.html#createDexClassLoader(java.lang.String,%20java.lang.String,%20java.lang.ClassLoader,%20java.util.Map)"><code>createDexClassLoader(String, String, ClassLoader, Map)</code></a>. In addition it is
possible to specify the mode in which the signature verification process will be carried.
<p>
In particular by setting the performLazyEvaluation parameter on true,
a lazy verification process will be chosen. This means that the signature
of the single container associated with the target class will be evaluated
only when <a href="../../../it/necst/grabnrun/SecureDexClassLoader.html#loadClass(java.lang.String)"><code>SecureDexClassLoader.loadClass(String)</code></a> will be invoked .
If this check succeeds the target class will be loaded.
<p>
On the other hand, by setting the parameter performLazyEvaluation to false
an eager evaluation will be carried out. This means that before returning this
object, the signature verification procedure will be carried out on all the
provided containers in a CONCURRENT way and all of those that do not succeed in the process will
be blocked from loading their classes in the following loadClass() method calls.
<p>
The use of one mode in stead of the other is merely a performance-related choice.
If you do not care that much about it, just invoke
<a href="../../../it/necst/grabnrun/SecureLoaderFactory.html#createDexClassLoader(java.lang.String,%20java.lang.String,%20java.lang.ClassLoader,%20java.util.Map)"><code>createDexClassLoader(String, String, ClassLoader, Map)</code></a>
which does not require to provide the performLazyEvaluation
parameter and it will perform an Eager evaluation. Otherwise as a general guideline,
prefer the lazy mode whenever you think that you won't need to load classes
from all the provided containers.</div>
<dl><dt><span class="strong">Parameters:</span></dt><dd><code>dexPath</code> - the list of jar/apk files containing classes and resources; these paths could
be either local URLs pointing to a location in the device or URLs that links
to a resource stored in the web via HTTP/HTTPS. In the latter case, if Internet
connectivity is available, the resource will be imported in a private-application
directory before being used.</dd><dd><code>libraryPath</code> - the list of directories containing native libraries; it may be <code>null</code>.</dd><dd><code>parent</code> - the parent class loader.</dd><dd><code>packageNameToCertificateMap</code> - a map that couples each package name to a URL which contains the certificate
that must be used to validate all the classes that belong to that package
before launching them at run time. Please notice that any URL in this map
using HTTP protocol will be enforced to use HTTPS in stead.</dd><dd><code>performLazyEvaluation</code> - the mode in which the verification will be handled. True for lazy verification;
false for the eager one.</dd>
<dt><span class="strong">Returns:</span></dt><dd>a <a href="../../../it/necst/grabnrun/SecureDexClassLoader.html" title="class in it.necst.grabnrun"><code>SecureDexClassLoader</code></a> object which can be used to load dynamic code securely and
uses a either Lazy or an Eager strategy for container signature verification depending
on the last parameter provided to this constructor.</dd></dl>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
</div>
<!-- ========= END OF CLASS DATA ========= -->
<!-- ======= START OF BOTTOM NAVBAR ====== -->
<div class="bottomNav"><a name="navbar_bottom">
<!-- -->
</a><a href="#skip-navbar_bottom" title="Skip navigation links"></a><a name="navbar_bottom_firstrow">
<!-- -->
</a>
<ul class="navList" title="Navigation">
<li><a href="../../../it/necst/grabnrun/package-summary.html">Package</a></li>
<li class="navBarCell1Rev">Class</li>
<li><a href="class-use/SecureLoaderFactory.html">Use</a></li>
<li><a href="package-tree.html">Tree</a></li>
<li><a href="../../../deprecated-list.html">Deprecated</a></li>
<li><a href="../../../index-files/index-1.html">Index</a></li>
<li><a href="../../../help-doc.html">Help</a></li>
</ul>
</div>
<div class="subNav">
<ul class="navList">
<li><a href="../../../it/necst/grabnrun/SecureDexClassLoader.html" title="class in it.necst.grabnrun"><span class="strong">Prev Class</span></a></li>
<li>Next Class</li>
</ul>
<ul class="navList">
<li><a href="../../../index.html?it/necst/grabnrun/SecureLoaderFactory.html" target="_top">Frames</a></li>
<li><a href="SecureLoaderFactory.html" target="_top">No Frames</a></li>
</ul>
<ul class="navList" id="allclasses_navbar_bottom">
<li><a href="../../../allclasses-noframe.html">All Classes</a></li>
</ul>
<div>
<script type="text/javascript"><!--
allClassesLink = document.getElementById("allclasses_navbar_bottom");
if(window==top) {
allClassesLink.style.display = "block";
}
else {
allClassesLink.style.display = "none";
}
//-->
</script>
</div>
<div>
<ul class="subNavList">
<li>Summary: </li>
<li>Nested | </li>
<li><a href="#field_summary">Field</a> | </li>
<li><a href="#constructor_summary">Constr</a> | </li>
<li><a href="#method_summary">Method</a></li>
</ul>
<ul class="subNavList">
<li>Detail: </li>
<li><a href="#field_detail">Field</a> | </li>
<li><a href="#constructor_detail">Constr</a> | </li>
<li><a href="#method_detail">Method</a></li>
</ul>
</div>
<a name="skip-navbar_bottom">
<!-- -->
</a></div>
<!-- ======== END OF BOTTOM NAVBAR ======= -->
</body>
</html>
================================================
FILE: docs/javaDoc/it/necst/grabnrun/class-use/SecureDexClassLoader.html
================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- NewPage -->
<html lang="en">
<head>
<!-- Generated by javadoc (version 1.7.0_72) on Mon Nov 17 19:29:57 CET 2014 -->
<title>Uses of Class it.necst.grabnrun.SecureDexClassLoader</title>
<meta name="date" content="2014-11-17">
<link rel="stylesheet" type="text/css" href="../../../../stylesheet.css" title="Style">
</head>
<body>
<script type="text/javascript"><!--
if (location.href.indexOf('is-external=true') == -1) {
parent.document.title="Uses of Class it.necst.grabnrun.SecureDexClassLoader";
}
//-->
</script>
<noscript>
<div>JavaScript is disabled on your browser.</div>
</noscript>
<!-- ========= START OF TOP NAVBAR ======= -->
<div class="topNav"><a name="navbar_top">
<!-- -->
</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
<!-- -->
</a>
<ul class="navList" title="Navigation">
<li><a href="../../../../it/necst/grabnrun/package-summary.html">Package</a></li>
<li><a href="../../../../it/necst/grabnrun/SecureDexClassLoader.html" title="class in it.necst.grabnrun">Class</a></li>
<li class="navBarCell1Rev">Use</li>
<li><a href="../../../../overview-tree.html">Tree</a></li>
<li><a href="../../../../deprecated-list.html">Deprecated</a></li>
<li><a href="../../../../index-files/index-1.html">Index</a></li>
<li><a href="../../../../help-doc.html">Help</a></li>
</ul>
</div>
<div class="subNav">
<ul class="navList">
<li>Prev</li>
<li>Next</li>
</ul>
<ul class="navList">
<li><a href="../../../../index.html?it/necst/grabnrun/class-use/SecureDexClassLoader.html" target="_top">Frames</a></li>
<li><a href="SecureDexClassLoader.html" target="_top">No Frames</a></li>
</ul>
<ul class="navList" id="allclasses_navbar_top">
<li><a href="../../../../allclasses-noframe.html">All Classes</a></li>
</ul>
<div>
<script type="text/javascript"><!--
allClassesLink = document.getElementById("allclasses_navbar_top");
if(window==top) {
allClassesLink.style.display = "block";
}
else {
allClassesLink.style.display = "none";
}
//-->
</script>
</div>
<a name="skip-navbar_top">
<!-- -->
</a></div>
<!-- ========= END OF TOP NAVBAR ========= -->
<div class="header">
<h2 title="Uses of Class it.necst.grabnrun.SecureDexClassLoader" class="title">Uses of Class<br>it.necst.grabnrun.SecureDexClassLoader</h2>
</div>
<div class="classUseContainer">
<ul class="blockList">
<li class="blockList">
<ul class="blockList">
<li class="blockList"><a name="it.necst.grabnrun">
<!-- -->
</a>
<h3>Uses of <a href="../../../../it/necst/grabnrun/SecureDexClassLoader.html" title="class in it.necst.grabnrun">SecureDexClassLoader</a> in <a href="../../../../it/necst/grabnrun/package-summary.html">it.necst.grabnrun</a></h3>
<table border="0" cellpadding="3" cellspacing="0" summary="Use table, listing methods, and an explanation">
<caption><span>Methods in <a href="../../../../it/necst/grabnrun/package-summary.html">it.necst.grabnrun</a> that return <a href="../../../../it/necst/grabnrun/SecureDexClassLoader.html" title="class in it.necst.grabnrun">SecureDexClassLoader</a></span><span class="tabEnd"> </span></caption>
<tr>
<th class="colFirst" scope="col">Modifier and Type</th>
<th class="colLast" scope="col">Method and Description</th>
</tr>
<tbody>
<tr class="altColor">
<td class="colFirst"><code><a href="../../../../it/necst/grabnrun/SecureDexClassLoader.html" title="class in it.necst.grabnrun">SecureDexClassLoader</a></code></td>
<td class="colLast"><span class="strong">SecureLoaderFactory.</span><code><strong><a href="../../../../it/necst/grabnrun/SecureLoaderFactory.html#createDexClassLoader(java.lang.String,%20java.lang.String,%20java.lang.ClassLoader,%20java.util.Map)">createDexClassLoader</a></strong>(<a href="http://d.android.com/reference/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> dexPath,
<a href="http://d.android.com/reference/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> libraryPath,
<a href="http://d.android.com/reference/java/lang/ClassLoader.html?is-external=true" title="class or interface in java.lang">ClassLoader</a> parent,
<a href="http://d.android.com/reference/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</a><<a href="http://d.android.com/reference/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>,<a href="http://d.android.com/reference/java/net/URL.html?is-external=true" title="class or interface in java.net">URL</a>> packageNameToCertificateMap)</code>
<div class="block">Creates a <a href="../../../../it/necst/grabnrun/SecureDexClassLoader.html" title="class in it.necst.grabnrun"><code>SecureDexClassLoader</code></a> that finds interpreted and native code in a set of
provided locations (either local or remote via HTTP or HTTPS) in dexPath.</div>
</td>
</tr>
<tr class="rowColor">
<td class="colFirst"><code><a href="../../../../it/necst/grabnrun/SecureDexClassLoader.html" title="class in it.necst.grabnrun">SecureDexClassLoader</a></code></td>
<td class="colLast"><span class="strong">SecureLoaderFactory.</span><code><strong><a href="../../../../it/necst/grabnrun/SecureLoaderFactory.html#createDexClassLoader(java.lang.String,%20java.lang.String,%20java.lang.ClassLoader,%20java.util.Map,%20boolean)">createDexClassLoader</a></strong>(<a href="http://d.android.com/reference/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> dexPath,
<a href="http://d.android.com/reference/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> libraryPath,
<a href="http://d.android.com/reference/java/lang/ClassLoader.html?is-external=true" title="class or interface in java.lang">ClassLoader</a> parent,
<a href="http://d.android.com/reference/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</a><<a href="http://d.android.com/reference/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>,<a href="http://d.android.com/reference/java/net/URL.html?is-external=true" title="class or interface in java.net">URL</a>> packageNameToCertificateMap,
boolean performLazyEvaluation)</code>
<div class="block">This method returns a <a href="../../../../it/necst/grabnrun/SecureDexClassLoader.html" title="class in it.necst.grabnrun"><code>SecureDexClassLoader</code></a> instance in the same way as it is
explained in the <a href="../../../../it/necst/grabnrun/SecureLoaderFactory.html#createDexClassLoader(java.lang.String,%20java.lang.String,%20java.lang.ClassLoader,%20java.util.Map)"><code>SecureLoaderFactory.createDexClassLoader(String, String, ClassLoader, Map)</code></a>.</div>
</td>
</tr>
</tbody>
</table>
</li>
</ul>
</li>
</ul>
</div>
<!-- ======= START OF BOTTOM NAVBAR ====== -->
<div class="bottomNav"><a name="navbar_bottom">
<!-- -->
</a><a href="#skip-navbar_bottom" title="Skip navigation links"></a><a name="navbar_bottom_firstrow">
<!-- -->
</a>
<ul class="navList" title="Navigation">
<li><a href="../../../../it/necst/grabnrun/package-summary.html">Package</a></li>
<li><a href="../../../../it/necst/grabnrun/SecureDexClassLoader.html" title="class in it.necst.grabnrun">Class</a></li>
<li class="navBarCell1Rev">Use</li>
<li><a href="../../../../overview-tree.html">Tree</a></li>
<li><a href="../../../../deprecated-list.html">Deprecated</a></li>
<li><a href="../../../../index-files/index-1.html">Index</a></li>
<li><a href="../../../../help-doc.html">Help</a></li>
</ul>
</div>
<div class="subNav">
<ul class="navList">
<li>Prev</li>
<li>Next</li>
</ul>
<ul class="navList">
<li><a href="../../../../index.html?it/necst/grabnrun/class-use/SecureDexClassLoader.html" target="_top">Frames</a></li>
<li><a href="SecureDexClassLoader.html" target="_top">No Frames</a></li>
</ul>
<ul class="navList" id="allclasses_navbar_bottom">
<li><a href="../../../../allclasses-noframe.html">All Classes</a></li>
</ul>
<div>
<script type="text/javascript"><!--
allClassesLink = document.getElementById("allclasses_navbar_bottom");
if(window==top) {
allClassesLink.style.display = "block";
}
else {
allClassesLink.style.display = "none";
}
//-->
</script>
</div>
<a name="skip-navbar_bottom">
<!-- -->
</a></div>
<!-- ======== END OF BOTTOM NAVBAR ======= -->
</body>
</html>
================================================
FILE: docs/javaDoc/it/necst/grabnrun/class-use/SecureLoaderFactory.html
================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- NewPage -->
<html lang="en">
<head>
<!-- Generated by javadoc (version 1.7.0_72) on Mon Nov 17 19:29:57 CET 2014 -->
<title>Uses of Class it.necst.grabnrun.SecureLoaderFactory</title>
<meta name="date" content="2014-11-17">
<link rel="stylesheet" type="text/css" href="../../../../stylesheet.css" title="Style">
</head>
<body>
<script type="text/javascript"><!--
if (location.href.indexOf('is-external=true') == -1) {
parent.document.title="Uses of Class it.necst.grabnrun.SecureLoaderFactory";
}
//-->
</script>
<noscript>
<div>JavaScript is disabled on your browser.</div>
</noscript>
<!-- ========= START OF TOP NAVBAR ======= -->
<div class="topNav"><a name="navbar_top">
<!-- -->
</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
<!-- -->
</a>
<ul class="navList" title="Navigation">
<li><a href="../../../../it/necst/grabnrun/package-summary.html">Package</a></li>
<li><a href="../../../../it/necst/grabnrun/SecureLoaderFactory.html" title="class in it.necst.grabnrun">Class</a></li>
<li class="navBarCell1Rev">Use</li>
<li><a href="../../../../overview-tree.html">Tree</a></li>
<li><a href="../../../../deprecated-list.html">Deprecated</a></li>
<li><a href="../../../../index-files/index-1.html">Index</a></li>
<li><a href="../../../../help-doc.html">Help</a></li>
</ul>
</div>
<div class="subNav">
<ul class="navList">
<li>Prev</li>
<li>Next</li>
</ul>
<ul class="navList">
<li><a href="../../../../index.html?it/necst/grabnrun/class-use/SecureLoaderFactory.html" target="_top">Frames</a></li>
<li><a href="SecureLoaderFactory.html" target="_top">No Frames</a></li>
</ul>
<ul class="navList" id="allclasses_navbar_top">
<li><a href="../../../../allclasses-noframe.html">All Classes</a></li>
</ul>
<div>
<script type="text/javascript"><!--
allClassesLink = document.getElementById("allclasses_navbar_top");
if(window==top) {
allClassesLink.style.display = "block";
}
else {
allClassesLink.style.display = "none";
}
//-->
</script>
</div>
<a name="skip-navbar_top">
<!-- -->
</a></div>
<!-- ========= END OF TOP NAVBAR ========= -->
<div class="header">
<h2 title="Uses of Class it.necst.grabnrun.SecureLoaderFactory" class="title">Uses of Class<br>it.necst.grabnrun.SecureLoaderFactory</h2>
</div>
<div class="classUseContainer">No usage of it.necst.grabnrun.SecureLoaderFactory</div>
<!-- ======= START OF BOTTOM NAVBAR ====== -->
<div class="bottomNav"><a name="navbar_bottom">
<!-- -->
</a><a href="#skip-navbar_bottom" title="Skip navigation links"></a><a name="navbar_bottom_firstrow">
<!-- -->
</a>
<ul class="navList" title="Navigation">
<li><a href="../../../../it/necst/grabnrun/package-summary.html">Package</a></li>
<li><a href="../../../../it/necst/grabnrun/SecureLoaderFactory.html" title="class in it.necst.grabnrun">Class</a></li>
<li class="navBarCell1Rev">Use</li>
<li><a href="../../../../overview-tree.html">Tree</a></li>
<li><a href="../../../../deprecated-list.html">Deprecated</a></li>
<li><a href="../../../../index-files/index-1.html">Index</a></li>
<li><a href="../../../../help-doc.html">Help</a></li>
</ul>
</div>
<div class="subNav">
<ul class="navList">
<li>Prev</li>
<li>Next</li>
</ul>
<ul class="navList">
<li><a href="../../../../index.html?it/necst/grabnrun/class-use/SecureLoaderFactory.html" target="_top">Frames</a></li>
<li><a href="SecureLoaderFactory.html" target="_top">No Frames</a></li>
</ul>
<ul class="navList" id="allclasses_navbar_bottom">
<li><a href="../../../../allclasses-noframe.html">All Classes</a></li>
</ul>
<div>
<script type="text/javascript"><!--
allClassesLink = document.getElementById("allclasses_navbar_bottom");
if(window==top) {
allClassesLink.style.display = "block";
}
else {
allClassesLink.style.display = "none";
}
//-->
</script>
</div>
<a name="skip-navbar_bottom">
<!-- -->
</a></div>
<!-- ======== END OF BOTTOM NAVBAR ======= -->
</body>
</html>
================================================
FILE: docs/javaDoc/it/necst/grabnrun/package-frame.html
================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- NewPage -->
<html lang="en">
<head>
<!-- Generated by javadoc (version 1.7.0_72) on Mon Nov 17 19:29:57 CET 2014 -->
<title>it.necst.grabnrun</title>
<meta name="date" content="2014-11-17">
<link rel="stylesheet" type="text/css" href="../../../stylesheet.css" title="Style">
</head>
<body>
<h1 class="bar"><a href="../../../it/necst/grabnrun/package-summary.html" target="classFrame">it.necst.grabnrun</a></h1>
<div class="indexContainer">
<h2 title="Classes">Classes</h2>
<ul title="Classes">
<li><a href="SecureDexClassLoader.html" title="class in it.necst.grabnrun" target="classFrame">SecureDexClassLoader</a></li>
<li><a href="SecureLoaderFactory.html" title="class in it.necst.grabnrun" target="classFrame">SecureLoaderFactory</a></li>
</ul>
</div>
</body>
</html>
================================================
FILE: docs/javaDoc/it/necst/grabnrun/package-summary.html
================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- NewPage -->
<html lang="en">
<head>
<!-- Generated by javadoc (version 1.7.0_72) on Mon Nov 17 19:29:57 CET 2014 -->
<title>it.necst.grabnrun</title>
<meta name="date" content="2014-11-17">
<link rel="stylesheet" type="text/css" href="../../../stylesheet.css" title="Style">
</head>
<body>
<script type="text/javascript"><!--
if (location.href.indexOf('is-external=true') == -1) {
parent.document.title="it.necst.grabnrun";
}
//-->
</script>
<noscript>
<div>JavaScript is disabled on your browser.</div>
</noscript>
<!-- ========= START OF TOP NAVBAR ======= -->
<div class="topNav"><a name="navbar_top">
<!-- -->
</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
<!-- -->
</a>
<ul class="navList" title="Navigation">
<li><a href="../../../it/necst/grabnrun/package-summary.html">Package</a></li>
<li>Class</li>
<li><a href="package-use.html">Use</a></li>
<li><a href="package-tree.html">Tree</a></li>
<li><a href="../../../deprecated-list.html">Deprecated</a></li>
<li><a href="../../../index-files/index-1.html">Index</a></li>
<li><a href="../../../help-doc.html">Help</a></li>
</ul>
</div>
<div class="subNav">
<ul class="navList">
<li>Prev Package</li>
<li>Next Package</li>
</ul>
<ul class="navList">
<li><a href="../../../index.html?it/necst/grabnrun/package-summary.html" target="_top">Frames</a></li>
<li><a href="package-summary.html" target="_top">No Frames</a></li>
</ul>
<ul class="navList" id="allclasses_navbar_top">
<li><a href="../../../allclasses-noframe.html">All Classes</a></li>
</ul>
<div>
<script type="text/javascript"><!--
allClassesLink = document.getElementById("allclasses_navbar_top");
if(window==top) {
allClassesLink.style.display = "block";
}
else {
allClassesLink.style.display = "none";
}
//-->
</script>
</div>
<a name="skip-navbar_top">
<!-- -->
</a></div>
<!-- ========= END OF TOP NAVBAR ========= -->
<div class="header">
<h1 title="Package" class="title">Package it.necst.grabnrun</h1>
</div>
<div class="contentContainer">
<ul class="blockList">
<li class="blockList">
<table class="packageSummary" border="0" cellpadding="3" cellspacing="0" summary="Class Summary table, listing classes, and an explanation">
<caption><span>Class Summary</span><span class="tabEnd"> </span></caption>
<tr>
<th class="colFirst" scope="col">Class</th>
<th class="colLast" scope="col">Description</th>
</tr>
<tbody>
<tr class="altColor">
<td class="colFirst"><a href="../../../it/necst/grabnrun/SecureDexClassLoader.html" title="class in it.necst.grabnrun">SecureDexClassLoader</a></td>
<td class="colLast">
<div class="block">A class that provides an extension of default <a href="http://d.android.com/reference/dalvik/system/DexClassLoader.html?is-external=true" title="class or interface in dalvik.system"><code>DexClassLoader</code></a>
provided by the Android system and it is used to load classes
from jar and apk container files including a classes.dex entry in a secure way.</div>
</td>
</tr>
<tr class="rowColor">
<td class="colFirst"><a href="../../../it/necst/grabnrun/SecureLoaderFactory.html" title="class in it.necst.grabnrun">SecureLoaderFactory</a></td>
<td class="colLast">
<div class="block">A Factory class that generates instances of classes used to
retrieve dynamic code in a secure way at run time.</div>
</td>
</tr>
</tbody>
</table>
</li>
</ul>
</div>
<!-- ======= START OF BOTTOM NAVBAR ====== -->
<div class="bottomNav"><a name="navbar_bottom">
<!-- -->
</a><a
gitextract_0udiqonx/
├── .gitmodules
├── COPYRIGHT
├── README.md
├── docs/
│ ├── .gitignore
│ ├── .placeholder
│ ├── Makefile
│ ├── complementary.rst
│ ├── conf.py
│ ├── example.rst
│ ├── index.rst
│ ├── javaDoc/
│ │ ├── allclasses-frame.html
│ │ ├── allclasses-noframe.html
│ │ ├── constant-values.html
│ │ ├── deprecated-list.html
│ │ ├── help-doc.html
│ │ ├── index-files/
│ │ │ ├── index-1.html
│ │ │ ├── index-2.html
│ │ │ ├── index-3.html
│ │ │ ├── index-4.html
│ │ │ ├── index-5.html
│ │ │ └── index-6.html
│ │ ├── index.html
│ │ ├── it/
│ │ │ └── necst/
│ │ │ └── grabnrun/
│ │ │ ├── SecureDexClassLoader.html
│ │ │ ├── SecureLoaderFactory.html
│ │ │ ├── class-use/
│ │ │ │ ├── SecureDexClassLoader.html
│ │ │ │ └── SecureLoaderFactory.html
│ │ │ ├── package-frame.html
│ │ │ ├── package-summary.html
│ │ │ ├── package-tree.html
│ │ │ └── package-use.html
│ │ ├── overview-tree.html
│ │ ├── package-list
│ │ └── stylesheet.css
│ ├── repackaging.rst
│ ├── security.rst
│ └── tutorial.rst
├── downloads/
│ ├── 1.0/
│ │ ├── gnr-1.0.jar
│ │ └── gnr-1.0.jar.sha1
│ ├── 1.0.1/
│ │ ├── gnr-1.0.1.aar
│ │ ├── gnr-1.0.1.aar.sha1
│ │ ├── gnr-1.0.1.jar
│ │ └── gnr-1.0.1.jar.sha1
│ ├── 1.0.2/
│ │ ├── gnr-1.0.2.aar
│ │ ├── gnr-1.0.2.aar.sha1
│ │ ├── gnr-1.0.2.jar
│ │ └── gnr-1.0.2.jar.sha1
│ ├── 1.0.3/
│ │ ├── grabnrun-1.0.3.aar
│ │ ├── grabnrun-1.0.3.aar.sha1
│ │ ├── grabnrun-1.0.3.jar
│ │ └── grabnrun-1.0.3.jar.sha1
│ └── 1.0.4/
│ ├── grabnrun-1.0.4.aar
│ ├── grabnrun-1.0.4.aar.sha1
│ ├── grabnrun-1.0.4.jar
│ └── grabnrun-1.0.4.jar.sha1
├── example/
│ ├── ADT/
│ │ ├── .classpath
│ │ ├── .gitignore
│ │ ├── .project
│ │ ├── AndroidManifest.xml
│ │ ├── assets/
│ │ │ └── exampleJar/
│ │ │ └── componentModifier.jar
│ │ ├── libs/
│ │ │ └── gnr-1.0.1.jar
│ │ ├── lint.xml
│ │ ├── proguard-project.txt
│ │ ├── project.properties
│ │ ├── res/
│ │ │ ├── layout/
│ │ │ │ ├── activity_dex_class_sample.xml
│ │ │ │ └── activity_main.xml
│ │ │ └── values/
│ │ │ └── strings.xml
│ │ └── src/
│ │ └── it/
│ │ └── polimi/
│ │ └── poccodeloading/
│ │ ├── ComponentModifier.java
│ │ ├── DexClassSampleActivity.java
│ │ └── MainActivity.java
│ └── AS/
│ ├── .gitignore
│ ├── app/
│ │ ├── build.gradle
│ │ ├── lint.xml
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ ├── assets/
│ │ │ └── exampleJar/
│ │ │ └── componentModifier.jar
│ │ ├── java/
│ │ │ └── it/
│ │ │ └── polimi/
│ │ │ └── poccodeloading/
│ │ │ ├── ComponentModifier.java
│ │ │ ├── DexClassSampleActivity.java
│ │ │ └── MainActivity.java
│ │ └── res/
│ │ ├── layout/
│ │ │ ├── activity_dex_class_sample.xml
│ │ │ └── activity_main.xml
│ │ └── values/
│ │ └── strings.xml
│ ├── build.gradle
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
├── gnr/
│ ├── .gitignore
│ ├── app/
│ │ ├── build.gradle
│ │ ├── lint.xml
│ │ ├── proguard-project.txt
│ │ └── src/
│ │ ├── main/
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── java/
│ │ │ │ └── it/
│ │ │ │ └── necst/
│ │ │ │ └── grabnrun/
│ │ │ │ ├── CacheLogger.java
│ │ │ │ ├── CertificateFileFilterByNameMatch.java
│ │ │ │ ├── ContainerSignatureVerifier.java
│ │ │ │ ├── DexPathStringProcessor.java
│ │ │ │ ├── FileDownloader.java
│ │ │ │ ├── FileFilterByNameMatch.java
│ │ │ │ ├── FileHelper.java
│ │ │ │ ├── PackageNameHelper.java
│ │ │ │ ├── PackageNameTrie.java
│ │ │ │ ├── SecureDexClassLoader.java
│ │ │ │ └── SecureLoaderFactory.java
│ │ │ └── res/
│ │ │ ├── values-v11/
│ │ │ │ └── styles.xml
│ │ │ └── values-v14/
│ │ │ └── styles.xml
│ │ └── test/
│ │ └── java/
│ │ └── it/
│ │ └── necst/
│ │ └── grabnrun/
│ │ ├── CacheLoggerTest.java
│ │ ├── CertificateFileFilterByNameMatchTest.java
│ │ ├── ContainerSignatureVerifierTest.java
│ │ ├── DexPathStringProcessorTest.java
│ │ ├── FileDownloaderTest.java
│ │ ├── FileFilterByNameMatchTest.java
│ │ ├── FileHelperTest.java
│ │ ├── PackageNameHelperTest.java
│ │ ├── PackageNameTrieTest.java
│ │ ├── SecureDexClassLoaderTest.java
│ │ ├── SecureLoaderFactoryTest.java
│ │ └── shadows/
│ │ ├── BaseDexClassLoaderShadow.java
│ │ └── DexFileShadow.java
│ ├── build.gradle
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradle-app.setting
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
├── grabandrun.bib
└── repackPOC/
├── .gitignore
├── RepackInputSelector/
│ ├── .classpath
│ ├── .project
│ └── src/
│ └── it/
│ └── necst/
│ └── grabnrun/
│ └── selector/
│ ├── LinkContainerDialog.java
│ └── MainFrame.java
├── libs/
│ ├── RepackInputSelector.jar
│ └── apktool.jar
├── repackagingTool.py
├── requirements.txt
└── smaliRes/
└── grabnrun/
├── CacheLogger.smali
├── CertFileFilter.smali
├── FileDownloader$1.smali
├── FileDownloader.smali
├── FileFilterByName.smali
├── PackageNameTrie.smali
├── RepackHandler.smali
├── RepackHandlerTail.smali
├── SecureDexClassLoader$SignatureVerificationTask.smali
├── SecureDexClassLoader.smali
└── SecureLoaderFactory.smali
SYMBOL INDEX (297 symbols across 33 files)
FILE: example/ADT/src/it/polimi/poccodeloading/ComponentModifier.java
type ComponentModifier (line 31) | public interface ComponentModifier {
method customizeButtons (line 33) | public void customizeButtons(List<Button> buttonList);
method customizeSwitch (line 35) | public void customizeSwitch(Switch switchSlider);
method customizeTextView (line 37) | public void customizeTextView(TextView textView);
FILE: example/ADT/src/it/polimi/poccodeloading/DexClassSampleActivity.java
class DexClassSampleActivity (line 56) | public class DexClassSampleActivity extends Activity {
method onCreate (line 87) | @Override
method randomContainerPathChoice (line 131) | private String randomContainerPathChoice() {
method retrieveComponentModifier (line 140) | private ComponentModifier retrieveComponentModifier(String className) {
method retrieveComponentModifierSecurely (line 212) | private ComponentModifier retrieveComponentModifierSecurely(String cla...
method onBtnClick (line 312) | public void onBtnClick(View view) {
method onBtnClickExit (line 368) | public void onBtnClickExit(View view) {
FILE: example/ADT/src/it/polimi/poccodeloading/MainActivity.java
class MainActivity (line 53) | public class MainActivity extends Activity {
method onCreate (line 89) | @Override
method setUpProfileSecureDexClassLoader (line 170) | protected void setUpProfileSecureDexClassLoader() {
method setUpSecureDexClassLoader (line 264) | protected void setUpSecureDexClassLoader() {
method setUpDexClassLoader (line 452) | protected void setUpDexClassLoader() {
FILE: example/AS/app/src/main/java/it/polimi/poccodeloading/ComponentModifier.java
type ComponentModifier (line 30) | public interface ComponentModifier {
method customizeButtons (line 32) | void customizeButtons(List<Button> buttonList);
method customizeSwitch (line 34) | void customizeSwitch(Switch switchSlider);
method customizeTextView (line 36) | void customizeTextView(TextView textView);
FILE: example/AS/app/src/main/java/it/polimi/poccodeloading/DexClassSampleActivity.java
class DexClassSampleActivity (line 55) | public class DexClassSampleActivity extends Activity {
method onCreate (line 86) | @Override
method randomContainerPathChoice (line 130) | private String randomContainerPathChoice() {
method retrieveComponentModifier (line 139) | private ComponentModifier retrieveComponentModifier(String className) {
method retrieveComponentModifierSecurely (line 212) | private ComponentModifier retrieveComponentModifierSecurely(String cla...
method onBtnClick (line 312) | public void onBtnClick(View view) {
method onBtnClickExit (line 368) | public void onBtnClickExit(View view) {
FILE: example/AS/app/src/main/java/it/polimi/poccodeloading/MainActivity.java
class MainActivity (line 52) | public class MainActivity extends Activity {
method onCreate (line 81) | @Override
method setUpProfileSecureDexClassLoader (line 155) | protected void setUpProfileSecureDexClassLoader() {
method setUpSecureDexClassLoader (line 247) | protected void setUpSecureDexClassLoader() {
method setUpDexClassLoader (line 411) | protected void setUpDexClassLoader() {
FILE: gnr/app/src/main/java/it/necst/grabnrun/CacheLogger.java
class CacheLogger (line 50) | final class CacheLogger {
method CacheLogger (line 95) | CacheLogger(@NonNull String cacheDirectoryPath, int daysTillConsidered...
method initializeMapsThroughHelperFile (line 113) | private void initializeMapsThroughHelperFile() {
method parseLineInHelperFile (line 136) | private void parseLineInHelperFile(String currentLine) {
method checkLocalFileFreshness (line 170) | private void checkLocalFileFreshness(Long fileCreationTimestamp) {
method checkForCachedEntry (line 186) | final @NonNull Optional<String> checkForCachedEntry(@NonNull URL remot...
method addCachedEntryToLog (line 210) | final void addCachedEntryToLog(@NonNull URL remoteURL, @NonNull String...
method finalizeLog (line 227) | final void finalizeLog() {
method deletePreviousHelperFile (line 238) | private void deletePreviousHelperFile() {
method updateHelperFileWithNewMappings (line 244) | private void updateHelperFileWithNewMappings() {
method getLogLineFromURL (line 266) | private String getLogLineFromURL(URL currentRemoteURL) {
FILE: gnr/app/src/main/java/it/necst/grabnrun/CertificateFileFilterByNameMatch.java
class CertificateFileFilterByNameMatch (line 31) | final class CertificateFileFilterByNameMatch extends FileFilterByNameMat...
method CertificateFileFilterByNameMatch (line 45) | CertificateFileFilterByNameMatch(@NonNull String certificateName) {
FILE: gnr/app/src/main/java/it/necst/grabnrun/ContainerSignatureVerifier.java
class ContainerSignatureVerifier (line 33) | class ContainerSignatureVerifier {
method ContainerSignatureVerifier (line 40) | ContainerSignatureVerifier(
method verifyContainerSignatureAgainstCertificate (line 52) | boolean verifyContainerSignatureAgainstCertificate(
method verifyJARContainer (line 170) | private void verifyJARContainer(
FILE: gnr/app/src/main/java/it/necst/grabnrun/DexPathStringProcessor.java
class DexPathStringProcessor (line 15) | class DexPathStringProcessor {
method DexPathStringProcessor (line 24) | DexPathStringProcessor(@NonNull String fullDexPathString) {
method extractSingleDexPathStringsFromFullOne (line 34) | private List<String> extractSingleDexPathStringsFromFullOne(String ful...
method hasNextDexPathString (line 44) | public boolean hasNextDexPathString() {
method nextDexPathString (line 48) | public String nextDexPathString() throws NoSuchElementException {
FILE: gnr/app/src/main/java/it/necst/grabnrun/FileDownloader.java
class FileDownloader (line 48) | final class FileDownloader {
method FileDownloader (line 75) | FileDownloader(@NonNull Context parentContext) {
method downloadRemoteResource (line 100) | final boolean downloadRemoteResource(
method getDownloadedFileExtension (line 267) | Optional<String> getDownloadedFileExtension() {
FILE: gnr/app/src/main/java/it/necst/grabnrun/FileFilterByNameMatch.java
class FileFilterByNameMatch (line 34) | class FileFilterByNameMatch implements FileFilter {
method FileFilterByNameMatch (line 48) | FileFilterByNameMatch(@NonNull String name, @NonNull String extension) {
method accept (line 58) | @Override
FILE: gnr/app/src/main/java/it/necst/grabnrun/FileHelper.java
class FileHelper (line 12) | public class FileHelper {
method extractFilePathWithoutExtensionFromFilePath (line 17) | public static String extractFilePathWithoutExtensionFromFilePath(@NonN...
method extractFileNameWithoutExtensionFromFilePath (line 23) | public static String extractFileNameWithoutExtensionFromFilePath(@NonN...
method extractSubstringWithoutExtensionFromString (line 29) | private static String extractSubstringWithoutExtensionFromString(@NonN...
method extractFileNameFromFilePath (line 39) | public static String extractFileNameFromFilePath(@NonNull String fileP...
method extractExtensionFromFilePath (line 50) | public static Optional<String> extractExtensionFromFilePath(@NonNull S...
method endsWithJarOrApkExtension (line 61) | public static boolean endsWithJarOrApkExtension(@NonNull String filePa...
method checkPreconditionsOnFilePath (line 75) | private static void checkPreconditionsOnFilePath(@NonNull String fileP...
FILE: gnr/app/src/main/java/it/necst/grabnrun/PackageNameHelper.java
class PackageNameHelper (line 13) | public class PackageNameHelper {
method isAValidPackageName (line 22) | public static boolean isAValidPackageName(@NonNull String candidatePac...
method revertPackageNameToURL (line 42) | public static URL revertPackageNameToURL(@NonNull String candidatePack...
FILE: gnr/app/src/main/java/it/necst/grabnrun/PackageNameTrie.java
class PackageNameTrie (line 38) | final class PackageNameTrie {
method PackageNameTrie (line 49) | PackageNameTrie() {
method generateEntriesForPackageName (line 69) | final void generateEntriesForPackageName(String packageName) {
method getUpALevel (line 98) | private String getUpALevel(String packageName) {
method setPackageNameHasAssociatedCertificate (line 118) | final void setPackageNameHasAssociatedCertificate(String packageName) {
method getPackageNameWithAssociatedCertificate (line 139) | final Optional<String> getPackageNameWithAssociatedCertificate(String ...
FILE: gnr/app/src/main/java/it/necst/grabnrun/SecureDexClassLoader.java
class SecureDexClassLoader (line 112) | public class SecureDexClassLoader {
method SecureDexClassLoader (line 160) | @VisibleForTesting SecureDexClassLoader(
method generatePackageNameToContainerPathMap (line 200) | private static Map<String, String> generatePackageNameToContainerPathMap(
method getPackageNamesFromContainerPath (line 239) | private static Optional<ImmutableSet<String>> getPackageNamesFromConta...
method initializePackageNameTrieBasedOnContainerAndCertificateMaps (line 333) | private static PackageNameTrie initializePackageNameTrieBasedOnContain...
method performEagerEvaluationOnAllContainers (line 349) | private void performEagerEvaluationOnAllContainers() {
method verifyAllContainersSignature (line 369) | private void verifyAllContainersSignature() {
method verifyAllContainersSignatureConcurrently (line 457) | private void verifyAllContainersSignatureConcurrently(Set<String> cont...
class SignatureVerificationTask (line 579) | class SignatureVerificationTask implements Runnable {
method SignatureVerificationTask (line 588) | public SignatureVerificationTask(String containerPath, String rootPa...
method run (line 596) | @Override
method loadClass (line 651) | public Class<?> loadClass(@NonNull String className) throws ClassNotFo...
method importCertificateFromPackageName (line 811) | private X509Certificate importCertificateFromPackageName(String packag...
method importCertificateFromAppPrivateDir (line 846) | private X509Certificate importCertificateFromAppPrivateDir(String pack...
method downloadCertificateRemotelyViaHttps (line 928) | private boolean downloadCertificateRemotelyViaHttps(String packageName) {
method wipeOutPrivateAppCachedData (line 962) | public void wipeOutPrivateAppCachedData(boolean containerPrivateFolder...
FILE: gnr/app/src/main/java/it/necst/grabnrun/SecureLoaderFactory.java
class SecureLoaderFactory (line 60) | public class SecureLoaderFactory {
method SecureLoaderFactory (line 108) | public SecureLoaderFactory(Context parentContext) {
method SecureLoaderFactory (line 134) | public SecureLoaderFactory(Context parentContext, int daysBeforeContai...
method createDexClassLoader (line 196) | public SecureDexClassLoader createDexClassLoader(
method createDexClassLoader (line 255) | public SecureDexClassLoader createDexClassLoader(
method checkPreconditionsOnArgumentsForSecureDexClassLoaderCreation (line 307) | private static void checkPreconditionsOnArgumentsForSecureDexClassLoad...
method processDexPathStringAndImportContainers (line 328) | private String processDexPathStringAndImportContainers(String dexPath,...
method isARemoteHttpOrHttpsResource (line 372) | private static boolean isARemoteHttpOrHttpsResource(String resourcePat...
method processPathPointingToARemoteContainer (line 377) | private Optional<String> processPathPointingToARemoteContainer(
method processPathPointingToALocallyStoredContainer (line 461) | private Optional<String> processPathPointingToALocallyStoredContainer(
method computeDigestFromFilePath (line 540) | private String computeDigestFromFilePath(String filePath) {
method processPackageNameToCertificateMap (line 582) | private Map<String, URL> processPackageNameToCertificateMap(
method downloadContainerIntoFolder (line 621) | private String downloadContainerIntoFolder(String urlPath, File resOut...
FILE: gnr/app/src/test/java/it/necst/grabnrun/CacheLoggerTest.java
class CacheLoggerTest (line 17) | @RunWith(MockitoJUnitRunner.class)
method givenNotPositiveIntegerForDaysTillConsideredFresh_whenCreateCacheLogger_thenThrows (line 26) | @Test (expected = IllegalArgumentException.class)
method givenNoHelperFileWasStored_whenCheckForCachedEntry_thenReturnsAnAbsentOptional (line 35) | @Test
method givenNoHelperFileWasStoredAndAddAURLAsACachedEntry_whenCheckForCachedEntryWithADifferentURL_thenReturnsAnAbsentOptional (line 49) | @Test
method givenNoHelperFileWasStoredAndAddAURLAsACachedEntry_whenCheckForCachedEntryWithThatURL_thenReturnsTheLocalFileName (line 65) | @Test
method givenNoHelperFileWasStoredAndCacheLoggerIsFinalizedAndAURLIsAddedAsACachedEntry_whenCheckForCachedEntryWithThatURL_thenReturnsAnAbsentOptional (line 82) | @Test
method givenHelperFileWasStoredWithAURLAsACachedEntry_whenCheckForCachedEntryWithThatURLOnANewCacheLogger_thenReturnsTheLocalFileName (line 99) | @Test
method initializeCacheLoggerWithTestValues (line 119) | private CacheLogger initializeCacheLoggerWithTestValues() {
method getTemporaryFolderPath (line 124) | private String getTemporaryFolderPath() {
method createFakeLocalFileAndAddItsNameToTheCacheLogger (line 128) | private String createFakeLocalFileAndAddItsNameToTheCacheLogger(
method computeFileNameFromURL (line 136) | private String computeFileNameFromURL(URL testRemoteURL) {
FILE: gnr/app/src/test/java/it/necst/grabnrun/CertificateFileFilterByNameMatchTest.java
class CertificateFileFilterByNameMatchTest (line 16) | @RunWith(MockitoJUnitRunner.class)
method initializeCertificateFileFilterWithTestCertificateName (line 31) | @Before
method givenAnEmptyFileName_whenCreateCertificateFileFilter_thenThrows (line 36) | @Test (expected = IllegalArgumentException.class)
method givenADirectory_whenAccept_thenReturnFalse (line 41) | @Test
method givenAFileWithMatchingFileNameButUnsupportedExtension_whenAccept_thenReturnFalse (line 53) | @Test
method givenAFileWithSupportedExtensionButNotMatchingFileName_whenAccept_thenReturnFalse (line 67) | @Test
method givenAFileWithMatchingFileNameAndSupportedExtension_whenAccept_thenReturnTrue (line 81) | @Test
method setupFileMockAsADirectory (line 95) | private void setupFileMockAsADirectory(boolean shouldBeADirectory) {
FILE: gnr/app/src/test/java/it/necst/grabnrun/ContainerSignatureVerifierTest.java
class ContainerSignatureVerifierTest (line 35) | @RunWith(MockitoJUnitRunner.class)
method initializeTestContainerSignatureVerifierAndSetupMocks (line 61) | @Before
method givenAnEmptyContainerPath_whenVerifyContainerAgainstCertificate_thenThrows (line 75) | @Test (expected = IllegalArgumentException.class)
method givenAnUnsignedJarContainer_whenVerifyContainerAgainstCertificate_thenThrows (line 82) | @Test (expected = IllegalArgumentException.class)
method givenAnUnsignedJarContainer_whenVerifyContainerAgainstCertificate_thenReturnsFalse (line 95) | @Test
method givenAJarContainerSignedWithAnOtherTrustedCertificate_whenVerifyContainerAgainstCertificate_thenReturnsFalse (line 107) | @Test
method givenARepackagedJarContainerPreviouslySignedWithTheTrustedCertificate_whenVerifyContainerAgainstCertificate_thenReturnsFalse (line 124) | @Test
method givenAJarContainerSignedWithTheTrustedCertificate_whenVerifyContainerAgainstCertificate_thenReturnsTrue (line 137) | @Test
method retrieveAndGenerateTrustedCertificate (line 150) | private X509Certificate retrieveAndGenerateTrustedCertificate(
method downloadRemoteResourceIntoTemporaryFolder (line 166) | private String downloadRemoteResourceIntoTemporaryFolder(String remote...
FILE: gnr/app/src/test/java/it/necst/grabnrun/DexPathStringProcessorTest.java
class DexPathStringProcessorTest (line 16) | @RunWith(MockitoJUnitRunner.class)
method givenAnEmptyDexPath_whenCreateDexPathStringProcessor_thenThrows (line 29) | @Test (expected = IllegalArgumentException.class)
method givenASingleTestLocalPath_whenHasNextDexPathString_thenReturnsTrue (line 35) | @Test
method givenASingleTestLocalPath_whenNextDexPathString_thenReturnsTheTestLocalPath (line 47) | @Test
method givenASingleTestRemoteHttpPath_whenHasNextDexPathString_thenReturnsTrue (line 59) | @Test
method givenASingleTestRemoteHttpPath_whenNextDexPathString_thenReturnsTheTestRemoteHttpPath (line 71) | @Test
method givenASingleTestRemoteHttpsPath_whenHasNextDexPathString_thenReturnsTrue (line 83) | @Test
method givenASingleTestRemoteHttpsPath_whenNextDexPathString_thenReturnsTheTestRemoteHttpsPath (line 95) | @Test
method givenATestDexPathWhichConcatenatesThreePaths_whenHasNextDexPathString_thenReturnsTrueThreeTimesAndFalseAtTheFourth (line 107) | @Test
method givenATestDexPathWhichConcatenatesThreePaths_whenNextDexPathString_thenReturnsThreeStringsInTheSameOrderOfTheInputDexPath (line 122) | @Test
method givenATestDexPathWhichConcatenatesThreePaths_whenNextDexPathString_thenThrowsAfterThirdInvocation (line 133) | @Test (expected = NoSuchElementException.class)
method concatenateDexPathStrings (line 145) | private static String concatenateDexPathStrings(String... dexPathStrin...
FILE: gnr/app/src/test/java/it/necst/grabnrun/FileDownloaderTest.java
class FileDownloaderTest (line 28) | @RunWith(MockitoJUnitRunner.class)
method setupMocksForFileDownloader (line 48) | @Before
method givenNoNetworkConnectivityIsAvailable_whenDownloadRemoteResource_thenDownloadFailsAndRetrievesNoFile (line 57) | @Test
method givenNetworkConnectivityIsAvailable_whenDownloadRemoteResourceWithTestURLUsingUnsupportedProtocol_thenThrows (line 76) | @Test (expected = IllegalArgumentException.class)
method givenNetworkConnectivityIsAvailable_whenDownloadRemoteResourceWithTestRemoteCertificateURL_thenDownloadSucceedsAndRetrievesAFile (line 90) | @Test
method givenNetworkConnectivityIsAvailableAndNoRedirectIsAllowed_whenDownloadRemoteResourceWithTestRemoteCertificateURLNeedingRedirect_thenDownloadFailsAndRetrievesNoFile (line 108) | @Test
method givenNetworkConnectivityIsAvailableAndRedirectIsAllowed_whenDownloadRemoteResourceWithTestRemoteCertificateURLNeedingRedirect_thenDownloadSucceedsAndRetrievesAFile (line 127) | @Test
method givenNoRemoteResourceWasPreviouslyDownloaded_whenGetDownloadedFileExtension_thenReturnsAnOptionalAbsent (line 146) | @Test
method givenRemoteResourceWasPreviouslyDownloaded_whenGetDownloadedFileExtension_thenReturnsAnOptionalStringMatchingTheFileExtension (line 156) | @Test
method givenRemoteResourceRequiringRedirectWasPreviouslyDownloaded_whenGetDownloadedFileExtension_thenReturnsAnOptionalStringMatchingTheFileExtension (line 175) | @Test
method getLocalFileURIInTemporaryTestDirectory (line 195) | private String getLocalFileURIInTemporaryTestDirectory(String localFil...
method fileExists (line 199) | private static boolean fileExists(String path) {
FILE: gnr/app/src/test/java/it/necst/grabnrun/FileFilterByNameMatchTest.java
class FileFilterByNameMatchTest (line 14) | @RunWith(MockitoJUnitRunner.class)
method givenAnEmptyFileName_whenCreateFileFilter_thenThrows (line 33) | @Test (expected = IllegalArgumentException.class)
method givenAFileExtensionNotMatchingDotAndThreeCharacters_whenCreateFileFilter_thenThrows (line 38) | @Test (expected = IllegalArgumentException.class)
method givenAFileExtensionWithFourUppercaseCharacters_whenCreateFileFilter_thenTheTestSucceeds (line 43) | @Test
method givenADirectory_whenAccept_thenReturnFalse (line 48) | @Test
method givenAFileWithMatchingFileNameButNotExtension_whenAccept_thenReturnFalse (line 61) | @Test
method givenAFileWithMatchingExtensionButNotName_whenAccept_thenReturnFalse (line 76) | @Test
method givenAFileWithMatchingNameAndExtension_whenAccept_thenReturnTrue (line 91) | @Test
method initializeFileFilterWithTestValues (line 106) | private void initializeFileFilterWithTestValues() {
method setupFileMockAsADirectory (line 110) | private void setupFileMockAsADirectory(boolean shouldBeADirectory) {
FILE: gnr/app/src/test/java/it/necst/grabnrun/FileHelperTest.java
class FileHelperTest (line 20) | @RunWith(MockitoJUnitRunner.class)
method givenAnEmptyFilePath_whenExtractFilePathWithoutExtensionFromFilePath_thenThrows (line 37) | @Test (expected = IllegalArgumentException.class)
method givenFileNameWithoutExtension_whenExtractFilePathWithoutExtensionFromFilePath_thenReturnsTheSameString (line 46) | @Test
method givenFileNameWithExtension_whenExtractFilePathWithoutExtensionFromFilePath_thenReturnsTheFileNameWithoutTheExtension (line 56) | @Test
method givenFilePathWithoutExtension_whenExtractFilePathWithoutExtensionFromFilePath_thenReturnsTheSameString (line 66) | @Test
method givenFilePathWithExtension_whenExtractFilePathWithoutExtensionFromFilePath_thenReturnsTheFilePathWithoutTheExtension (line 76) | @Test
method givenAnEmptyFilePath_whenExtractFileNameWithoutExtensionFromFilePath_thenThrows (line 86) | @Test (expected = IllegalArgumentException.class)
method givenAFilePathWithoutAFileNameAndExtension_whenExtractFileNameWithoutExtensionFromFilePath_thenReturnsAnEmptyString (line 95) | @Test
method givenFileNameWithoutExtension_whenExtractFileNameWithoutExtensionFromFilePath_thenReturnsTheSameString (line 104) | @Test
method givenFileNameWithExtension_whenExtractFileNameWithoutExtensionFromFilePath_thenReturnsTheFileNameWithoutTheExtension (line 114) | @Test
method givenFilePathWithoutExtension_whenExtractFileNameWithoutExtensionFromFilePath_thenReturnsTheFileNameWithoutTheExtension (line 124) | @Test
method givenFilePathWithExtension_whenExtractFileNameWithoutExtensionFromFilePath_thenReturnsTheFileNameWithoutTheExtension (line 134) | @Test
method givenAnEmptyFilePath_whenExtractFileNameFromFilePath_thenThrows (line 144) | @Test (expected = IllegalArgumentException.class)
method givenAFilePathWithoutAFileNameAndExtension_whenExtractFileNameFromFilePath_thenReturnsAnEmptyString (line 153) | @Test
method givenFileNameWithoutExtension_whenExtractFileNameFromFilePath_thenReturnsTheSameString (line 162) | @Test
method givenFileNameWithExtension_whenExtractFileNameFromFilePath_thenReturnsTheSameString (line 171) | @Test
method givenFilePathWithoutExtension_whenExtractFileNameFromFilePath_thenReturnsTheFileName (line 180) | @Test
method givenFilePathWithExtension_whenExtractFileNameFromFilePath_thenReturnsTheFileName (line 189) | @Test
method givenAnEmptyFilePath_whenExtractExtensionFromFilePath_thenThrows (line 199) | @Test (expected = IllegalArgumentException.class)
method givenAFileNameWithNoExtensionOnTheFile_whenExtractExtensionFromFilePath_thenReturnsAnAbsentOptional (line 208) | @Test
method givenAFilePathWithNoExtensionOnTheFile_whenExtractExtensionFromFilePath_thenReturnsAnAbsentOptional (line 218) | @Test
method givenAFileNameWithExtensionForTheFile_whenExtractExtensionFromFilePath_thenReturnsAnOptionalContainingTheExtension (line 228) | @Test
method givenAFilePathWithExtensionForTheFile_whenExtractExtensionFromFilePath_thenReturnsAnOptionalContainingTheExtension (line 238) | @Test
method givenAnEmptyFilePath_whenEndsWithJarOrApkExtension_thenThrows (line 248) | @Test (expected = IllegalArgumentException.class)
method givenAFileNameWithNoExtension_whenEndsWithJarOrApkExtension_thenReturnsFalse (line 257) | @Test
method givenAFileNameWithANotContainerExtension_whenEndsWithJarOrApkExtension_thenReturnsFalse (line 263) | @Test
method givenAFileExtensionNotForAContainer_whenEndsWithJarOrApkExtension_thenReturnsFalse (line 270) | @Test
method givenAFileExtensionForAContainer_whenEndsWithJarOrApkExtension_thenReturnsTrue (line 276) | @Test
method givenAFileNameWithAContainerExtension_whenEndsWithJarOrApkExtension_thenReturnsTrue (line 282) | @Test
method givenAFilePathWithAContainerExtension_whenEndsWithJarOrApkExtension_thenReturnsTrue (line 288) | @Test
FILE: gnr/app/src/test/java/it/necst/grabnrun/PackageNameHelperTest.java
class PackageNameHelperTest (line 15) | public class PackageNameHelperTest {
method givenAnEmptyPackageName_whenIsAValidPackageName_thenReturnFalse (line 32) | @Test
method givenAPackageNameStartingWithADot_whenIsAValidPackageName_thenReturnFalse (line 44) | @Test
method givenAPackageNameWithAnEmptyFieldBetweenTwoDots_whenIsAValidPackageName_thenReturnFalse (line 53) | @Test
method givenAPackageNameEndingWithADot_whenIsAValidPackageName_thenReturnFalse (line 63) | @Test
method givenAPackageNameWithOnlyOneField_whenIsAValidPackageName_thenReturnFalse (line 72) | @Test
method givenAPackageNameWithAtLeastTwoFieldsSeparatedByASingleDot_whenIsAValidPackageName_thenReturnTrue (line 81) | @Test
method givenANotValidPackageName_whenRevertPackageNameToURL_thenThrows (line 90) | @Test (expected = IllegalArgumentException.class)
method givenAValidPackageNameWithTwoFields_whenRevertPackageNameToURL_thenReturnsTheRevertedPackageNameAsDomainName (line 96) | @Test
method givenAValidPackageNameWithThreeOrMoreFields_whenRevertPackageNameToURL_thenReturnsTheRevertedTwoFieldsOfPackageNameAsDomainNameAndTheRestAsFilePart (line 107) | @Test
FILE: gnr/app/src/test/java/it/necst/grabnrun/PackageNameTrieTest.java
class PackageNameTrieTest (line 13) | @RunWith(MockitoJUnitRunner.class)
method initializePackageNameTrie (line 26) | @Before
method givenNoEntriesForPackageNameWereGenerated_whenGetPackageNameWithAssociatedCertificate_thenReturnsAnAbsentOptional (line 31) | @Test
method givenEntriesForTestPackageNameWereGeneratedButNoPackageNameWasSetToHaveACertificate_whenGetPackageNameWithAssociatedCertificate_thenReturnsAnAbsentOptional (line 41) | @Test
method givenNoEntriesForTestPackageNameWereGeneratedButPackageNameWasSetToHaveACertificate_whenGetPackageNameWithAssociatedCertificate_thenReturnsAnAbsentOptional (line 54) | @Test
method givenEntriesForTestPackageNameWereGeneratedAndTestPackageNameWasSetToHaveACertificate_whenGetPackageNameWithAssociatedCertificate_thenReturnsAnOptionalOfTestPackageName (line 67) | @Test
method givenEntriesForTestPackageNameWereGeneratedAndPrefixOfTestPackageNameWasSetToHaveACertificate_whenGetPackageNameWithAssociatedCertificateWithTestPackageName_thenReturnsAnOptionalOfPrefixOfTestPackageName (line 83) | @Test
method givenEntriesForTestPackageNameWereGeneratedAndTestPackageNameWasSetToHaveACertificate_whenGetPackageNameWithAssociatedCertificateWithPrefixOfTestPackageName_thenReturnsAnAbsentOptional (line 99) | @Test
method givenEntriesForTestPackageNameAndAnotherPackageNameWithNoCommonPrefixWereGeneratedAndPrefixOfTestPackageNameWasSetToHaveACertificate_whenGetPackageNameWithAssociatedCertificateWithTheOtherTestPackageName_thenReturnsAnAbsentOptional (line 113) | @Test
method givenEntriesForTestPackageNameAndAnotherPackageNameWithACommonPrefixWereGeneratedAndPrefixOfTestPackageNameWasSetToHaveACertificate_whenGetPackageNameWithAssociatedCertificateWithTheOtherTestPackageName_thenReturnsAnOptionalOfPrefixOfTestPackageName (line 129) | @Test
FILE: gnr/app/src/test/java/it/necst/grabnrun/SecureDexClassLoaderTest.java
class SecureDexClassLoaderTest (line 57) | @RunWith(RobolectricGradleTestRunner.class)
method setupMocksForSecureDexClassLoader (line 126) | @Before
method givenASecureDexClassLoaderWithAContainerAndACertificateForVerification_whenLoadClassWithAnEmptyClassName_thenThrows (line 166) | @Test (expected = IllegalArgumentException.class)
method givenASecureDexClassLoaderWithAContainerAndNoCertificateForItsPackageNameForVerification_whenLoadClassInTheContainerWithEagerEvaluation_thenRemovesRetrievedContainerAndReturnsNull (line 179) | @Test
method givenASecureDexClassLoaderWithAContainerAndNoCertificateForItsPackageNameForVerification_whenLoadClassInTheContainerWithLazyEvaluation_thenImportsRetrievedContainerButReturnsNull (line 199) | @Test
method givenASecureDexClassLoaderWithARepackedContainerAndACertificateUsedToSignThatContainerForItsPackageNameForVerification_whenLoadClassInTheContainerWithEagerEvaluation_thenRemovesRetrievedContainerAndReturnsNull (line 219) | @Test
method givenASecureDexClassLoaderWithARepackedContainerAndACertificateUsedToSignThatContainerForItsPackageNameForVerification_whenLoadClassInTheContainerWithLazyEvaluation_thenRemovesRetrievedContainerAndReturnsNull (line 237) | @Test
method givenASecureDexClassLoaderWithAContainerAndACertificateNotUsedForSigningTheContainerForItsPackageNameForVerification_whenLoadClassInTheContainerWithEagerEvaluation_thenRemovesRetrievedContainerAndReturnsNull (line 255) | @Test
method givenASecureDexClassLoaderWithAContainerAndACertificateNotUsedForSigningTheContainerForItsPackageNameForVerification_whenLoadClassInTheContainerWithLazyEvaluation_thenRemovesRetrievedContainerAndReturnsNull (line 275) | @Test
method givenASecureDexClassLoaderWithAContainerAndACertificateUsedToSignThatContainerForItsPackageNameForVerification_whenLoadClassNotInTheContainerWithEagerEvaluation_thenImportRetrievedContainerButThrows (line 295) | @Test (expected = ClassNotFoundException.class)
method givenASecureDexClassLoaderWithAContainerAndACertificateUsedToSignThatContainerForItsPackageNameForVerification_whenLoadClassNotInTheContainerWithLazyEvaluation_thenImportRetrievedContainerButThrows (line 312) | @Test (expected = ClassNotFoundException.class)
method givenASecureDexClassLoaderWithAContainerAndACertificateUsedToSignThatContainerForItsPackageNameForVerification_whenLoadClassInTheContainerWithEagerEvaluation_thenImportRetrievedContainerAndReturnsAClassInstance (line 329) | @Test
method givenASecureDexClassLoaderWithAContainerAndACertificateUsedToSignThatContainerForItsPackageNameForVerification_whenLoadClassInTheContainerWithLazyEvaluation_thenImportRetrievedContainerAndReturnsAClassInstance (line 350) | @Test
method givenASecureDexClassLoaderWithAnAPKContainerAndACertificateUsedToSignThatContainerForItsPackageNameForVerification_whenLoadMultipleClassesInTheContainerWhosePackageNameHasTheVerifiedOneAsPrefix_thenReturnsMultipleNotNullClassInstances (line 371) | @Test
method givenASecureDexClassLoaderWithAContainerAndACertificateAssociatedToIt_whenWipeOutPrivateAppCachedDataForNoneContainersAndCertificates_thenAllImportedFilesAreNotErasedAndLoadClassReturnsAClass (line 423) | @Test
method givenASecureDexClassLoaderWithAContainerAndACertificateAssociatedToIt_whenWipeOutPrivateAppCachedDataForContainers_thenAllImportedContainersAreErasedAndLoadClassReturnsNull (line 445) | @Test
method givenASecureDexClassLoaderWithAContainerAndACertificateAssociatedToIt_whenWipeOutPrivateAppCachedDataForCertificates_thenAllImportedCertificatesAreErasedAndLoadClassReturnsNull (line 467) | @Test
method givenASecureDexClassLoaderWithAContainerAndACertificateAssociatedToIt_whenWipeOutPrivateAppCachedDataForBothContainersAndCertificates_thenAllImportedFilesAreErasedAndLoadClassReturnsNull (line 489) | @Test
method initializeSecureDexClassLoaderWithTestValues (line 511) | private SecureDexClassLoader initializeSecureDexClassLoaderWithTestVal...
method downloadRemoteContainerIntoTemporaryImportedContainersFolder (line 525) | private String downloadRemoteContainerIntoTemporaryImportedContainersF...
method retrieveAndGenerateTrustedCertificate (line 531) | private X509Certificate retrieveAndGenerateTrustedCertificate(
method downloadRemoteResourceIntoTemporaryFolder (line 547) | private String downloadRemoteResourceIntoTemporaryFolder(
method assertThatNoFileIsPresentInTheImportedContainersFolderMatchingTheFilter (line 564) | private void assertThatNoFileIsPresentInTheImportedContainersFolderMat...
method assertThatOnlyOneFileIsPresentInTheImportedContainersFolderMatchingTheFilter (line 570) | private void assertThatOnlyOneFileIsPresentInTheImportedContainersFold...
method assertThatNoFileIsPresentInTheImportedCertificateFolderMatchingTheFilter (line 576) | private void assertThatNoFileIsPresentInTheImportedCertificateFolderMa...
method assertThatOnlyOneFileIsPresentInTheImportedCertificateFolderMatchingTheFilter (line 582) | private void assertThatOnlyOneFileIsPresentInTheImportedCertificateFol...
method assertThatFileIsPresentInTheTemporaryFolderMatchingTheFilterInQuantity (line 588) | private void assertThatFileIsPresentInTheTemporaryFolderMatchingTheFil...
FILE: gnr/app/src/test/java/it/necst/grabnrun/SecureLoaderFactoryTest.java
class SecureLoaderFactoryTest (line 44) | @RunWith(RobolectricGradleTestRunner.class)
method setupMocksForSecureLoaderFactory (line 75) | @Before
method givenANonPositiveNumberOfDaysBeforeContainerCacheExpiration_whenCreateSecureLoaderFactory_thenThrows (line 100) | @Test (expected = IllegalArgumentException.class)
method givenAnEmptyDexPath_whenCreateDexClassLoader_thenThrows (line 109) | @Test (expected = IllegalArgumentException.class)
method givenADexPathPointingToARemoteResourceButThePackageNameToCertificateMapIsEmpty_whenCreateDexClassLoader_thenThrows (line 119) | @Test (expected = IllegalArgumentException.class)
method givenADexPathPointingToARemoteResourceAndThePackageNameToCertificateMapContainsPackageNamesAssociatedToNullValues_whenCreateDexClassLoader_thenReturnsASecureDexClassLoaderObject (line 132) | @Test
method givenADexPathPointingToARemoteResourceAndThePackageNameOfTheTargetClassHasACertificate_whenCreateDexClassLoader_thenReturnsASecureDexClassLoaderObject (line 149) | @Test
method givenADexPathPointingToALocalResourceAndThePackageNameOfTheTargetClassHasACertificate_whenCreateDexClassLoader_thenReturnsASecureDexClassLoaderObject (line 162) | @Test
method downloadRemoteContainerIntoTemporaryFolderHoldingALocalContainer (line 179) | private String downloadRemoteContainerIntoTemporaryFolderHoldingALocal...
FILE: gnr/app/src/test/java/it/necst/grabnrun/shadows/BaseDexClassLoaderShadow.java
class BaseDexClassLoaderShadow (line 10) | @Implements(BaseDexClassLoader.class)
method __constructor__ (line 18) | public void __constructor__(
FILE: gnr/app/src/test/java/it/necst/grabnrun/shadows/DexFileShadow.java
class DexFileShadow (line 11) | @Implements(DexFile.class)
method setDexFileShadow (line 15) | public static void setDexFileShadow(DexFile dexFile) {
method loadDex (line 19) | @Implementation
method entries (line 24) | @Implementation
FILE: repackPOC/RepackInputSelector/src/it/necst/grabnrun/selector/LinkContainerDialog.java
class LinkContainerDialog (line 39) | public class LinkContainerDialog extends Dialog {
method LinkContainerDialog (line 64) | public LinkContainerDialog( Frame owner,
method validateInput (line 226) | private void validateInput() {
method saveAndFinish (line 388) | private void saveAndFinish(Map<String, String> keyToCertificateURLMap,
method finish (line 441) | private void finish(boolean isCorrectTermination) {
method isValidRemoteCertURL (line 454) | private boolean isValidRemoteCertURL(String candidateURLString) {
method isValidPackageName (line 477) | private boolean isValidPackageName(String candidatePackNameString) {
FILE: repackPOC/RepackInputSelector/src/it/necst/grabnrun/selector/MainFrame.java
class MainFrame (line 28) | public class MainFrame extends Frame {
method main (line 50) | public static void main(String[] args) {
method MainFrame (line 56) | private MainFrame() {
method buildContent (line 76) | private void buildContent() {
method updateContainerBoxes (line 179) | private void updateContainerBoxes(Integer boxToShow) {
method apkChoose (line 211) | private void apkChoose() {
method next (line 250) | private void next() {
method quit (line 310) | private void quit() {
FILE: repackPOC/repackagingTool.py
function isAValidContainer (line 57) | def isAValidContainer(containerPath, onlyAPKallowed = False):
function isARemoteURL (line 90) | def isARemoteURL(candidateRemoteURL, onlyHTTPSrequired = False):
function isAValidPackageName (line 104) | def isAValidPackageName(candidatePackageName):
function downloadRemoteContainer (line 122) | def downloadRemoteContainer(containerRemoteURL):
function extractPackageNamesFromLocalContainer (line 148) | def extractPackageNamesFromLocalContainer(containerPath):
function computeDigestEncode (line 217) | def computeDigestEncode(filePath):
function decodeTargetAPK (line 238) | def decodeTargetAPK(apkPath):
function buildRepackagedAPK (line 264) | def buildRepackagedAPK(decodeDirName):
function performAnalysis (line 285) | def performAnalysis(apkPath):
function addMissingPermsToAndroidManifest (line 380) | def addMissingPermsToAndroidManifest(decodeDirName, missingPerms):
function addBlankPadding (line 414) | def addBlankPadding(line):
function patchSmaliClasses (line 423) | def patchSmaliClasses(decodeDirName, classesWithDynCodeLoad):
function setUpRepackHandler (line 599) | def setUpRepackHandler(decodeDirName, hasStaticAssociativeMap, entriesDi...
function makeOneWriteIteration (line 719) | def makeOneWriteIteration(repackHandlerFile, needToReinitializePackageNa...
function reinitializeSet (line 747) | def reinitializeSet(repackHandlerFile):
function insertPackageNameInSet (line 756) | def insertPackageNameInSet(repackHandlerFile, packageName):
function linkContainerToCurrentPackageNameSet (line 763) | def linkContainerToCurrentPackageNameSet(repackHandlerFile, container):
function linkPackageNameToCertURL (line 771) | def linkPackageNameToCertURL(repackHandlerFile, packageName, certificate...
function setHasStaticAssociativeMapBool (line 780) | def setHasStaticAssociativeMapBool(repackHandlerFile, boolValue):
function main (line 789) | def main(argv):
Condensed preview — 145 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (990K chars).
[
{
"path": ".gitmodules",
"chars": 116,
"preview": "[submodule \"repackPOC/androguard\"]\n\tpath = repackPOC/androguard\n\turl = https://github.com/androguard/androguard.git\n"
},
{
"path": "COPYRIGHT",
"chars": 552,
"preview": "Copyright 2014 Luca Falsina\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file e"
},
{
"path": "README.md",
"chars": 14255,
"preview": "# \r\n\r"
},
{
"path": "docs/.gitignore",
"chars": 28,
"preview": "/_build/\n/javaAPI/\nmake.bat\n"
},
{
"path": "docs/.placeholder",
"chars": 0,
"preview": ""
},
{
"path": "docs/Makefile",
"chars": 6782,
"preview": "# Makefile for Sphinx documentation\n#\n\n# You can set these variables from the command line.\nSPHINXOPTS =\nSPHINXBUILD "
},
{
"path": "docs/complementary.rst",
"chars": 34325,
"preview": "Complementary topics\n====================\n\nIn the end of this documentation a couple of not so trivial use cases of *Gra"
},
{
"path": "docs/conf.py",
"chars": 8401,
"preview": "# -*- coding: utf-8 -*-\n#\n# docgrabnrun documentation build configuration file, created by\n# sphinx-quickstart on Tue Se"
},
{
"path": "docs/example.rst",
"chars": 19678,
"preview": "Discussion of an example project\n================================\n\nBefore digging into this section, you are **strongly*"
},
{
"path": "docs/index.rst",
"chars": 1887,
"preview": ".. docgrabnrun documentation master file, created by\n sphinx-quickstart on Tue Sep 23 09:59:33 2014.\n You can adapt "
},
{
"path": "docs/javaDoc/allclasses-frame.html",
"chars": 763,
"preview": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n"
},
{
"path": "docs/javaDoc/allclasses-noframe.html",
"chars": 723,
"preview": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n"
},
{
"path": "docs/javaDoc/constant-values.html",
"chars": 4498,
"preview": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n"
},
{
"path": "docs/javaDoc/deprecated-list.html",
"chars": 3318,
"preview": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n"
},
{
"path": "docs/javaDoc/help-doc.html",
"chars": 8274,
"preview": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n"
},
{
"path": "docs/javaDoc/index-files/index-1.html",
"chars": 5432,
"preview": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n"
},
{
"path": "docs/javaDoc/index-files/index-2.html",
"chars": 4483,
"preview": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n"
},
{
"path": "docs/javaDoc/index-files/index-3.html",
"chars": 3974,
"preview": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n"
},
{
"path": "docs/javaDoc/index-files/index-4.html",
"chars": 4160,
"preview": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n"
},
{
"path": "docs/javaDoc/index-files/index-5.html",
"chars": 6082,
"preview": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n"
},
{
"path": "docs/javaDoc/index-files/index-6.html",
"chars": 4492,
"preview": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n"
},
{
"path": "docs/javaDoc/index.html",
"chars": 2723,
"preview": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Frameset//EN\" \"http://www.w3.org/TR/html4/frameset.dtd\">\n<!-- NewPage -->\n<"
},
{
"path": "docs/javaDoc/it/necst/grabnrun/SecureDexClassLoader.html",
"chars": 15723,
"preview": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n"
},
{
"path": "docs/javaDoc/it/necst/grabnrun/SecureLoaderFactory.html",
"chars": 28244,
"preview": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n"
},
{
"path": "docs/javaDoc/it/necst/grabnrun/class-use/SecureDexClassLoader.html",
"chars": 8656,
"preview": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n"
},
{
"path": "docs/javaDoc/it/necst/grabnrun/class-use/SecureLoaderFactory.html",
"chars": 4049,
"preview": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n"
},
{
"path": "docs/javaDoc/it/necst/grabnrun/package-frame.html",
"chars": 879,
"preview": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n"
},
{
"path": "docs/javaDoc/it/necst/grabnrun/package-summary.html",
"chars": 4941,
"preview": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n"
},
{
"path": "docs/javaDoc/it/necst/grabnrun/package-tree.html",
"chars": 4150,
"preview": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n"
},
{
"path": "docs/javaDoc/it/necst/grabnrun/package-use.html",
"chars": 4707,
"preview": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n"
},
{
"path": "docs/javaDoc/overview-tree.html",
"chars": 4090,
"preview": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n"
},
{
"path": "docs/javaDoc/package-list",
"chars": 18,
"preview": "it.necst.grabnrun\n"
},
{
"path": "docs/javaDoc/stylesheet.css",
"chars": 11139,
"preview": "/* Javadoc style sheet */\n/*\nOverall document style\n*/\nbody {\n background-color:#ffffff;\n color:#353833;\n font-"
},
{
"path": "docs/repackaging.rst",
"chars": 7225,
"preview": "\nRepackaging tool\n================\n\nIn this section you will learn how to configure and use the repackaging tool to have"
},
{
"path": "docs/security.rst",
"chars": 6277,
"preview": "Why should I use Grab'n Run?\n============================\n\nA significant question that every developer faces every time "
},
{
"path": "docs/tutorial.rst",
"chars": 21284,
"preview": "\nQuick start and tutorial\n========================\n\nIn this section you will see how to *retrieve and include Grab'n Run"
},
{
"path": "downloads/1.0/gnr-1.0.jar.sha1",
"chars": 54,
"preview": "26de8ca9e32987d5d5094c432ad7480b09b134b4 gnr-1.0.jar\n"
},
{
"path": "downloads/1.0.1/gnr-1.0.1.aar.sha1",
"chars": 56,
"preview": "10e18e6c5e14ebfbb075a746334d1722040c59f6 gnr-1.0.1.aar\n"
},
{
"path": "downloads/1.0.1/gnr-1.0.1.jar.sha1",
"chars": 56,
"preview": "c56ebdfc50ae227aa85f0aaf2d4559dadce076e3 gnr-1.0.1.jar\n"
},
{
"path": "downloads/1.0.2/gnr-1.0.2.aar.sha1",
"chars": 56,
"preview": "2d1d9bc079ae9908ce1f7b8c826ee8f0657aa40b gnr-1.0.2.aar\n"
},
{
"path": "downloads/1.0.2/gnr-1.0.2.jar.sha1",
"chars": 56,
"preview": "330385bd0e67a8b0b83048577d995c916aae7de2 gnr-1.0.2.jar\n"
},
{
"path": "downloads/1.0.3/grabnrun-1.0.3.aar.sha1",
"chars": 40,
"preview": "b6b10ea1c67856374830a07080a02dcbe973ba6d"
},
{
"path": "downloads/1.0.3/grabnrun-1.0.3.jar.sha1",
"chars": 61,
"preview": "8802180428e8783339a77484bfa45a74021c5b54 grabnrun-1.0.3.jar\n"
},
{
"path": "downloads/1.0.4/grabnrun-1.0.4.aar.sha1",
"chars": 40,
"preview": "cc06e36eeb7104b5cc0fa555c668990b027bf53a"
},
{
"path": "downloads/1.0.4/grabnrun-1.0.4.jar.sha1",
"chars": 61,
"preview": "9e849b9adbf0ca3c48ac8d71704753a885a8ede2 grabnrun-1.0.4.jar\n"
},
{
"path": "example/ADT/.classpath",
"chars": 482,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<classpath>\n\t<classpathentry exported=\"true\" kind=\"con\" path=\"com.android.ide.ecl"
},
{
"path": "example/ADT/.gitignore",
"chars": 24,
"preview": "/.settings/\n/bin/\n/gen/\n"
},
{
"path": "example/ADT/.project",
"chars": 816,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<projectDescription>\n\t<name>ExampleAppGNR</name>\n\t<comment></comment>\n\t<projects>"
},
{
"path": "example/ADT/AndroidManifest.xml",
"chars": 1615,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n package="
},
{
"path": "example/ADT/lint.xml",
"chars": 53,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<lint>\n</lint>"
},
{
"path": "example/ADT/proguard-project.txt",
"chars": 781,
"preview": "# To enable ProGuard in your project, edit project.properties\n# to define the proguard.config property as described in t"
},
{
"path": "example/ADT/project.properties",
"chars": 585,
"preview": "# This file is automatically generated by Android Tools.\n# Do not modify this file -- YOUR CHANGES WILL BE ERASED!\n#\n# T"
},
{
"path": "example/ADT/res/layout/activity_dex_class_sample.xml",
"chars": 1883,
"preview": "<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:tools=\"http://schemas.android.com/too"
},
{
"path": "example/ADT/res/layout/activity_main.xml",
"chars": 729,
"preview": "<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:tools=\"http://schemas.android.com/too"
},
{
"path": "example/ADT/res/values/strings.xml",
"chars": 923,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n\n <string name=\"app_name\">Dynamic Code Loading Techniques</string>"
},
{
"path": "example/ADT/src/it/polimi/poccodeloading/ComponentModifier.java",
"chars": 1259,
"preview": "/*******************************************************************************\n * Copyright 2014 Luca Falsina\n *\n * Li"
},
{
"path": "example/ADT/src/it/polimi/poccodeloading/DexClassSampleActivity.java",
"chars": 12744,
"preview": "/*******************************************************************************\n * Copyright 2014 Luca Falsina\n *\n * Li"
},
{
"path": "example/ADT/src/it/polimi/poccodeloading/MainActivity.java",
"chars": 20817,
"preview": "/*******************************************************************************\n * Copyright 2014 Luca Falsina\n *\n * Li"
},
{
"path": "example/AS/.gitignore",
"chars": 139,
"preview": ".gradle/\napp/build/\nbuild/\nimport-summary.txt\nlocal.properties\n\n## Directory-based project format:\n.idea/\n\n## IntelliJ c"
},
{
"path": "example/AS/app/build.gradle",
"chars": 536,
"preview": "apply plugin: 'com.android.application'\n\nandroid {\n compileSdkVersion 23\n buildToolsVersion \"23.0.2\"\n\n defaultC"
},
{
"path": "example/AS/app/lint.xml",
"chars": 53,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<lint>\n</lint>"
},
{
"path": "example/AS/app/src/main/AndroidManifest.xml",
"chars": 1948,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n package="
},
{
"path": "example/AS/app/src/main/java/it/polimi/poccodeloading/ComponentModifier.java",
"chars": 1235,
"preview": "/*******************************************************************************\n * Copyright 2014 Luca Falsina\n *\n * Li"
},
{
"path": "example/AS/app/src/main/java/it/polimi/poccodeloading/DexClassSampleActivity.java",
"chars": 12705,
"preview": "/*******************************************************************************\n * Copyright 2014 Luca Falsina\n *\n * Li"
},
{
"path": "example/AS/app/src/main/java/it/polimi/poccodeloading/MainActivity.java",
"chars": 22537,
"preview": "/*******************************************************************************\n * Copyright 2014 Luca Falsina\n *\n * Li"
},
{
"path": "example/AS/app/src/main/res/layout/activity_dex_class_sample.xml",
"chars": 1883,
"preview": "<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:tools=\"http://schemas.android.com/too"
},
{
"path": "example/AS/app/src/main/res/layout/activity_main.xml",
"chars": 729,
"preview": "<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:tools=\"http://schemas.android.com/too"
},
{
"path": "example/AS/app/src/main/res/values/strings.xml",
"chars": 1013,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n\n <string name=\"app_name\">Dynamic Code Loading Techniques</string>"
},
{
"path": "example/AS/build.gradle",
"chars": 301,
"preview": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\nbuildscript {\n re"
},
{
"path": "example/AS/gradle/wrapper/gradle-wrapper.properties",
"chars": 232,
"preview": "#Wed Apr 10 15:27:10 PDT 2013\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_"
},
{
"path": "example/AS/gradlew",
"chars": 5080,
"preview": "#!/usr/bin/env bash\n\n##############################################################################\n##\n## Gradle start "
},
{
"path": "example/AS/gradlew.bat",
"chars": 2404,
"preview": "@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@r"
},
{
"path": "example/AS/settings.gradle",
"chars": 15,
"preview": "include ':app'\n"
},
{
"path": "gnr/.gitignore",
"chars": 151,
"preview": "/app/build/\n/build/\n/import-summary.txt\n.gradle\n/local.properties\n.DS_Store\n\n## Directory-based project format:\n.idea/\n\n"
},
{
"path": "gnr/app/build.gradle",
"chars": 3234,
"preview": "apply plugin: 'com.android.library'\napply plugin: 'maven'\n\next {\n PUBLISH_GROUP_ID = 'it.necst.grabnrun'\n PUBLISH_"
},
{
"path": "gnr/app/lint.xml",
"chars": 53,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<lint>\n</lint>"
},
{
"path": "gnr/app/proguard-project.txt",
"chars": 950,
"preview": "# To enable ProGuard in your project, edit project.properties\n# to define the proguard.config property as described in t"
},
{
"path": "gnr/app/src/main/AndroidManifest.xml",
"chars": 435,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n package="
},
{
"path": "gnr/app/src/main/java/it/necst/grabnrun/CacheLogger.java",
"chars": 11409,
"preview": "/*******************************************************************************\n * Copyright 2014 Luca Falsina\n *\n * Li"
},
{
"path": "gnr/app/src/main/java/it/necst/grabnrun/CertificateFileFilterByNameMatch.java",
"chars": 1817,
"preview": "/*******************************************************************************\n * Copyright 2014 Luca Falsina\n *\n * Li"
},
{
"path": "gnr/app/src/main/java/it/necst/grabnrun/ContainerSignatureVerifier.java",
"chars": 11134,
"preview": "package it.necst.grabnrun;\n\nimport static com.google.common.base.Preconditions.checkArgument;\nimport static com.google.c"
},
{
"path": "gnr/app/src/main/java/it/necst/grabnrun/DexPathStringProcessor.java",
"chars": 2583,
"preview": "package it.necst.grabnrun;\n\nimport static com.google.common.base.Preconditions.checkArgument;\nimport static com.google.c"
},
{
"path": "gnr/app/src/main/java/it/necst/grabnrun/FileDownloader.java",
"chars": 10678,
"preview": "/*******************************************************************************\n * Copyright 2014 Luca Falsina\n *\n * Li"
},
{
"path": "gnr/app/src/main/java/it/necst/grabnrun/FileFilterByNameMatch.java",
"chars": 2639,
"preview": "/*******************************************************************************\n * Copyright 2014 Luca Falsina\n *\n * Li"
},
{
"path": "gnr/app/src/main/java/it/necst/grabnrun/FileHelper.java",
"chars": 2935,
"preview": "package it.necst.grabnrun;\n\nimport static com.google.common.base.Preconditions.checkArgument;\nimport static com.google.c"
},
{
"path": "gnr/app/src/main/java/it/necst/grabnrun/PackageNameHelper.java",
"chars": 2519,
"preview": "package it.necst.grabnrun;\n\nimport static com.google.common.base.Preconditions.checkArgument;\nimport static com.google.c"
},
{
"path": "gnr/app/src/main/java/it/necst/grabnrun/PackageNameTrie.java",
"chars": 6097,
"preview": "/*******************************************************************************\n * Copyright 2014 Luca Falsina\n *\n * Li"
},
{
"path": "gnr/app/src/main/java/it/necst/grabnrun/SecureDexClassLoader.java",
"chars": 43379,
"preview": "/*******************************************************************************\n * Copyright 2014 Luca Falsina\n *\n * Li"
},
{
"path": "gnr/app/src/main/java/it/necst/grabnrun/SecureLoaderFactory.java",
"chars": 33177,
"preview": "/*******************************************************************************\n * Copyright 2014 Luca Falsina\n *\n * Li"
},
{
"path": "gnr/app/src/main/res/values-v11/styles.xml",
"chars": 321,
"preview": "<resources>\n\n <!--\n Base application theme for API 11+. This theme completely replaces\n AppBaseTheme fr"
},
{
"path": "gnr/app/src/main/res/values-v14/styles.xml",
"chars": 378,
"preview": "<resources>\n\n <!--\n Base application theme for API 14+. This theme completely replaces\n AppBaseTheme fr"
},
{
"path": "gnr/app/src/test/java/it/necst/grabnrun/CacheLoggerTest.java",
"chars": 5756,
"preview": "package it.necst.grabnrun;\n\nimport static org.hamcrest.MatcherAssert.assertThat;\nimport static org.hamcrest.Matchers.equ"
},
{
"path": "gnr/app/src/test/java/it/necst/grabnrun/CertificateFileFilterByNameMatchTest.java",
"chars": 3329,
"preview": "package it.necst.grabnrun;\n\nimport static it.necst.grabnrun.CertificateFileFilterByNameMatch.PEM_EXTENSION;\nimport stati"
},
{
"path": "gnr/app/src/test/java/it/necst/grabnrun/ContainerSignatureVerifierTest.java",
"chars": 7980,
"preview": "package it.necst.grabnrun;\n\nimport static android.content.Context.CONNECTIVITY_SERVICE;\nimport static it.necst.grabnrun."
},
{
"path": "gnr/app/src/test/java/it/necst/grabnrun/DexPathStringProcessorTest.java",
"chars": 6056,
"preview": "package it.necst.grabnrun;\n\nimport static junit.framework.Assert.assertFalse;\nimport static junit.framework.Assert.asser"
},
{
"path": "gnr/app/src/test/java/it/necst/grabnrun/FileDownloaderTest.java",
"chars": 8172,
"preview": "package it.necst.grabnrun;\n\nimport static org.hamcrest.CoreMatchers.equalTo;\nimport static org.junit.Assert.assertFalse;"
},
{
"path": "gnr/app/src/test/java/it/necst/grabnrun/FileFilterByNameMatchTest.java",
"chars": 3923,
"preview": "package it.necst.grabnrun;\n\nimport static org.junit.Assert.assertFalse;\nimport static org.junit.Assert.assertTrue;\nimpor"
},
{
"path": "gnr/app/src/test/java/it/necst/grabnrun/FileHelperTest.java",
"chars": 11307,
"preview": "package it.necst.grabnrun;\n\nimport static it.necst.grabnrun.FileHelper.endsWithJarOrApkExtension;\nimport static it.necst"
},
{
"path": "gnr/app/src/test/java/it/necst/grabnrun/PackageNameHelperTest.java",
"chars": 4493,
"preview": "package it.necst.grabnrun;\n\nimport static it.necst.grabnrun.PackageNameHelper.isAValidPackageName;\nimport static it.necs"
},
{
"path": "gnr/app/src/test/java/it/necst/grabnrun/PackageNameTrieTest.java",
"chars": 6852,
"preview": "package it.necst.grabnrun;\n\nimport static org.hamcrest.MatcherAssert.assertThat;\nimport static org.hamcrest.Matchers.equ"
},
{
"path": "gnr/app/src/test/java/it/necst/grabnrun/SecureDexClassLoaderTest.java",
"chars": 31250,
"preview": "package it.necst.grabnrun;\n\nimport static android.content.Context.CONNECTIVITY_SERVICE;\nimport static android.content.Co"
},
{
"path": "gnr/app/src/test/java/it/necst/grabnrun/SecureLoaderFactoryTest.java",
"chars": 8385,
"preview": "package it.necst.grabnrun;\n\nimport static android.content.Context.CONNECTIVITY_SERVICE;\nimport static android.content.Co"
},
{
"path": "gnr/app/src/test/java/it/necst/grabnrun/shadows/BaseDexClassLoaderShadow.java",
"chars": 739,
"preview": "package it.necst.grabnrun.shadows;\n\nimport org.robolectric.annotation.Implements;\nimport org.robolectric.internal.Shadow"
},
{
"path": "gnr/app/src/test/java/it/necst/grabnrun/shadows/DexFileShadow.java",
"chars": 691,
"preview": "package it.necst.grabnrun.shadows;\n\nimport org.robolectric.annotation.Implementation;\nimport org.robolectric.annotation."
},
{
"path": "gnr/build.gradle",
"chars": 324,
"preview": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\nbuildscript {\n re"
},
{
"path": "gnr/gradle/wrapper/gradle-wrapper.properties",
"chars": 232,
"preview": "#Wed Apr 10 15:27:10 PDT 2013\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_"
},
{
"path": "gnr/gradle-app.setting",
"chars": 977,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<root>\n <setting name=\"task-tab\">\n <setting name=\"show-description\" value=\"t"
},
{
"path": "gnr/gradlew",
"chars": 5080,
"preview": "#!/usr/bin/env bash\n\n##############################################################################\n##\n## Gradle start "
},
{
"path": "gnr/gradlew.bat",
"chars": 2404,
"preview": "@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@r"
},
{
"path": "gnr/settings.gradle",
"chars": 15,
"preview": "include ':app'\n"
},
{
"path": "grabandrun.bib",
"chars": 426,
"preview": "@InProceedings{falsina15:grabandrun,\n author = {Luca Falsina and Yanick Fratantonio and Stefano Zanero and Christopher "
},
{
"path": "repackPOC/.gitignore",
"chars": 54,
"preview": "/previousExperiments/\n/RepackInputSelector/.gitignore\n"
},
{
"path": "repackPOC/RepackInputSelector/.classpath",
"chars": 226,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<classpath>\n\t<classpathentry kind=\"src\" path=\"src\"/>\n\t<classpathentry kind=\"con\" "
},
{
"path": "repackPOC/RepackInputSelector/.project",
"chars": 378,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<projectDescription>\n\t<name>RepackInputSelector</name>\n\t<comment></comment>\n\t<pro"
},
{
"path": "repackPOC/RepackInputSelector/src/it/necst/grabnrun/selector/LinkContainerDialog.java",
"chars": 17428,
"preview": "package it.necst.grabnrun.selector;\n\nimport java.awt.BorderLayout;\nimport java.awt.Button;\nimport java.awt.CardLayout;\ni"
},
{
"path": "repackPOC/RepackInputSelector/src/it/necst/grabnrun/selector/MainFrame.java",
"chars": 8742,
"preview": "package it.necst.grabnrun.selector;\n\nimport java.awt.BorderLayout;\nimport java.awt.Button;\nimport java.awt.Choice;\nimpor"
},
{
"path": "repackPOC/repackagingTool.py",
"chars": 33252,
"preview": "import sys, argparse, shutil, os\n\n# This variable matches the local folder in the repo \n# where the submodule of Androgu"
},
{
"path": "repackPOC/requirements.txt",
"chars": 700,
"preview": "# Required modules you will need on your machine in order to run\n# 'Grab'n Run repackaging tool\".\n# Type in a terminal t"
},
{
"path": "repackPOC/smaliRes/grabnrun/CacheLogger.smali",
"chars": 21816,
"preview": ".class final Lit/necst/grabnrun/CacheLogger;\n.super Ljava/lang/Object;\n.source \"CacheLogger.java\"\n\n\n# static fields\n.fie"
},
{
"path": "repackPOC/smaliRes/grabnrun/CertFileFilter.smali",
"chars": 2576,
"preview": ".class final Lit/necst/grabnrun/CertFileFilter;\n.super Ljava/lang/Object;\n.source \"CertFileFilter.java\"\n\n# interfaces\n.i"
},
{
"path": "repackPOC/smaliRes/grabnrun/FileDownloader$1.smali",
"chars": 18797,
"preview": ".class Lit/necst/grabnrun/FileDownloader$1;\n.super Ljava/lang/Thread;\n.source \"FileDownloader.java\"\n\n\n# annotations\n.ann"
},
{
"path": "repackPOC/smaliRes/grabnrun/FileDownloader.smali",
"chars": 6197,
"preview": ".class final Lit/necst/grabnrun/FileDownloader;\n.super Ljava/lang/Object;\n.source \"FileDownloader.java\"\n\n\n# static field"
},
{
"path": "repackPOC/smaliRes/grabnrun/FileFilterByName.smali",
"chars": 2197,
"preview": ".class final Lit/necst/grabnrun/FileFilterByName;\n.super Ljava/lang/Object;\n.source \"FileFilterByName.java\"\n\n# interface"
},
{
"path": "repackPOC/smaliRes/grabnrun/PackageNameTrie.smali",
"chars": 8208,
"preview": ".class final Lit/necst/grabnrun/PackageNameTrie;\n.super Ljava/lang/Object;\n.source \"PackageNameTrie.java\"\n\n\n# static fie"
},
{
"path": "repackPOC/smaliRes/grabnrun/RepackHandler.smali",
"chars": 36711,
"preview": ".class public Lit/necst/grabnrun/RepackHandler;\n.super Ljava/lang/Object;\n.source \"RepackHandler.java\"\n\n\n# static fields"
},
{
"path": "repackPOC/smaliRes/grabnrun/RepackHandlerTail.smali",
"chars": 3585,
"preview": " sput-boolean v2, Lit/necst/grabnrun/RepackHandler;->hasStaticAssociativeMap:Z\n\n .line 160\n :try_start_0\n co"
},
{
"path": "repackPOC/smaliRes/grabnrun/SecureDexClassLoader$SignatureVerificationTask.smali",
"chars": 4872,
"preview": ".class Lit/necst/grabnrun/SecureDexClassLoader$SignatureVerificationTask;\n.super Ljava/lang/Object;\n.source \"SecureDexCl"
},
{
"path": "repackPOC/smaliRes/grabnrun/SecureDexClassLoader.smali",
"chars": 111376,
"preview": ".class public Lit/necst/grabnrun/SecureDexClassLoader;\n.super Ljava/lang/Object;\n.source \"SecureDexClassLoader.java\"\n\n\n#"
},
{
"path": "repackPOC/smaliRes/grabnrun/SecureLoaderFactory.smali",
"chars": 62905,
"preview": ".class public Lit/necst/grabnrun/SecureLoaderFactory;\n.super Ljava/lang/Object;\n.source \"SecureLoaderFactory.java\"\n\n\n# s"
}
]
// ... and 16 more files (download for full content)
About this extraction
This page contains the full source code of the lukeFalsina/Grab-n-Run GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 145 files (910.8 KB), approximately 245.9k tokens, and a symbol index with 297 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.