FlowDroid
FlowDroid copied to clipboard
FlowDroid Unsound Callgraph
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?
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.
I debug it, here is the list of callbacks:
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 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);
here is my sample apk file. Is there specific setting to be used ?
@StevenArzt , I have new findings, would be happy to hear from you :)
I debug it, here is the list of callbacks:
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 classcom.example.assertionsample1.MainActivity
which iscom.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
Hello, I encountered the same problem. Did you manage to solve it later?
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?
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
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?