secure-software-engineering / FlowDroid

FlowDroid Static Data Flow Tracker

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Help with taint analysis of selected Android APIs

vijayantajain opened this issue · comments

Hi,

I am trying to use FlowDroid to do taint analysis of Android apps. While the tool can easily provide taint paths of APIs already present in the SourcesAndSinks.txt file, it does not provide any paths for the APIs I add in the file (such as android.net.wifi.WifiManager;getConnectionInfo).

Also, I am interested in learning where the information from these sources goes, regardless if they have leaked or not. Based on the comments here, the config is already to false and I modified the isClassInSystemPackage method to return false so that each class is evaluated if it "leaks" the information or not. But so far, the tool is not able to identify paths for such APIs. Using Androguard, I have verified the usage of such APIs in these apps.

Have you checked that the syntax of your SourcesAndSinks.txt file is correct? Your example android.net.wifi.WifiManager;getConnectionInfo is not the correct syntax. You can use the APIs that are already in the file as an example.

If you post your source/sink definition here, we can have a look.

Hello again,

Apologies for the confusion. I followed the syntax of the provided in the SourcesAndSinks.txt file and added some APIs as follows:

<android.net.wifi.WifiManager: android.net.wifi.WifiInfo getConnectionInfo()> -> _SOURCE_
<android.net.ConnectivityManager: android.net.NetworkInfo android.net.wifi.WifiInfo getConnectionInfo()> -> _SOURCE_

I don't have any SINK definitions as I am not sure where the information is used.

I don't have any SINK definitions as I am not sure where the information is used.

FlowDroid does one pass over all reachable methods and checks whether there is at least one source and one sink. If not, it aborts before the data flow analysis. There is a lengthy discussion about this in #471. The changes required should be identical to the ones discussed in the issue because the AbstractInfoflow class is independent of the data flow direction.

Also, you need a condition where you decide to log taints. The path reconstruction from the abstraction graph can be quite time-intensive, and you won't be able to build all paths in reasonable time.

Hi @timll, I finally got a chance to work on your feedback. I looked at the discussion in #471 and wrote my own TaintPropagationHandler. But I don't understand how to add the statements to construct the path. Here is the output I am logging in my notifyFlowout:


