static reference analysis for gui objects in android software
Post on 20-Oct-2014
332 views
DESCRIPTION
The popularity of Android software has grown dramatically in the last few years. It is essential for researchers in programming languages and compilers to contribute new techniques in this increasingly important area. Such techniques require a foundation of program analyses for Android. The target of our work is static object reference analysis, which models the flow of object references. Existing reference analyses cannot be applied directly to Android because the software is component-based and event-driven. An Android application is driven by a graphical user interface (GUI), with GUI objects responding to user actions. These objects and the event handlers associated with them ultimately determine the possible flow of control and data. We propose the first static analysis to model GUI-related Android objects, their flow through the application, and their interactions with each other via the abstractions defined by the Android platform. A formal semantics for the relevant Android constructs is developed to provide a solid foundation for this and other analyses. Next, we propose a constraint-based reference analysis based on the semantics. The analysis employs a constraint graph to model the flow of GUI objects, the hierarchical structure of these objects, and the effects of relevant Android operations. Experimental evaluation on real-world Android applications strongly suggests that the analysis achieves high precision with low cost. The analysis enables static modeling of control/data flow that is foundational for compiler analyses, instrumentation for event/interaction profiling, static error checking, security analysis, test generation, and automated debugging. It provides a key component to be used by compile-time analysis researchers in the growing area of Android software.TRANSCRIPT
Sta$c Reference Analysis for GUI Objects in Android So9ware
PRESTO: Program Analyses and So5ware Tools Research Group, Ohio State University
Atanas Rountev, Dacong (Tony) Yan
Ohio State University
MoFvaFon and Background • Android so5ware is used by millions of users • Requires foundaFonal program analyses for improved performance and quality
• StaFc reference analysis for Java • What is the set of run-‐Fme objects? • Which variables contain references to which objects? • CriFcal component of data-‐ and control-‐flow analysis • Prerequisite for many other techniques
• ExisFng work cannot be applied directly to Android • Goal: develop a precise and efficient staFc reference analysis for Android-‐specific features
2
StaFc Reference Analysis for Android Features • Android applicaFon • Driven by a graphical user interface (GUI) • Ac#vity: on-‐screen window with GUI elements (views) • Event handlers: defined in listeners and associated with views to respond to user acFons
• Need to model staFcally • Views and their hierarchical structure • AssociaFon of views with acFviFes • AssociaFon of views with listeners • Variables that refer to views, acFviFes, and listeners
3
Example MyActivity.java: ! 1 class MyActivity extends Activity { ! 2 void onCreate() { ! 3 this.setContentView(R.layout.main); // Inflate ! 4 View a = this.findViewById(R.id.my_btn); // FindView! 5 Button b = (Button) a; ! 6 ButtonListener c = new ButtonListener(); ! 7 b.setOnClickListener(c); // SetListener } } !!ButtonListener.java: ! 8 class ButtonListener implements OnClickListener { ! 9 void onClick(View d) { ... } } !!main.xml: ! 10 <RelativeLayout ...> ! 11 <Button android:id=“@+id/my_btn” ... /> ! 12 </RelativeLayout> !
4
Example MyActivity.java: ! 1 class MyActivity extends Activity { ! 2 void onCreate() { ! 3 this.setContentView(R.layout.main); // Inflate ! 4 View a = this.findViewById(R.id.my_btn); // FindView! 5 Button b = (Button) a; ! 6 ButtonListener c = new ButtonListener(); ! 7 b.setOnClickListener(c); // SetListener } } !!ButtonListener.java: ! 8 class ButtonListener implements OnClickListener { ! 9 void onClick(View d) { ... } } !!main.xml: ! 10 <RelativeLayout ...> ! 11 <Button android:id=“@+id/my_btn” ... /> ! 12 </RelativeLayout> !
5
Example MyActivity.java: ! 1 class MyActivity extends Activity { ! 2 void onCreate() { ! 3 this.setContentView(R.layout.main); // Inflate ! 4 View a = this.findViewById(R.id.my_btn); // FindView! 5 Button b = (Button) a; ! 6 ButtonListener c = new ButtonListener(); ! 7 b.setOnClickListener(c); // SetListener } } !!ButtonListener.java: ! 8 class ButtonListener implements OnClickListener { ! 9 void onClick(View d) { ... } } !!main.xml: ! 10 <RelativeLayout ...> ! 11 <Button android:id=“@+id/my_btn” ... /> ! 12 </RelativeLayout> !
6
Example MyActivity.java: ! 1 class MyActivity extends Activity { ! 2 void onCreate() { ! 3 this.setContentView(R.layout.main); // Inflate ! 4 View a = this.findViewById(R.id.my_btn); // FindView! 5 Button b = (Button) a; ! 6 ButtonListener c = new ButtonListener(); ! 7 b.setOnClickListener(c); // SetListener } } !!ButtonListener.java: ! 8 class ButtonListener implements OnClickListener { ! 9 void onClick(View d) { ... } } !!main.xml: ! 10 <RelativeLayout ...> ! 11 <Button android:id=“@+id/my_btn” ... /> ! 12 </RelativeLayout> !
7
RelativeLayout!
Button: my_btn!
child
Example MyActivity.java: ! 1 class MyActivity extends Activity { ! 2 void onCreate() { ! 3 this.setContentView(R.layout.main); // Inflate ! 4 View a = this.findViewById(R.id.my_btn); // FindView! 5 Button b = (Button) a; ! 6 ButtonListener c = new ButtonListener(); ! 7 b.setOnClickListener(c); // SetListener } } !!ButtonListener.java: ! 8 class ButtonListener implements OnClickListener { ! 9 void onClick(View d) { ... } } !!main.xml: ! 10 <RelativeLayout ...> ! 11 <Button android:id=“@+id/my_btn” ... /> ! 12 </RelativeLayout> !
8
RelativeLayout!
Button: my_btn!
child
Example MyActivity.java: ! 1 class MyActivity extends Activity { ! 2 void onCreate() { ! 3 this.setContentView(R.layout.main); // Inflate ! 4 View a = this.findViewById(R.id.my_btn); // FindView! 5 Button b = (Button) a; ! 6 ButtonListener c = new ButtonListener(); ! 7 b.setOnClickListener(c); // SetListener } } !!ButtonListener.java: ! 8 class ButtonListener implements OnClickListener { ! 9 void onClick(View d) { ... } } !!main.xml: ! 10 <RelativeLayout ...> ! 11 <Button android:id=“@+id/my_btn” ... /> ! 12 </RelativeLayout> !
9
RelativeLayout!
Button: my_btn!
child
Example MyActivity.java: ! 1 class MyActivity extends Activity { ! 2 void onCreate() { ! 3 this.setContentView(R.layout.main); // Inflate ! 4 View a = this.findViewById(R.id.my_btn); // FindView! 5 Button b = (Button) a; ! 6 ButtonListener c = new ButtonListener(); ! 7 b.setOnClickListener(c); // SetListener } } !!ButtonListener.java: ! 8 class ButtonListener implements OnClickListener { ! 9 void onClick(View d) { ... } } !!main.xml: ! 10 <RelativeLayout ...> ! 11 <Button android:id=“@+id/my_btn” ... /> ! 12 </RelativeLayout> !
10
RelativeLayout!
Button: my_btn!
child
Example MyActivity.java: ! 1 class MyActivity extends Activity { ! 2 void onCreate() { ! 3 this.setContentView(R.layout.main); // Inflate ! 4 View a = this.findViewById(R.id.my_btn); // FindView! 5 Button b = (Button) a; ! 6 ButtonListener c = new ButtonListener(); ! 7 b.setOnClickListener(c); // SetListener } } !!ButtonListener.java: ! 8 class ButtonListener implements OnClickListener { ! 9 void onClick(View d) { ... } } !!main.xml: ! 10 <RelativeLayout ...> ! 11 <Button android:id=“@+id/my_btn” ... /> ! 12 </RelativeLayout> !
11
Example MyActivity.java: ! 1 class MyActivity extends Activity { ! 2 void onCreate() { ! 3 this.setContentView(R.layout.main); // Inflate ! 4 View a = this.findViewById(R.id.my_btn); // FindView! 5 Button b = (Button) a; ! 6 ButtonListener c = new ButtonListener(); ! 7 b.setOnClickListener(c); // SetListener } } !!ButtonListener.java: ! 8 class ButtonListener implements OnClickListener { ! 9 void onClick(View d) { ... } } !!main.xml: ! 10 <RelativeLayout ...> ! 11 <Button android:id=“@+id/my_btn” ... /> ! 12 </RelativeLayout> !
12
Example MyActivity.java: ! 1 class MyActivity extends Activity { ! 2 void onCreate() { ! 3 this.setContentView(R.layout.main); // Inflate ! 4 View a = this.findViewById(R.id.my_btn); // FindView! 5 Button b = (Button) a; ! 6 ButtonListener c = new ButtonListener(); ! 7 b.setOnClickListener(c); // SetListener } } !!ButtonListener.java: ! 8 class ButtonListener implements OnClickListener { ! 9 void onClick(View d) { ... } } !!main.xml: ! 10 <RelativeLayout ...> ! 11 <Button android:id=“@+id/my_btn” ... /> ! 12 </RelativeLayout> !
13
Example MyActivity.java: ! 1 class MyActivity extends Activity { ! 2 void onCreate() { ! 3 this.setContentView(R.layout.main); // Inflate ! 4 View a = this.findViewById(R.id.my_btn); // FindView! 5 Button b = (Button) a; ! 6 ButtonListener c = new ButtonListener(); ! 7 b.setOnClickListener(c); // SetListener } } !!ButtonListener.java: ! 8 class ButtonListener implements OnClickListener { ! 9 void onClick(View d) { ... } } !!main.xml: ! 10 <RelativeLayout ...> ! 11 <Button android:id=“@+id/my_btn” ... /> ! 12 </RelativeLayout> !
14
Example MyActivity.java: ! 1 class MyActivity extends Activity { ! 2 void onCreate() { ! 3 this.setContentView(R.layout.main); // Inflate ! 4 View a = this.findViewById(R.id.my_btn); // FindView! 5 Button b = (Button) a; ! 6 ButtonListener c = new ButtonListener(); ! 7 b.setOnClickListener(c); // SetListener } } !!ButtonListener.java: ! 8 class ButtonListener implements OnClickListener { ! 9 void onClick(View d) { ... } } !!main.xml: ! 10 <RelativeLayout ...> ! 11 <Button android:id=“@+id/my_btn” ... /> ! 12 </RelativeLayout> !
15
Modeled Android OperaFons • Inflate • Create GUI structure from XML and a\ach to acFvity/view
• CreateView • ProgrammaFcally create a view through new V
• FindView • Lookup a view from acFvity or ancestor view (e.g., by ID)
• SetListener • Associate view and listener
• AddView • Establish parent-‐child relaFonship between two views
• SetId • ProgrammaFcally set the ID of a view
16
Our Proposal • Define formal seman#cs of GUI-‐related Android constructs
• Encode semanFcs of an Android applicaFon in a constraint graph
• Perform constraint-‐based staFc reference analysis
17
Example 1 class MyActivity extends Activity { ! 2 void onCreate() { ! 3 this.setContentView(R.layout.main); // Inflate ! 4 View a = this.findViewById(R.id.my_btn); // FindView! 5 Button b = (Button) a; ! 6 ButtonListener c = new ButtonListener(); ! 7 b.setOnClickListener(c); // SetListener } } !
"... "... "... ! 9 void onClick(View d) { ... } } !!!!
18 Propaga$on edges and relevant nodes
Example 1 class MyActivity extends Activity { ! 2 void onCreate() { ! 3 this.setContentView(R.layout.main); // Inflate ! 4 View a = this.findViewById(R.id.my_btn); // FindView! 5 Button b = (Button) a; ! 6 ButtonListener c = new ButtonListener(); ! 7 b.setOnClickListener(c); // SetListener } } !
"... "... "... ! 9 void onClick(View d) { ... } } !!!!
19 Propaga$on edges and relevant nodes
MyActivity!
Example 1 class MyActivity extends Activity { ! 2 void onCreate() { ! 3 this.setContentView(R.layout.main); // Inflate ! 4 View a = this.findViewById(R.id.my_btn); // FindView! 5 Button b = (Button) a; ! 6 ButtonListener c = new ButtonListener(); ! 7 b.setOnClickListener(c); // SetListener } } !
"... "... "... ! 9 void onClick(View d) { ... } } !!!!
20 Propaga$on edges and relevant nodes
MyActivity!
Example 1 class MyActivity extends Activity { ! 2 void onCreate() { ! 3 this.setContentView(R.layout.main); // Inflate ! 4 View a = this.findViewById(R.id.my_btn); // FindView! 5 Button b = (Button) a; ! 6 ButtonListener c = new ButtonListener(); ! 7 b.setOnClickListener(c); // SetListener } } !
"... "... "... ! 9 void onClick(View d) { ... } } !!!!
21 Propaga$on edges and relevant nodes
MyActivity! this2 !
Example 1 class MyActivity extends Activity { ! 2 void onCreate() { ! 3 this.setContentView(R.layout.main); // Inflate ! 4 View a = this.findViewById(R.id.my_btn); // FindView! 5 Button b = (Button) a; ! 6 ButtonListener c = new ButtonListener(); ! 7 b.setOnClickListener(c); // SetListener } } !
"... "... "... ! 9 void onClick(View d) { ... } } !!!!
22 Propaga$on edges and relevant nodes
MyActivity!
a
b
c
d
this2 ! this9 !
Example 1 class MyActivity extends Activity { ! 2 void onCreate() { ! 3 this.setContentView(R.layout.main); // Inflate ! 4 View a = this.findViewById(R.id.my_btn); // FindView! 5 Button b = (Button) a; ! 6 ButtonListener c = new ButtonListener(); ! 7 b.setOnClickListener(c); // SetListener } } !
"... "... "... ! 9 void onClick(View d) { ... } } !!!!
23 Propaga$on edges and relevant nodes
MyActivity!
a
b
c
Inflate !id:main!
this9 !
d
this2 !
Example 1 class MyActivity extends Activity { ! 2 void onCreate() { ! 3 this.setContentView(R.layout.main); // Inflate ! 4 View a = this.findViewById(R.id.my_btn); // FindView! 5 Button b = (Button) a; ! 6 ButtonListener c = new ButtonListener(); ! 7 b.setOnClickListener(c); // SetListener } } !
"... "... "... ! 9 void onClick(View d) { ... } } !!!!
24 Propaga$on edges and relevant nodes
MyActivity!
a
b
c
Inflate !id:main!
FindView!id:my_btn! d
this9 !this2 !
Example 1 class MyActivity extends Activity { ! 2 void onCreate() { ! 3 this.setContentView(R.layout.main); // Inflate ! 4 View a = this.findViewById(R.id.my_btn); // FindView! 5 Button b = (Button) a; ! 6 ButtonListener c = new ButtonListener(); ! 7 b.setOnClickListener(c); // SetListener } } !
"... "... "... ! 9 void onClick(View d) { ... } } !!!!
25 Propaga$on edges and relevant nodes
MyActivity!
a
b
c
Inflate !id:main!
FindView!id:my_btn! d
this9 !this2 !
Example 1 class MyActivity extends Activity { ! 2 void onCreate() { ! 3 this.setContentView(R.layout.main); // Inflate ! 4 View a = this.findViewById(R.id.my_btn); // FindView! 5 Button b = (Button) a; ! 6 ButtonListener c = new ButtonListener(); ! 7 b.setOnClickListener(c); // SetListener } } !
"... "... "... ! 9 void onClick(View d) { ... } } !!!!
26 Propaga$on edges and relevant nodes
MyActivity!
a
b
c
Inflate !id:main!
FindView!id:my_btn! d
this9 !this2 !
Example 1 class MyActivity extends Activity { ! 2 void onCreate() { ! 3 this.setContentView(R.layout.main); // Inflate ! 4 View a = this.findViewById(R.id.my_btn); // FindView! 5 Button b = (Button) a; ! 6 ButtonListener c = new ButtonListener(); ! 7 b.setOnClickListener(c); // SetListener } } !
"... "... "... ! 9 void onClick(View d) { ... } } !!!!
27 Propaga$on edges and relevant nodes
MyActivity!
a
b
c
Inflate !id:main!
FindView!id:my_btn!
ButtonListener!
d
this9 !this2 !
Example 1 class MyActivity extends Activity { ! 2 void onCreate() { ! 3 this.setContentView(R.layout.main); // Inflate ! 4 View a = this.findViewById(R.id.my_btn); // FindView! 5 Button b = (Button) a; ! 6 ButtonListener c = new ButtonListener(); ! 7 b.setOnClickListener(c); // SetListener } } !
"... "... "... ! 9 void onClick(View d) { ... } } !!!!
28 Propaga$on edges and relevant nodes
MyActivity!
Inflate !id:main!
FindView!id:my_btn! a
b SetListener!
ButtonListener! c
d
this9 !this2 !
Example 1 class MyActivity extends Activity { ! 2 void onCreate() { ! 3 this.setContentView(R.layout.main); // Inflate ! 4 View a = this.findViewById(R.id.my_btn); // FindView! 5 Button b = (Button) a; ! 6 ButtonListener c = new ButtonListener(); ! 7 b.setOnClickListener(c); // SetListener } } !
"... "... "... ! 9 void onClick(View d) { ... } } !!!!
29 Propaga$on edges and relevant nodes
MyActivity!
Inflate !id:main!
FindView!id:my_btn! a
b SetListener!
ButtonListener! c
d
this9 !this2 !
Example
30
1 class MyActivity extends Activity { ! 2 void onCreate() { ! 3 this.setContentView(R.layout.main); // Inflate ! 4 View a = this.findViewById(R.id.my_btn); // FindView! 5 Button b = (Button) a; ! 6 ButtonListener c = new ButtonListener(); ! 7 b.setOnClickListener(c); // SetListener } } !
"... "... "... ! 10 <RelativeLayout ...> ! 11 <Button android:id=“@+id/my_btn” ... /> ! 12 </RelativeLayout> !
Property edges and relevant nodes
RelativeLayout!
Button !
child
view id id:my_btn!
Example
31
1 class MyActivity extends Activity { ! 2 void onCreate() { ! 3 this.setContentView(R.layout.main); // Inflate ! 4 View a = this.findViewById(R.id.my_btn); // FindView! 5 Button b = (Button) a; ! 6 ButtonListener c = new ButtonListener(); ! 7 b.setOnClickListener(c); // SetListener } } !
"... "... "... ! 10 <RelativeLayout ...> ! 11 <Button android:id=“@+id/my_btn” ... /> ! 12 </RelativeLayout> !
Property edges and relevant nodes
RelativeLayout!
Button !
child
view id id:my_btn!
Inflate !inflater
1 class MyActivity extends Activity { ! 2 void onCreate() { ! 3 this.setContentView(R.layout.main); // Inflate ! 4 View a = this.findViewById(R.id.my_btn); // FindView! 5 Button b = (Button) a; ! 6 ButtonListener c = new ButtonListener(); ! 7 b.setOnClickListener(c); // SetListener } } !
"... "... "... ! 10 <RelativeLayout ...> ! 11 <Button android:id=“@+id/my_btn” ... /> ! 12 </RelativeLayout> !
Example
32 Property edges and relevant nodes
RelativeLayout!
Button !
child
view id id:my_btn!
Inflate !inflater
MyActivity!
this2 !
Example
33 Property edges and relevant nodes
RelativeLayout!
Button !
child
view id id:my_btn!
Inflate !inflater
MyActivity!root
1 class MyActivity extends Activity { ! 2 void onCreate() { ! 3 this.setContentView(R.layout.main); // Inflate ! 4 View a = this.findViewById(R.id.my_btn); // FindView! 5 Button b = (Button) a; ! 6 ButtonListener c = new ButtonListener(); ! 7 b.setOnClickListener(c); // SetListener } } !
"... "... "... ! 10 <RelativeLayout ...> ! 11 <Button android:id=“@+id/my_btn” ... /> ! 12 </RelativeLayout> !
Example
34
1 class MyActivity extends Activity { ! 2 void onCreate() { ! 3 this.setContentView(R.layout.main); // Inflate ! 4 View a = this.findViewById(R.id.my_btn); // FindView! 5 Button b = (Button) a; ! 6 ButtonListener c = new ButtonListener(); ! 7 b.setOnClickListener(c); // SetListener } } !
"!
MyActivity! RelativeLayout!
Button !
root
child
view id id:my_btn!
Property edges and relevant nodes
Inflate !inflater
Example
35
1 class MyActivity extends Activity { ! 2 void onCreate() { ! 3 this.setContentView(R.layout.main); // Inflate ! 4 View a = this.findViewById(R.id.my_btn); // FindView! 5 Button b = (Button) a; ! 6 ButtonListener c = new ButtonListener(); ! 7 b.setOnClickListener(c); // SetListener } } !
"!
Property edges and relevant nodes
MyActivity! RelativeLayout!
Button !
root
child
view id id:my_btn!
Inflate !inflater
Example
36
1 class MyActivity extends Activity { ! 2 void onCreate() { ! 3 this.setContentView(R.layout.main); // Inflate ! 4 View a = this.findViewById(R.id.my_btn); // FindView! 5 Button b = (Button) a; ! 6 ButtonListener c = new ButtonListener(); ! 7 b.setOnClickListener(c); // SetListener } } !
"!
Property edges and relevant nodes
MyActivity! RelativeLayout!
Button !
root
child
view id id:my_btn!
Inflate !inflater
lookup performed by FindView
Example
37 Property edges and relevant nodes
MyActivity! RelativeLayout!
Button !
root
child
view id id:my_btn!
Inflate !inflater
1 class MyActivity extends Activity { ! 2 void onCreate() { ! 3 this.setContentView(R.layout.main); // Inflate ! 4 View a = this.findViewById(R.id.my_btn); // FindView! 5 Button b = (Button) a; ! 6 ButtonListener c = new ButtonListener(); ! 7 b.setOnClickListener(c); // SetListener } } !
"!
Example
38
1 class MyActivity extends Activity { ! 2 void onCreate() { ! 3 this.setContentView(R.layout.main); // Inflate ! 4 View a = this.findViewById(R.id.my_btn); // FindView! 5 Button b = (Button) a; ! 6 ButtonListener c = ! 7 b.setOnClickListener(c); // SetListener } } !
"!
Property edges and relevant nodes
ButtonListener!
MyActivity! RelativeLayout!
Button !
root
child
view id id:my_btn!
Inflate !inflater
Example
39
1 class MyActivity extends Activity { ! 2 void onCreate() { ! 3 this.setContentView(R.layout.main); // Inflate ! 4 View a = this.findViewById(R.id.my_btn); // FindView! 5 Button b = (Button) a; ! 6 ButtonListener c = new ButtonListener(); ! 7 b.setOnClickListener(c); // SetListener } } !
"!
Property edges and relevant nodes
MyActivity! RelativeLayout!
Button !
root
child
view id id:my_btn!
Inflate !inflater
ButtonListener!listener
ImplementaFon • Input • Java bytecode of the applicaFon • Relevant XML files
• Output • Parent-‐child relaFonships between views • AssociaFon of acFviFes with root views • AssociaFon of views with listeners • Variables and fields referring to views, acFviFes, listeners
• Analysis algorithm 1. Create iniFal constraint graph from app code 2. Solve propagaFon constraints for IDs, acFviFes, listeners 3. Fixed-‐point computaFon for flow of views between
operaFon nodes 40
EvaluaFon • Experiments on 20 open-‐source Android apps • Experiment I – applicaFon characterizaFon • Constraint graph: number of various types of nodes • Result: Android-‐specific features are widely used
• Experiment II – analysis performance and precision • Running Fme to perform the constraint analysis • Less than 5 seconds for each app
• Average number of objects for variables at relevant operaFons – e.g. • v1.addChild(v2) – receiver v1, parameter v2 • v = x.findViewById(…) – result v • v.setListener(m) – receiver v, listener m
41
Precision Measurements
42 Average number of objects for variables at relevant opera$ons
Precision Measurements
43 Average number of objects for variables at relevant opera$ons
Imprecision?
Conclusions • First staFc analysis to focus on GUI-‐related Android constructs
• Proposed constraint-‐based algorithm exhibits high precision and low cost
• CriFcal building block for other analyses and tools for Android
● So5ware release ● GATOR: Program Analysis Toolkit For Android ● h\p://www.cse.ohio-‐state.edu/presto/so5ware/
44
Thank you
45