FlowDroid icon indicating copy to clipboard operation
FlowDroid copied to clipboard

FlowDroid Unsound Callgraph

Open maryammsd opened this issue 2 years ago • 9 comments

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?

maryammsd avatar Mar 23 '22 12:03 maryammsd

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.

StevenArzt avatar Mar 23 '22 13:03 StevenArzt

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 avatar Mar 24 '22 02:03 maryammsd

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

maryammsd avatar Mar 24 '22 02:03 maryammsd

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

maryammsd avatar Mar 26 '22 14:03 maryammsd

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

JuggGit avatar Mar 31 '22 08:03 JuggGit

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

Jennie2hang avatar Jan 19 '24 13:01 Jennie2hang

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?

t1mlange avatar Jan 19 '24 14:01 t1mlange

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

Jennie2hang avatar Jan 19 '24 14:01 Jennie2hang

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?

t1mlange avatar Jan 19 '24 15:01 t1mlange