LinkScanner: performance improvements

Signed-off-by: Tavi <tavi@divested.dev>
This commit is contained in:
Tavi 2024-05-23 09:14:33 -04:00
parent ff2e34e49e
commit 8fb829ca6d
No known key found for this signature in database
GPG key ID: E599F62ECBAEAF2E
3 changed files with 29 additions and 19 deletions

View file

@ -18,7 +18,7 @@ public class LinkScannerService extends AccessibilityService {
private static final String hostnameRegex = "^((?!-)[A-Za-z0-9-]{1,63}(?<!-)\\.)+[A-Za-z]{2,6}$"; //Credit: http://www.mkyong.com/regular-expressions/domain-name-regular-expression-example/ private static final String hostnameRegex = "^((?!-)[A-Za-z0-9-]{1,63}(?<!-)\\.)+[A-Za-z]{2,6}$"; //Credit: http://www.mkyong.com/regular-expressions/domain-name-regular-expression-example/
private static final Pattern hostnamePattern = Pattern.compile(hostnameRegex); private static final Pattern hostnamePattern = Pattern.compile(hostnameRegex);
private static final ConcurrentSkipListSet<Integer> scannedObjects = new ConcurrentSkipListSet<>(); private static final ConcurrentSkipListSet<Integer> scannedText = new ConcurrentSkipListSet<>();
private static final ConcurrentSkipListSet<String> scannedDomains = new ConcurrentSkipListSet<>(); private static final ConcurrentSkipListSet<String> scannedDomains = new ConcurrentSkipListSet<>();
private NotificationManager notificationManager = null; private NotificationManager notificationManager = null;
@ -50,18 +50,20 @@ public class LinkScannerService extends AccessibilityService {
return; return;
} }
//Don't scan if we already did
int hash = mNodeInfo.toString().hashCode();
if (scannedObjects.contains(hash)) {
return;
} else {
scannedObjects.add(hash);
}
//Get and check the text //Get and check the text
String text = (String) mNodeInfo.getText(); String text = (String) mNodeInfo.getText();
if (text != null && text.contains(".")) { if (text != null && text.contains(".") && text.length() < 10000) {
scanText(text.toLowerCase()); //Don't scan text if we already did
int hashDomain = mNodeInfo.getText().hashCode();
if (scannedText.contains(hashDomain)) {
return;
} else {
if (scannedText.size() > 10000) {
scannedText.clear();
}
scannedText.add(hashDomain);
scanText(text.toLowerCase());
}
} }
//Finish if no more children //Finish if no more children
@ -80,12 +82,7 @@ public class LinkScannerService extends AccessibilityService {
private void scanText(String haystack) { private void scanText(String haystack) {
Matcher matcher = hostnamePattern.matcher(haystack); Matcher matcher = hostnamePattern.matcher(haystack);
while (matcher.find()) { while (matcher.find()) {
if (!scannedDomains.contains(matcher.group())) { scanDomain(matcher.group());
scannedDomains.add(matcher.group());
if (Database.domains.mightContain(matcher.group())) {
sendNotification(matcher.group());
}
}
} }
if (haystack.contains("/")) { if (haystack.contains("/")) {
for (String split : haystack.split("/")) { for (String split : haystack.split("/")) {
@ -94,6 +91,19 @@ public class LinkScannerService extends AccessibilityService {
} }
} }
private void scanDomain(String domain) {
//Don't scan domain if we already did
if (!scannedDomains.contains(domain)) {
if (scannedDomains.size() > 1000) {
scannedDomains.clear();
}
scannedDomains.add(domain);
if (Database.domains.mightContain(domain)) {
sendNotification(domain);
}
}
}
private void sendNotification(String link) { private void sendNotification(String link) {
link = link.replaceAll("\\.", "[.]"); link = link.replaceAll("\\.", "[.]");
Notification.Builder mBuilder = Notification.Builder mBuilder =

View file

@ -83,5 +83,5 @@
<string name="lblNotificationLinkDetection">Malicious Link Detected:</string> <string name="lblNotificationLinkDetection">Malicious Link Detected:</string>
<string name="lblLinkScannerToggle">Link Scanner</string> <string name="lblLinkScannerToggle">Link Scanner</string>
<string name="confirm_link_scanner_title">Enable link scanner?</string> <string name="confirm_link_scanner_title">Enable link scanner?</string>
<string name="confirm_link_scanner_summary">[EXPERIMENTAL]\nThis will download an additional database of domains.\nAny domains found in screen content will be checked against the database.\nThis requires granting accessibility service permission manually.</string> <string name="confirm_link_scanner_summary">[EXPERIMENTAL]\nThis will download an additional database of domains.\nAny domains found in screen content will be checked against the database.\nThis requires granting accessibility service permission manually.\nThis can have a substantial performance impact on screen with large amounts of text.</string>
</resources> </resources>

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android" <accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
android:description="@string/accessibility_service_description" android:description="@string/accessibility_service_description"
android:accessibilityEventTypes="typeAllMask" android:accessibilityEventTypes="typeWindowContentChanged|typeViewTextChanged"
android:accessibilityFlags="flagDefault" android:accessibilityFlags="flagDefault"
android:accessibilityFeedbackType="feedbackGeneric" android:accessibilityFeedbackType="feedbackGeneric"
android:notificationTimeout="1" android:notificationTimeout="1"