mirror of
https://github.com/emanuele-f/PCAPdroid.git
synced 2026-07-03 21:21:12 +08:00
Fix app not blocked after reinstallation
The package name to UID mapping was not updated after reinstallation, causing UID matching to fail and subsequent failure to block it. Now the UID mapping is automatically updated whenever an app is installed or uninstalled. Fixes #338
This commit is contained in:
parent
e2c5b81d4f
commit
68daa312bf
@ -509,17 +509,19 @@ public class CaptureService extends VpnService implements Runnable {
|
||||
if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
|
||||
boolean newInstall = !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
|
||||
String packageName = intent.getData().getSchemeSpecificPart();
|
||||
Log.i(TAG, "ACTION_PACKAGE_ADDED [new=" + newInstall + "]: " + packageName);
|
||||
|
||||
if(newInstall && Prefs.blockNewApps(mPrefs)) {
|
||||
Log.i(TAG, "Blocking newly installed app: " + packageName);
|
||||
mBlocklist.addApp(packageName);
|
||||
if(!mBlocklist.addApp(packageName))
|
||||
return;
|
||||
|
||||
mBlocklist.save();
|
||||
reloadBlocklist();
|
||||
|
||||
AppDescriptor app = AppsResolver.resolveInstalledApp(getPackageManager(), packageName, 0);
|
||||
String label = (app != null) ? app.getName() : packageName;
|
||||
|
||||
Log.i(TAG, "Blocking newly installed app: " + packageName + ((app != null) ? " - " + app.getUid() : ""));
|
||||
|
||||
PendingIntent pi = PendingIntent.getActivity(CaptureService.this, 0,
|
||||
new Intent(CaptureService.this, FirewallActivity.class), Utils.getIntentFlags(0));
|
||||
|
||||
|
||||
@ -20,7 +20,10 @@
|
||||
package com.emanuelef.remote_capture;
|
||||
|
||||
import android.app.Application;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.SharedPreferences;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
@ -92,6 +95,32 @@ public class PCAPdroid extends Application {
|
||||
theme = "system";
|
||||
}
|
||||
Utils.setAppTheme(theme);
|
||||
|
||||
// Listen to package events
|
||||
IntentFilter filter = new IntentFilter();
|
||||
filter.addAction(Intent.ACTION_PACKAGE_ADDED);
|
||||
filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
|
||||
filter.addDataScheme("package");
|
||||
registerReceiver(new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
|
||||
boolean newInstall = !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
|
||||
String packageName = intent.getData().getSchemeSpecificPart();
|
||||
Log.d(TAG, "ACTION_PACKAGE_ADDED [new=" + newInstall + "]: " + packageName);
|
||||
|
||||
if(newInstall)
|
||||
checkUidMapping(packageName);
|
||||
} else if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
|
||||
boolean isUpdate = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
|
||||
String packageName = intent.getData().getSchemeSpecificPart();
|
||||
Log.d(TAG, "ACTION_PACKAGE_REMOVED [update=" + isUpdate + "]: " + packageName);
|
||||
|
||||
if(!isUpdate)
|
||||
checkUidMapping(packageName);
|
||||
}
|
||||
}
|
||||
}, filter);
|
||||
}
|
||||
|
||||
public static @NonNull PCAPdroid getInstance() {
|
||||
@ -141,6 +170,31 @@ public class PCAPdroid extends Application {
|
||||
mFirewallWhitelist.save();
|
||||
}
|
||||
|
||||
private void checkUidMapping(String pkg) {
|
||||
if(mVisMask != null)
|
||||
mVisMask.uidMappingChanged(pkg);
|
||||
|
||||
// When an app is installed/uninstalled, recheck the UID mappings.
|
||||
// In particular:
|
||||
// - On app uninstall, invalidate any package_name -> UID mapping
|
||||
// - On app install, add the new package_name -> UID mapping
|
||||
if((mMalwareWhitelist != null) && mMalwareWhitelist.uidMappingChanged(pkg))
|
||||
CaptureService.reloadMalwareWhitelist();
|
||||
|
||||
if((mFirewallWhitelist != null) && mFirewallWhitelist.uidMappingChanged(pkg)) {
|
||||
if(CaptureService.isServiceActive())
|
||||
CaptureService.requireInstance().reloadFirewallWhitelist();
|
||||
}
|
||||
|
||||
if((mDecryptionList != null) && mDecryptionList.uidMappingChanged(pkg))
|
||||
CaptureService.reloadDecryptionList();
|
||||
|
||||
if((mBlocklist != null) && mBlocklist.uidMappingChanged(pkg)) {
|
||||
if(CaptureService.isServiceActive())
|
||||
CaptureService.requireInstance().reloadBlocklist();
|
||||
}
|
||||
}
|
||||
|
||||
public MatchList getFirewallWhitelist() {
|
||||
if(mFirewallWhitelist == null) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
|
||||
@ -60,6 +60,7 @@ public class MatchList {
|
||||
private final ArrayList<Rule> mRules = new ArrayList<>();
|
||||
private final ArrayMap<String, Rule> mMatches = new ArrayMap<>();
|
||||
private final ArraySet<Integer> mUids = new ArraySet<>();
|
||||
private final ArrayMap<String, Integer> mPackageToUid = new ArrayMap<>();
|
||||
private final AppsResolver mResolver;
|
||||
private boolean mMigration = false;
|
||||
|
||||
@ -314,6 +315,7 @@ public class MatchList {
|
||||
if(uid == Utils.UID_NO_FILTER)
|
||||
return false;
|
||||
|
||||
mPackageToUid.put(value, uid);
|
||||
mUids.add(uid);
|
||||
}
|
||||
|
||||
@ -352,9 +354,10 @@ public class MatchList {
|
||||
|
||||
if(rule.getType() == RuleType.APP) {
|
||||
int uid = mResolver.getUid(val);
|
||||
if(uid != Utils.UID_NO_FILTER)
|
||||
if(uid != Utils.UID_NO_FILTER) {
|
||||
mPackageToUid.remove(val);
|
||||
mUids.remove(uid);
|
||||
else
|
||||
} else
|
||||
Log.w(TAG, "removeRule: no uid found for package " + val);
|
||||
}
|
||||
|
||||
@ -417,6 +420,7 @@ public class MatchList {
|
||||
boolean hasRules = mRules.size() > 0;
|
||||
mRules.clear();
|
||||
mMatches.clear();
|
||||
mPackageToUid.clear();
|
||||
mUids.clear();
|
||||
|
||||
if(notify && hasRules)
|
||||
@ -510,4 +514,37 @@ public class MatchList {
|
||||
for(ListChangeListener listener: mListeners)
|
||||
listener.onListChanged();
|
||||
}
|
||||
|
||||
/* Call this whenever a package name -> uid mapping may have changed.
|
||||
* True is returned when the mapping has been updated. In such a case,
|
||||
* the caller must reload any native rules based on this MatchList. */
|
||||
public boolean uidMappingChanged(String pkg) {
|
||||
if(!mMatches.containsKey(matchKey(RuleType.APP, pkg)))
|
||||
return false;
|
||||
|
||||
boolean changed = false;
|
||||
Integer old_uid = mPackageToUid.get(pkg);
|
||||
AppDescriptor app = mResolver.getAppByPackage(pkg, 0);
|
||||
|
||||
if((old_uid != null) && ((app == null) || (app.getUid() != old_uid))) {
|
||||
Log.i(TAG, "Remove old UID mapping of " + pkg + ": " + old_uid);
|
||||
|
||||
mPackageToUid.remove(pkg);
|
||||
mUids.remove(old_uid);
|
||||
changed = true;
|
||||
|
||||
old_uid = null; // possibly add the new UID mapping below
|
||||
}
|
||||
|
||||
if((old_uid == null) && (app != null)) {
|
||||
int new_uid = app.getUid();
|
||||
Log.i(TAG, "Add UID mapping of " + pkg + ": " + new_uid);
|
||||
|
||||
mPackageToUid.put(pkg, new_uid);
|
||||
mUids.add(new_uid);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user