1 Introduction
-
PREV, a fully automated framework for detecting permission re-delegation vulnerabilities in Android apps, based on static analysis, natural language processing, machine learning, and genetic algorithm.
-
A publicly-available implementation of PREV and dataset.2
-
A large-scale empirical assessment, in which 11,796 apps were analyzed for learning the permission re-delegation models, and 1,258 real world apps were analyzed to detect permission re-delegation vulnerabilities.
-
A comprehensive comparison with static analysis tools in terms of precision and recall.
2 Background
2.1 Android Design
<activity>
) — with an intent filter (tag <intent-filter>
). Activity DialerActivity can be requested by other apps to initiate a phone call, for example, when a link with phone number (e.g., href="tel:+ 1234") is clicked within a web page, the browser sends an intent containing the DIAL
action, the DEFAULT
category and phone number to this app.DIAL
as the action and the scheme and number to call as the data, e.g., tel:+ 39.0461.314.577
. As this intent matches the intent-filter in Fig. 1, the request is dispatched to the corresponding DialerActivity activity. This activity in our running example app becomes active and is displayed on the screen to initiate the phone call.2.2 Genetic Algorithm
3 Motivating Example
3.1 Attack Scenario
CALL_PHONE
for initiating phone call. An intent-filter is defined to allow other apps to request a phone call via this app. When A sends an intent message to D, D extracts the destination phone number from the message and requests a confirmation from the end-user. After the end-user confirms to call the destination number, the app initiates a call.onCreate
method in Fig. 5. Figure 5 shows the intent handling snippet of the Dialer app. The code starts by getting the intent sent to the app (Line 1). If the action in the intent is DIAL
, the app extracts the data from the intent (Lines 2-4). The data contains the scheme
and the phone number. If the scheme
is “tel”, the Dialer app then extracts the number associated to this scheme
(Lines 7-8). Then depending on the number, that is, if the number starts with * or #, the app directly performs a configuration related task (e.g., getting serial number of the phone if the number is *#06#) without asking for end-user confirmation; otherwise the app initiates a phone call.
DIAL
and data tel:⋆#060#
, D performs the specified task without the user interaction. In essence, D performed a privileged operation on behalf of A based on the data controlled by A without any user interaction.MODIFY_PHONE_STATE
or READ_PHONE_STATE
permission.3.2 Vulnerability Preconditions
DevicePolicyManager.wipeData(0)
, which requires the BIND_DEVICE_ADMIN
permission.makePhoneCall()
) when requested by other app is an intended behavior of the Dialer app.4 Overview of the Approach
5 Model Inference
5.1 Clustering
5.2 API Reachability Analysis
onCreate()
for Activities and onReceive()
for Broadcast Receivers) as entry points. The sample manifest in Fig. 1 defines a single public interface — DialerActivity, because it defines the tag <intent-filter>
without specifying the exported attribute (if a component specifies an intent-filter, by default the exported attribute is set to true
). Our approach parses the manifest file using XOM,10 an open source library to parse XML files. Intent-filters are extracted using XPath queries.5.3 Learning the Model
openConnection()
and connect()
have the value 1 or the value close to 1 since the APIs are frequently used while the third and the fourth elements corresponding to the APIs sendTextMessage()
and setWifiEnabled()
are close to the value 0 because the APIs are uncommon.openConnection()
is 1 and of connect()
is 0.75; so the use of these APIs when servicing action requests is common and thus, considered as legitimate. On the other hand, the frequency of both sendTextMessage()
and SetWifiEnabled()
is 0.25, which is less than tcomApi; so they are considered as APIs uncommonly subject to permission re-delegation.6 Outlier Detection
6.1 Cluster Assignment
6.2 API Reachability Analysis
6.3 Anomalies Identification
openConnection
and connect
are reachable from public entry points in the code of AUTa. Similarly, the third and fourth elements of xaut,b are set to 1 because calls to APIs sendTextMessage
and setWifiEnabled
are reachable in the app code. This corresponds to computing new rows of the matrix M as discussed in Section 5.3 (see Fig. 8).
sendTextMessage
and setWifiEnabled
are not commonly executed in its cluster because tcomApi = 0.5 and \(\widetilde {m}[3]=0.25\) and \(\widetilde {m}[4]=0.25\) (Fig. 11). Therefore, the sendTextMessage
and setWifiEnabled
APIs satisfy the second condition. These two APIs are exposed by our outlier app AUTb. As shown in Fig. 11, xaut,b[3] = xaut,b[4] = 1. Therefore, they also satisfy the third condition and are reported as anomalous privileged APIs.7 Test Case Generation
7.1 Path Extraction
onClick(), onTouch()
and Android Material Design Library functions (UI-related functions). Our tool detects paths that include a call to a function from this list and discards them. The remaining paths (denoted as target paths) are subject to testing next.7.2 Genetic Algorithm
Field | Description | Example |
---|---|---|
$action | a string representing the action to be performed | SMS , CALL , VIEW , EDIT , ... |
$category | additional information about the action to perform | DEFAULT , BROWSABLE |
$extra | a (possibly empty) set of key-value pairs (not specified in the manifest file) | “ wifi_state ”→“1 ”, “volume ” →10 |
$scheme | a value that expresses the format of the next $data field | http or tel |
$data | URI that references the data | http://se.fbk.eu:80/people/pro - |
to be used; e.g., the file to be | file/ceccato | |
opened, the number to dial or the contact to access. Depending on the $scheme, this field is composed of different subfields | tel:+ 39.0461.314.577 | |
If $scheme is http , $data represents a URL with these subfields: | ||
$scheme | the prefix of the URI | http , https , ftp , sftp , file , |
$host | the string corresponding to host name | content se.fbk.eu |
$port | the (optional) number corresponding to the port to use | 80 |
$path | The path part of a URI to locate the corresponding resource | people/profile/ceccato |
$pathPattern | Regular expression that the path should match | /specialdirctory.⋆/ |
If $scheme is telephony-related, $data represents a number to call/text with these subfields: | ||
$scheme | the prefix of the URL | tel , sms , smsto , voicemail , mms , |
mmsto | ||
$uri | the number/code to dial or to text to | + 39.0461.314.577 |
getIntent().getAction().equals
(ACTION)) in the corresponding component code. The technique is simplified because, for scalability reasons, we do not track the propagation of string constants through string operations such as substring()
. Code scanning is applied to extract the string constants (such as static strings) from the component code.DIAL
in Fig. 1). If no action is specified in the manifest file, its seed values are assigned with the string constants extracted from the corresponding component code (as explained above for example from getIntent(). getAction().equals
(ACTION)). Eventually, if this strategy also fails, seed values are taken from the set of all the constant strings that are statically available in the component,13 in the hope of choosing a string value that is (possibly indirectly) compared to the Action when processing an Intent.getIntent(). hasCategory
("Browsable")). If no such value is available, similarly to the $action field, string values from the constant pool of the current component are used as seed values. For instance, we used values from declarations like String value = "Browsable";
.getIntent().getIntExtra("id")
, id
is extracted as a key). Simplified constant propagation is used if the key parameter in the method call is a constant. The data type of the value is identified based on method signature (e.g., integer for getIntExtra
). Default values for those keys are sometimes available as parameters, e.g., in getIntent().getIntExtra("id", -1)
, -1 is a default value for id
. If a default value is available, it is extracted as a seed value for the corresponding key. If no default value is found after static analysis of the component code, the seed values for a given key are assigned with the constants of the same data type extracted through scanning of the component code. The key is also annotated with its data type.tel
in Fig. 1). The value of this field defines the format of $data field (explained next). We support 15 different $scheme s that are grouped into two classes: for resources such as network and contacts (e.g., "http", "file", "content"
) and for telephony (e.g., "tel","sms","mms"
). Custom $scheme s (e.g., "fb"
for Facebook) are also supported, when they are specified in the manifest file.⋆
) and a period followed by an asterisk (.⋆
). The Android framework uses PatternMatcher, a simple pattern matcher that is safe to use on untrusted data and does not provide full regex support. According to the documentation,14 an asterisk (⋆
) matches a sequence of 0 to many occurrences of the immediately preceding character, while a period followed by an asterisk (.⋆
) matches any sequence of 0 to many characters. The seed value for this field is, thus, generated as the shortest string accepted by the regex. For example, given a pathPattern “/movies.⋆/
”, a string “/movies/
” is generated which will be later concatenated to a URL (e.g., https://example.com/movies/).NULL
value in its seed values. All the extracted fields and their seed values are then stored in a Database to be later used by the GA component to generate the chromosomes.CALL
and DEFAULT
. The field $extra contains the key count
with the integer value 0
. The field $scheme is set to tel
and the subsequent $uri field contains the phone number. Figure 13b shows another chromosome containing the same set of fields but with different values for some of the fields.
tel
scheme requires the $data field to contain only a phone number, while the http
scheme requires the $data field to be composed of $host, $port and $path (see Table 1). Intents with the same $scheme ensures that $data are composed of compatible sub-fields, and thus can be exchanged.-
The values of the $scheme field is mutated (with 30% probability) by the operator SwitchScheme that swaps the original value of this field with one of the seed values, selected with uniform probability. In the example of Table 3, the scheme http is replaced by the scheme ftp (available as seed in Table 2) to change the URL as shown in the corresponding line.
-
The value of the $action, $category and $pathPattern fields are not mutated.
-
For the $extra field, the keys are not mutated. The values of the extra are mutated with 30% probability. The mutation is performed as follows:
-
With 15% probability, the SwitchExtraValue operator is used to change the value of the $extra field with a seed value. In the example, the value of
wifi_state
is changed from 1 to 0, by peeking the new value from the pool of seed values for this key (see second line in Table 2); -
With 15% probability, a AlterExrtra*Value operator is selected to arbitrarily change the value of the $extra value. AlterExrtraIntValue or AlterExrtraStringValue are used, depending on the type of the extra. This operator does not use seed values. If the type is numeric, AlterExrtraIntValue mutates the value by adding or subtracting an offset. Small offsets are chosen with higher probability and the probability of larger offsets decreases exponentially. In the example the value of
wifi_state
is changed from 1 to 5, the value added as offset (i.e., 4) is not a seed value.In case the type of the extra is string, the operator AlterExrtraStringValue is used instead. The extra value is mutated by deleting, inserting or replacing a character in the string with a random character. In the example thepreferred_ssid
is changed from‘‘myhome''
, respectively, to‘‘myhom''
,‘‘myhomeX''
and‘‘myWome''
.
-
-
For fields $host, $port and $path, the mutation operators are similar to previous cases. That is, the mutation is performed with 30% probability. With 15% probability, the field is replaced with a seed value (operators SwitchHost, SwitchPort and SwitchPath), and with 15% probability the value is changed regardless the available seeds (operators AlterHost, AlterPort and AlterPath), as shown in the corresponding examples.
Field | Seed values |
---|---|
$scheme | http , https , ftp |
$extra (key=wifi_state) | 1 , 0 |
$host | se.fbk.eu , univr.it |
$port | 80 , 443 |
$path | people/ceccato , item/pen |
Operator | Original | Mutated |
---|---|---|
SwitchScheme | ||
SwitchExtraValue | wifi_state →1 | wifi_state →0 |
AlterExtraIntValue | wifi_state →1 | wifi_state →5 |
AlterExtraStringValue | preferred_ssid →“myhome ” | preferred_ssid →“myhom ” |
preferred_ssid →“myhome ” | preferred_ssid →“myhome X” | |
preferred_ssid →“myhome ” | preferred_ssid →“my W ome ” | |
SwitchHost | ||
AlterHost | ||
SwitchPort | ||
AlterPort | ||
SwitchPath | ||
AlterPath |
8 Evaluation
-
RQ1 (Precision): Is PREV precise at detecting permission re-delegation vulnerabilities in Android apps?
-
RQ2 (Cost): Is the cost (in terms of analysis time) of using our approach affordable in practice?
-
RQ3 (Recall): Does PREV miss permission re-delegation vulnerabilities?
-
RQ4 (Comparison): Does PREV perform better than other tools that can be used to detect permission re-delegation vulnerabilities?
-
RQ5 (Robustnesses): Is PREV robust against the inclusion of anomalies in the training set?
-
RQ6 (Threshold): What is the impact of other threshold values on vulnerability detection accuracy of PREV?
8.1 Subject Apps
8.2 Metrics
-
Number of true positives (TP): Number of real vulnerable apps correctly reported as vulnerable;
-
Number of false positives (FP): Number of vulnerable apps incorrectly reported as vulnerable (false alarms);
-
Number of false negatives (FN): Number of vulnerable apps that are missed (not reported by the tool);
-
Analysis time: The time (measured in minutes) taken by the tool to analyze a subject app;
-
Number of contaminated apps: Number of training apps that contain permission re-delegation vulnerabilities;
-
Threshold: the value used to flag outlier apps
8.3 RQ1: Precision
-
Custom protocol: the vulnerability can be triggered only with a particular message that follows an application-specific invocation protocol;
-
System intents: the vulnerable component subscribed for system-generated events, but it fails to check whether the notified event is actually generated by the system;
-
Misuse of libraries: the vulnerable app performs an insecure use of a library that deals with sensitive data;
-
App description: a permission re-delegation causes the vulnerable app to perform a privileged task that is not explicitly specified as a feature in the app description.
App | TP | FP | Guideline |
---|---|---|---|
com.mendhak.gpslogger | ✓ | App Description | |
com.seafile.seadroid2 | ✓ | App Description | |
org.ligi.ajsha | ✓ | App Description | |
org.linphone | ✓ | App Description | |
org.tigase.messenger.phone.pro | ✓ | App Description | |
org.totschnig.myexpenses | ✓ | App Description | |
org.ttrssreader | ✓ | App Description | |
bestvalleygames.turningvalley | ✓ | App Description | |
com.akgun.uknews | ✓ | Custom Protocol | |
com.appportunity.androidpreviewer | ✓ | App Description | |
com.appreka.mycoop | ✓ | Misuse of Library | |
com.appsdv.smsmefitr | ✓ | Misuse of Library | |
com.aurorasi.aurorasfa | ✓ | Misuse of Library | |
com.bimandika.Congratulationsmalonepost | ✓ | System Intents | |
com.braingen.devanagarinotepad | ✓ | App Description | |
com.dinosaur.dinosaur_vs_zombie | ✓ | App Description | |
com.fmplural.radio | ✓ | App Description | |
com.innogang.kollywoodNews | ✓ | App Description | |
com.javirurro.games.spaceshipzigzag | ✓ | App Description | |
com.josejoaquin.traductor | ✓ | App Description | |
com.magmamobile.game.SpiderSolitaire2 | ✓ | Custom Protocol | |
com.netdania | ✓ | Custom Protocol | |
com.npes87184.s2tdroid | ✓ | App Description | |
com.rbsoftware.pfm.personalfinancemanager | ✓ | Misuse of Library | |
com.reverbnation.artistapp.i739749 | ✓ | System Intents | |
com.softdx.qrscanner | ✓ | App Description | |
com.superfanu.bryantbulldogrewards | ✓ | System Intents | |
com.vent | ✓ | Misuse of Library | |
lv.delfi.ru | ✓ | Custom Protocol | |
piproduction.frankthejew | ✓ | Custom Protocol |
com.example.TestApp.TEST_ACTION
for the app com.example.TestApp
; it is not from an included library or from the Android framework. Therefore, this action is likely for internal use, i.e., only for components of the AUT or only for apps developed by the same developers who know the internal details of the app. It is highly unlikely that this component intends to accept action requests from other external apps. Therefore, when there is a permission re-delegation scenario in which intent messages can invoke such components, we believe that this is a developer’s mistake or she/he adopts a security-by-obscurity approach. This is a vulnerability because it can be uncovered by an approach like ours. This guideline was applied to classify 5 vulnerable apps such as com.netdania and piproduction.frankthejew.ACTION_BOOT_COMPLETED
action, which Android platform generates on completing the boot. However, the component of this app does not validate that this notification was actually sent by the system. It blindly assumes that any intent sent to this component is from the system and processes as such. Therefore, when the intent filter specifies a system action but the app code does not validate intent data, we assume that it is a programming mistake and we classify the case as a permission re-delegation vulnerability. This guideline was applied to classify 3 vulnerable apps.ACTION_MY_PACKAGE_REPLACED
, is actually sent by the PackageManager (the system). System actions such as ACTION_MY_PACKAGE_REPLACED
are actions that can only be set by the system when sending an Intent. If an app registers to receive a broadcast Intent with such actions, the Android system guarantees that the Intent is sent only by the system. However, apps still have to verify if the Intent they receive is actually sent by the system by checking if the action matches exactly the one that they registered to receive. If an app fails to verify and simply assumes that the Intent came from the system, then the app is potentially vulnerable. This is because a malicious app may send an Intent directly to the vulnerable app component with an arbitrary action and trick the app into performing a privileged action. This guideline was applied to classify 5 vulnerable apps.8.4 RQ2: Cost
8.5 RQ3: Recall
-
The mutated app crashes;
-
The privileged API call is in a path that is not realizable from public entry points, due to certain path conditions in place;
-
A path involves a UI event, such as a click event;
-
A mutated component only accepts intents sent by the system.
Mutant | TP | FN |
---|---|---|
com.colortime.mandala_exposed_99 | ✓ | |
com.compasskeyboards.skullkeyboards_exposed_63 | ✓ | |
com.khampat.damdawi.in_exposed_63 | ✓ | |
com.khampat.damdawi.in_exposed_158 | ✗ | |
com.khampat.damdawi.in_exposed_165 | ✓ | |
com.kisstakoala.vehiclesfree_direct_1 | ✓ | |
com.mademin.avoidthecircles_direct_1 | ✓ | |
com.mademin.avoidthecircles_exposed_47 | ✗ | |
com.mfoundry.mb.android.mb_252070299_exposed_331 | ✓ | |
com.tdelphiblog.LazyShaker_exposed_33 | ✗ | |
lwcr46lion.lwp_exposed_360 | ✗ | |
com.futurice.android.reservator_17_exposed_2 | ✓ | |
com.junjunguo.pocketmaps_8_exposed_22 | ✓ | |
com.newsblur_138_direct_1 | ✓ | |
com.newsblur_138_direct_5 | ✓ | |
com.nextcloud.client_10040299_exposed_13 | ✗ | |
com.nextcloud.client_10040299_exposed_81 | ✓ | |
com.nextcloud.client_10040299_exposed_108 | ✓ | |
net.mypapit.mobile.myposition_12_direct_1 | ✓ | |
org.ligi.gobandroid_hd_258_exposed_35 | ✓ |
lwcr46lion.lwp_exposed _360
because the app expects a media URL (e.g., a URL pointing to .mp4 file) with an advertisement to display. When apps are expecting an intent $data field with a URI that meets some conditions, these conditions are usually specified in the intent-filter. As discussed in Section 7.2, the test case generation phase relies on intent-filters in order to seed the $data field. However, this component does not specify an intent-filter at all (only the attribute exported
is set to true
). While the test case generation can seed other intent fields, such as $action
and $extra
, from the component’s code even if they are not specified in the manifest file, the $data
field is seeded either from the intent-filter or the component code only when the specification exists in the manifest file. As this component does not specify an intent-filter, our approach failed in generating the $data
field that was essential to test this app. Similarly, the remaining 4 apps require inputs of specific data structures that could not be generated automatically and therefore, are missed.-
Five apps are actually vulnerable but missed by our tool. The reason is because our test generator was unable to generate the intent messages as required by those apps due to the similar problems explained above (missing intent-filter specifications);
-
Four apps are not exploitable as the components are protected by custom permissions;
-
Seven apps involve UI event-based paths that include user interactions (such as touches). Hence, they are not considered vulnerable (see Precondition PR1 in Section 3.2).
8.6 RQ4: Comparison
getIntent()
) as sources and configured all the APIs that require special permission as sinks (listed in Pscout (Au et al. 2012)). If there is a data flow from a source (i.e., data sent from another app or another component) to a sink (i.e., performing privileged action), it is a case of permission re-delegation. We configured IccTA to report such cases. We note that such permission re-delegation cases are not necessarily vulnerabilities. Some of these cases could be the intended features of the app and thus, safe cases. ICC is a feature of Android framework. On the other hand, this in fact motivates the need of an approach like ours, for more precise vulnerability detection. In the following, we compare the results by discussing what cases are genuine vulnerabilities and what cases are safe cases.App | Vulnerable | Intentional | Intra-comp. | Private | System |
---|---|---|---|---|---|
Behaviour | Intent | Components | Intent | ||
be.brunoparmentier.openbikesharing.app | ✗ | ||||
com.briankhuu.nfcmessageboard | ✗ | ||||
com.duckduckgo.mobile.android | ✗ | ||||
com.hectorone.multismssender | ✗ | ||||
com.mschlauch.comfortreader | ✗ | ||||
com.newsblur | ✗ | ||||
com.seafile.seadroid2 | ✗ | ||||
com.xperia64.timidityae | ✗ | ||||
de.hirtenstrasse.michael.lnkshortener | ✗ | ||||
de.jkliemann.parkendd | ✗ | ||||
de.syss.MifareClassicTool | ✗ | ||||
de.yazo_games.mensaguthaben | ✗ | ||||
net.kervala.comicsreader | ✗ | ||||
org.glucosio.android | ✗ | ||||
org.marcus905.wifi.ace | ✗ | ||||
org.nerdcircus.android.klaxon | ✗ | ||||
org.tigase.messenger.phone.pro | ✓ | ||||
se.anyro.nfc_reader | ✗ |
-
Intentional behavior: some reported apps receive data from other apps (components) and use privileged APIs. These are cases of permission re-delegations. However, our inspection found that those cases actually implement app features declared in app’s descriptions (intended features). For example,
com.newsblur
,com.mschlauch.comfortreader
,com.duckduckgo.mobile.android
andse.anyro.nfc_reader
are browser, NFC reader and news/document reader apps, respectively; and browsing and data reading features are clearly declared in their Play Store descriptions. Therefore, those reports are actually safe cases of permission re-delegation. Most reports fall under this category. -
Intra-component intent: for some reported apps, the intent can only come from a component within the same app (i.e., result of
startActivityForResult
call). Hence, those reports are actually safe cases, because the intent originates from the same app. -
Private components: for the reported app
com.briankhuu.nfcmessageboard
, the components in question are not exported. Therefore, they are only accessible within the same app and thus, not exploitable. -
System intent: for the reported app
be.brunoparmentier.openbikesharing. app
, the intent returned from the system component,AccountManager
, is reported to be potentially dangerous. Since the intent actually comes from the Android system, we consider this as safe.
-
User interaction: some reported apps such as
com.newsblur
andcom.ringdroid
require the user to interact. If a user is involved, it is either an intended behavior or an action that can be aborted by the user. Therefore, we do not consider this as a vulnerability (See Precondition PR1 in Section 3.2). -
Overtainting: for some reported apps such as
de.syss.MifareClassicTool
, the result of IccTA is affected by overtainting. For example, an activity instance containing an untrusted field is tainted. This instance is then used in a callback function but the field does not actually influence the invocation of any privileged API; hence this is a safe case.
App | Vulnerable | Intentional | Private | User | Overtainting |
---|---|---|---|---|---|
Behaviour | Components | Interaction | |||
com.alfray.timeriffic | ✗ | ||||
com.commonsware.android.arXiv | ✗ | ✗ | |||
com.newsblur | ✗ | ||||
com.mschlauch.comfortreader | ✗ | ||||
com.ringdroid | ✗ | ||||
cz.romario.opensudoku | ✗ | ||||
de.jkliemann.parkendd | ✗ | ||||
de.syss.MifareClassicTool | ✗ | ||||
mobi.boilr.boilr | ✗ | ||||
moe.minori.pgpclipper | ✗ | ||||
org.jfet.batsHIIT | ✗ | ||||
org.sixgun.ponyexpress | ✗ | ||||
org.smc.inputmethod.indic | ✗ | ||||
se.anyro.nfc_reader | ✗ | ✗ | |||
sk.halmi.fbeditplus | ✗ |
Open source apps | Mutated apps | |||
---|---|---|---|---|
Tool | Detected | Safe | Detected | Missed |
PREV | 7 | 0 | 15 | 5 |
Covert | 1 | 17 | 0 | 20 |
IccTA | 0 | 15 | 0 | 20 |
8.7 RQ5: Robustness
com.appportun- ity.androidpreviewer
. PREV detected the vulnerability based on the permission re-delegation model learnt on the training apps of the cluster to which the subject app belongs (cluster 20). Now, we degrade this training set by modifying the API Camera.open() as reachable in TrainingApp2, a training app from the same cluster as com.appportunity.androidpreviewer
. This in fact corresponds to changing a value from 0 to 1 in the third column of the matrix. The change is highlighted in boldface in Fig. 17b. In this way, we contaminate the training set, by making the privileged but uncommon API Camera.open() more frequent and, thus, less likely anomalous.App | Number of Contaminated Apps | Cluster size |
---|---|---|
bestvalleygames.turningvalley | 5 | 443 |
com.akgun.uknews | 7 | 337 |
com.appportunity.androidpreviewer | 2 | 438 |
com.appreka.mycoop | 5 | 537 |
com.appsdv.smsmefitr | 3 | 410 |
com.aurorasi.aurorasfa | 5 | 537 |
com.bimandika.Congratulationsmalonepost | 3 | 410 |
com.braingen.devanagarinotepad | 5 | 469 |
com.dinosaur.dinosaur_vs_zombie | 5 | 443 |
com.fmplural.radio | 3 | 293 |
com.innogang.kollywoodNews | 7 | 337 |
com.javirurro.games.spaceshipzigzag | 3 | 410 |
com.josejoaquin.traductor | 3 | 311 |
com.magmamobile.game.SpiderSolitaire2 | 3 | 410 |
com.netdania | 5 | 537 |
com.npes87184.s2tdroid | 7 | 337 |
com.rbsoftware.pfm.personalfinancemanager | 5 | 537 |
com.reverbnation.artistapp.i739749 | 7 | 337 |
com.softdx.qrscanner | 5 | 537 |
com.superfanu.bryantbulldogrewards | 3 | 410 |
com.vent | 5 | 537 |
lv.delfi.ru | 5 | 469 |
piproduction.frankthejew | 3 | 410 |
com.mendhak.gpslogger | 4 | 380 |
com.seafile.seadroid2 | 2 | 537 |
org.ligi.ajsha | 2 | 537 |
org.linphone | 2 | 380 |
org.tigase.messenger.phone.pro | 5 | 453 |
org.totschnig.myexpenses | 5 | 537 |
org.ttrssreader | 5 | 410 |