AQL-Questions & -Queries
AQL-Questions can be used to ask various analysis tools for certain analysis subjects in a general way. AQL-Queries represent compositions of AQL-Questions combined by AQL-Operators.
All possible AQL-Queries are defined by this grammar. In general, a query consists of one or more questions possibly connected by AQL-Operators. A question in turn exist of an analysis subject and a target description.
Each question can ask for one of the following analysis subjects:
Flows: A flow symbolizes the transfer of information from one program location to another. To describe such a flow, these two locations have to be specified
Intents: Intents are used for inter-component communication, where one component sends an intent to another component. In case of an explicit intent the receiver can be identified by a component reference. But in case of an implicit intent the receiver needs to be recognized through the information triple action, category and data
IntentFilters: Specifies the types of intents that an activity, service, or broadcast receiver can respond to
IntentSinks: Intent-sinks are special intents, so they can be described in the same way as intents can be described. However, in this case a reference to a program location is always required (Required to connect answers -- See
IntentSources: Intent-sources represent the counterpart of intent-sinks. An intent-source might be the starting location of an information flow path. They can be described just like intent-sinks and intents with one small but important difference: The reference has to refer to a statement that, for instance, extracts information from an intent. (Also required to connect answers -- See
Permissions: Shows which permissions are used by a reference
The analysis target is specified by a chain consisting of the following elements
Statement -> Method -> Class -> App
In such a chain the elements
Class are optional.
This allows to ask for on-demand properties for certains parts of an app.
In a complete question we can ask for information inside one target (
IN) or for information between two targets (
Furthermore, a certain preprocessor can be assigned to be apllied before an app is analyzed.
Any question contained in a query ends with a
?-symbol. This indirectly refers to the answer which is received by asking this question.
It is also possible to directly reference a previously computed answer. Therefore an
! at the end distinguishes directly addressed answers from indirectly addressed ones.
The following operators can be used to filter or combine answers.
FILTER: Outputs the input set, but beforehand it removes all permissions, intent-sinks and -sources whose reference does not appear in any flow contained in the answer. Intents and intent-filters from the input set are kept in the output set. The filter operator can also be used together with an analysis subject in order to filter out all elements of the selected subject of interest or with a name-value-pair to filter elements that contain this name-value-pair as attribute.
UNIFY: Collects all information from two different AQL-Answers and puts it into one.
CONNECT: Works as
UNIFY, however, it additionally computes transitive flows and flows that can be determined by connecting intent-sinks with intent-sources.
To identify boundaries of operators,
] are used.
It is also possible to define your own operator (see the configuration tutorial).
The following question asks for flows inside app A:
Flows IN App('A.apk') ?
The next one for flows between app A and B:
Flows FROM App('A.apk') TO App('B.apk') ?
To ask for the permission(s) used by a specific statement inside app A, the following question can be constructed:
Permissions IN Statement(sendTextMessage(..))->App('A.apk') ?
Let us assume we got a preprocessor associated with the keyword TEST. To ask for Intents in a preprocessed version of A we formulate:
Intents IN App('A.apk' | 'TEST') ?
To influence the tool selection a specific tool can be choosen:
Flows IN App('A.apk') USES 'AwesomeDroid' ?
Or the tool with the highest priority for a certain set of features can be selected:
Flows IN App('A.apk') FEATURING 'TEST', 'Awesome' ?
Let us assume we want to know which permission protected statements are connected. The question we could ask is:
UNIFY [ Flows IN App('A.apk') ?, Permissions IN App('A.apk') ? ]
Assuming we downloaded an answer telling us which permission uses can be found in app A we could use the following query:
UNIFY [ Flows IN App('A.apk') ?, 'downloaded_permission_answer.xml' ! ]
We could further filter this result by adding the
FILTER operator. In this case we would only get Permissions that are somehow related to a flow:
FILTER [ UNIFY [ Flows IN App('A.apk') ?, Permissions IN App('A.apk') ? ] ]
To connect two answers determined for two different apps (A, B) the
CONNECT operator can be used. Thereby, flows are generated for each pair of matching intent-sinks and -sources:
CONNECT [ IntentSinks IN App('A.apk') ?, IntentSources IN App('B.apk') ? ]
CONNECT operator can also be used to compute the transitive closure of a set of flows:
CONNECT [ Flows IN App('A.apk') ? ]
The following queries may lead to the same answer:
Flows FROM App('A.apk') TO App('B.apk') ?
FILTER [ CONNECT [ Flows IN App('A.apk')?, Flows IN App('B.apk')?, CONNECT [ IntentSinks IN App('A.apk') ?, IntentSources IN App('B.apk') ? ] ] ]
(The AQL-System automatically applies such transformations if required, e.g. because of missing appropiate tools to answer the initial query.)