Abstraction statement: $r3 = virtualinvoke $r2.<android.net.wifi.WifiManager: android.net.wifi.WifiInfo getConnectionInfo()>()
Abstraction taint: zero(null_type) <+length> | >>
Abstraction method: <com.pollfish.f.c: java.lang.String m(android.app.Activity)>
Abstraction incoming: zero(null_type) <+length> | >>
Abstraction outgoing: [$r3(android.net.wifi.WifiInfo) * <+length> | >>]
***************
Abstraction statement: $r3 = virtualinvoke $r2.<android.net.wifi.WifiManager: android.net.wifi.WifiInfo getConnectionInfo()>()
Abstraction taint: zero(null_type) <+length> | >>
Abstraction method: <com.pollfish.f.c: java.lang.String m(android.app.Activity)>
Abstraction incoming: zero(null_type) <+length> | >>
Abstraction outgoing: [$r3(android.net.wifi.WifiInfo) * <+length> | >>]
***************
Abstraction statement: $r4 = virtualinvoke $r3.<android.net.wifi.WifiInfo: java.lang.String getMacAddress()>()
Abstraction taint: zero(null_type) <+length> | >>
Abstraction method: <com.pollfish.f.c: java.lang.String m(android.app.Activity)>
Abstraction incoming: $r3(android.net.wifi.WifiInfo) * <+length> | >>
Abstraction outgoing: [$r3(android.net.wifi.WifiInfo) * <+length> | >>]
***************
Abstraction statement: $r4 = virtualinvoke $r3.<android.net.wifi.WifiInfo: java.lang.String getMacAddress()>()
Abstraction taint: zero(null_type) <+length> | >>
Abstraction method: <com.pollfish.f.c: java.lang.String m(android.app.Activity)>
Abstraction incoming: $r3(android.net.wifi.WifiInfo) * <+length> | >>
Abstraction outgoing: [$r3(android.net.wifi.WifiInfo) * <+length> | >>]
***************
Abstraction statement: $r5 := @caughtexception
Abstraction taint: zero(null_type) <+length> | >>
Abstraction method: <com.pollfish.f.c: java.lang.String m(android.app.Activity)>
Abstraction incoming: $r3(android.net.wifi.WifiInfo) * <+length> | >>
Abstraction outgoing: [$r3(android.net.wifi.WifiInfo) * <+length> | >>]
***************
Abstraction statement: if $r4 != null goto return $r4
Abstraction taint: zero(null_type) <+length> | >>
Abstraction method: <com.pollfish.f.c: java.lang.String m(android.app.Activity)>
Abstraction incoming: $r3(android.net.wifi.WifiInfo) * <+length> | >>
Abstraction outgoing: [$r3(android.net.wifi.WifiInfo) * <+length> | >>]
***************
Abstraction statement: if $r4 != null goto return $r4
Abstraction taint: zero(null_type) <+length> | >>
Abstraction method: <com.pollfish.f.c: java.lang.String m(android.app.Activity)>
Abstraction incoming: $r3(android.net.wifi.WifiInfo) * <+length> | >>
Abstraction outgoing: [$r3(android.net.wifi.WifiInfo) * <+length> | >>]
***************
Abstraction statement: staticinvoke <com.pollfish.f.b.a: void a(java.lang.Throwable)>($r5)
Abstraction taint: zero(null_type) <+length> | >>
Abstraction method: <com.pollfish.f.c: java.lang.String m(android.app.Activity)>
Abstraction incoming: $r3(android.net.wifi.WifiInfo) * <+length> | >>
Abstraction outgoing: [$r3(android.net.wifi.WifiInfo) * <+length> | >>]
***************
Abstraction statement: $r6 = new java.lang.StringBuilder
Abstraction taint: zero(null_type) <+length> | >>
Abstraction method: <com.pollfish.f.c: java.lang.String m(android.app.Activity)>
Abstraction incoming: $r3(android.net.wifi.WifiInfo) * <+length> | >>
Abstraction outgoing: [$r3(android.net.wifi.WifiInfo) * <+length> | >>]
***************
Abstraction statement: specialinvoke $r6.<java.lang.StringBuilder: void <init>()>()
Abstraction taint: zero(null_type) <+length> | >>
Abstraction method: <com.pollfish.f.c: java.lang.String m(android.app.Activity)>
Abstraction incoming: $r3(android.net.wifi.WifiInfo) * <+length> | >>
Abstraction outgoing: [$r3(android.net.wifi.WifiInfo) * <+length> | >>]
***************
Abstraction statement: $r6 = virtualinvoke $r6.<java.lang.StringBuilder: java.lang.StringBuilder append(java.lang.String)>("noMac: ")
Abstraction taint: zero(null_type) <+length> | >>
Abstraction method: <com.pollfish.f.c: java.lang.String m(android.app.Activity)>
Abstraction incoming: $r3(android.net.wifi.WifiInfo) * <+length> | >>
Abstraction outgoing: [$r3(android.net.wifi.WifiInfo) * <+length> | >>]
***************
Abstraction statement: $r6 = virtualinvoke $r6.<java.lang.StringBuilder: java.lang.StringBuilder append(java.lang.Object)>($r5)
Abstraction taint: zero(null_type) <+length> | >>
Abstraction method: <com.pollfish.f.c: java.lang.String m(android.app.Activity)>
Abstraction incoming: $r3(android.net.wifi.WifiInfo) * <+length> | >>
Abstraction outgoing: [$r3(android.net.wifi.WifiInfo) * <+length> | >>]
***************
Abstraction statement: $r4 = virtualinvoke $r6.<java.lang.StringBuilder: java.lang.String toString()>()
Abstraction taint: zero(null_type) <+length> | >>
Abstraction method: <com.pollfish.f.c: java.lang.String m(android.app.Activity)>
Abstraction incoming: $r3(android.net.wifi.WifiInfo) * <+length> | >>
Abstraction outgoing: [$r3(android.net.wifi.WifiInfo) * <+length> | >>]
***************
Abstraction statement: staticinvoke <com.pollfish.f.b: void b(java.lang.String,java.lang.String)>("PollfishUtilities", $r4)
Abstraction taint: zero(null_type) <+length> | >>
Abstraction method: <com.pollfish.f.c: java.lang.String m(android.app.Activity)>
Abstraction incoming: $r3(android.net.wifi.WifiInfo) * <+length> | >>
Abstraction outgoing: [$r3(android.net.wifi.WifiInfo) * <+length> | >>]
***************

I am hoping to explore new sinks for my APIs.