secure-software-engineering / FlowDroid

FlowDroid Static Data Flow Tracker
GNU Lesser General Public License v2.1
1.05k stars 298 forks source link

FlowDroid Unsound Callgraph #450

Open maryammsd opened 2 years ago

maryammsd commented 2 years ago

Hi, Consider the following case:

` public class MainActivity extends AppCompatActivity {

private Button btn1;

private final View.OnClickListener onClickListener =  v -> onClick2(v);

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    btn1 =  findViewById(R.id.button2);
    btn1.setOnClickListener(onClickListener);

}

public void onClick2(View v ){
    ...
}

}

`

Why flowdroid cannot add the callback onCLick2 to the callgraph and perform analysis over it?

StevenArzt commented 2 years ago

That should normally work. If it doesn't, it's a bug. Can you try to debug it? Have a look at AbstractCallbackAnalyzer.analyzeMethodForCallbackRegistrations. This method should detect the call to setOnClickListener and add it to the dummy main method.

maryammsd commented 2 years ago

I debug it, here is the list of callbacks: callback

It detects it as a callback but its key value is null. When I print out the dummy main method, there is no direct call to the callback in it.

`public static com.example.assertionsample1.MainActivity dummyMainMethod_com_example_assertionsample1_MainActivity(android.content.Intent) { int $i0; android.content.Intent parameter0; com.example.assertionsample1.MainActivity $r0;

    parameter0 := @parameter0: android.content.Intent;

    $i0 = 0;

 label1:
    if $i0 == 0 goto label9;

    $r0 = new com.example.assertionsample1.MainActivity;

    specialinvoke $r0.<com.example.assertionsample1.MainActivity: void <init>()>();

    $r0.<com.example.assertionsample1.MainActivity: android.content.Intent ipcIntent> = parameter0;

    virtualinvoke $r0.<com.example.assertionsample1.MainActivity: void onCreate(android.os.Bundle)>(null);

 label2:
    if $i0 == 1 goto label3;

 label3:
    virtualinvoke $r0.<androidx.fragment.app.FragmentActivity: void onResume()>();

 label4:
    if $i0 == 2 goto label7;

 label5:
    if $i0 == 3 goto label6;

    virtualinvoke $r0.<com.example.assertionsample1.MainActivity: void onNewIntent(android.content.Intent)>(null);

 label6:
    if $i0 == 4 goto label5;

 label7:
    if $i0 == 5 goto label4;

    virtualinvoke $r0.<androidx.fragment.app.FragmentActivity: void onPause()>();

    if $i0 == 6 goto label3;

    if $i0 == 7 goto label8;

    goto label2;

 label8:
    if $i0 == 8 goto label1;

 label9:
    return $r0;
}`

I find a new class called com.example.assertionsample1.MainActivity$$ExternalSyntheticLambda0 is created. In the constructor of the class com.example.assertionsample1.MainActivity which is com.example.assertionsample1.MainActivity: void <init>(), there is a call to it and the listener will be assigned. However, there is no direct call to the onClick callback. Now, this comes to my mind that why this callback is not added explicitly within the constructor or the dummy Main method? Is it a bug?

Here is the code snipped assigning setOnClickListener in function or constructor of MainActivity I mentioned above: specialinvoke r9.<com.example.assertionsample1.MainActivity$$ExternalSyntheticLambda0: void <init>(com.example.assertionsample1.MainActivity)>(r0); virtualinvoke r3.<android.widget.Button: void setOnClickListener(android.view.View$OnClickListener)>(r9);

maryammsd commented 2 years ago

here is my sample apk file. Is there specific setting to be used ?

maryammsd commented 2 years ago

@StevenArzt , I have new findings, would be happy to hear from you :)

JuggGit commented 2 years ago

I debug it, here is the list of callbacks: callback

It detects it as a callback but its key value is null. When I print out the dummy main method, there is no direct call to the callback in it.

`public static com.example.assertionsample1.MainActivity dummyMainMethod_com_example_assertionsample1_MainActivity(android.content.Intent) { int $i0; android.content.Intent parameter0; com.example.assertionsample1.MainActivity $r0;

    parameter0 := @parameter0: android.content.Intent;

    $i0 = 0;

 label1:
    if $i0 == 0 goto label9;

    $r0 = new com.example.assertionsample1.MainActivity;

    specialinvoke $r0.<com.example.assertionsample1.MainActivity: void <init>()>();

    $r0.<com.example.assertionsample1.MainActivity: android.content.Intent ipcIntent> = parameter0;

    virtualinvoke $r0.<com.example.assertionsample1.MainActivity: void onCreate(android.os.Bundle)>(null);

 label2:
    if $i0 == 1 goto label3;

 label3:
    virtualinvoke $r0.<androidx.fragment.app.FragmentActivity: void onResume()>();

 label4:
    if $i0 == 2 goto label7;

 label5:
    if $i0 == 3 goto label6;

    virtualinvoke $r0.<com.example.assertionsample1.MainActivity: void onNewIntent(android.content.Intent)>(null);

 label6:
    if $i0 == 4 goto label5;

 label7:
    if $i0 == 5 goto label4;

    virtualinvoke $r0.<androidx.fragment.app.FragmentActivity: void onPause()>();

    if $i0 == 6 goto label3;

    if $i0 == 7 goto label8;

    goto label2;

 label8:
    if $i0 == 8 goto label1;

 label9:
    return $r0;
}`

I find a new class called com.example.assertionsample1.MainActivity$$ExternalSyntheticLambda0 is created. In the constructor of the class com.example.assertionsample1.MainActivity which is com.example.assertionsample1.MainActivity: void <init>(), there is a call to it and the listener will be assigned. However, there is no direct call to the onClick callback. Now, this comes to my mind that why this callback is not added explicitly within the constructor or the dummy Main method? Is it a bug?

Here is the code snipped assigning setOnClickListener in function or constructor of MainActivity I mentioned above: specialinvoke r9.<com.example.assertionsample1.MainActivity$$ExternalSyntheticLambda0: void <init>(com.example.assertionsample1.MainActivity)>(r0); virtualinvoke r3.<android.widget.Button: void setOnClickListener(android.view.View$OnClickListener)>(r9);

perfect

Jennie2hang commented 8 months ago

Hello, I encountered the same problem. Did you manage to solve it later?

t1mlange commented 8 months ago

Hello, I encountered the same problem. Did you manage to solve it later?

I have fixed a problem with button callbacks some time ago that only occurred when the app was compiled with newer API versions. I think that fix is only available on the develop branch, but not yet included in any release. Which version of FlowDroid do you use?

Jennie2hang commented 8 months ago

Hello, I encountered the same problem. Did you manage to solve it later?

I have fixed a problem with button callbacks some time ago that only occurred when the app was compiled with newer API versions. I think that fix is only available on the develop branch, but not yet included in any release. Which version of FlowDroid do you use?

I used 2.12.0

t1mlange commented 8 months ago

Hello, I encountered the same problem. Did you manage to solve it later?

I have fixed a problem with button callbacks some time ago that only occurred when the app was compiled with newer API versions. I think that fix is only available on the develop branch, but not yet included in any release. Which version of FlowDroid do you use?

I used 2.12.0

Does the problem persist when using the newest develop commit or, alternatively, manually cherry-picking 4cd6c3a?