Merge branch 'Divested-Mobile:stable' into stable

This commit is contained in:
Manuel-Senpai 2023-12-12 12:40:04 +00:00 committed by GitHub
commit fe8b482cf5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
47 changed files with 2059 additions and 803 deletions

2
.idea/compiler.xml generated
View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="11" />
<bytecodeTargetLevel target="17" />
</component>
</project>

1
.idea/gradle.xml generated
View file

@ -8,6 +8,7 @@
<option name="testRunner" value="GRADLE" />
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="Embedded JDK" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />

3
.idea/misc.xml generated
View file

@ -1,4 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DesignSurface">
<option name="filePathToZoomLevelMap">
@ -54,7 +53,7 @@
</value>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="JDK" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" project-jdk-name="jbr-17" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">

View file

@ -43,7 +43,6 @@ Geplante Updates
- Automatische Datenbank-Updates
- Automatische Datenbankerstellung
- Client-seitige Datenbank-Generierung
- Überprüfung der Datenbanksignatur
- Datenbank-Sanity-Checks
- Prüfung
- Bessere GUI

View file

@ -52,7 +52,7 @@ Crédits
- ESET pour les bases de données supplémentaires (BSD 2-Clause)
- RecursiveFileObserver.java (GPLv3): Daniel Gultsch, ownCloud Inc, Bartek Przybylski
- Petra Mirelli pour les traductions allemandes et la bannière/le graphique de l'application.
- Symboles : Google/Android/AOSP, Licence: Apache 2.0, https://google.github.io/material-design-icons/
- Symboles: Google/Android/AOSP, Licence: Apache 2.0, https://google.github.io/material-design-icons/
Avis
-------

View file

@ -45,7 +45,6 @@ Planned Updates
- Automatic database updates
- Automatic database generation
- Client side database generation
- Database signature verification
- Database sanity checks
- Testing
- Better GUI
@ -65,7 +64,9 @@ Credits
- ESET for extra databases (BSD 2-Clause)
- Nex (@botherder) for extra databases (CC BY-SA 4.0)
- Amnesty International for extra databases (CC BY 2.0)
- RecursiveFileObserver.java (GPLv3): Daniel Gultsch, ownCloud Inc., Bartek Przybylski
- Echap for extra databases (CC BY 4.0)
- RecursiveFileObserver.java (GPL-3.0-or-later): Daniel Gultsch, ownCloud Inc., Bartek Przybylski
- GPGDetachedSignatureVerifier.java (GPL-2.0-or-later): Federico Fissore, Arduino LLC
- Petra Mirelli for the German/Spanish/Italian translations, the app banner/feature graphic, and various tweaks.
- Jean-Luc Tibaux and Petra Mirelli for the French translations.
- @srccrow for the Italian translations.
@ -75,7 +76,12 @@ Credits
- Oswald van Ginkel for the Afrikaans translations.
- huuhaa for the Finnish translations.
- Marcin Mikołajczak for Polish translations.
- @senpai33 for the Spanish translations.
- @Manuel-Senpai for the Spanish translations.
- @Balthazar1234 for German translations.
- @Sdarfeesh for the simplified Chinese translations.
- @cardpuncher for French and the Turkish translations.
- Tommaso Fonda for Italian translations.
- Dimitris Vagiakakos for the Greek translations.
- Icons: Google/Android/AOSP, License: Apache 2.0, https://google.github.io/material-design-icons/
Notices

View file

@ -43,7 +43,6 @@ Planowane aktualizacje
- Automatyczne aktualizacje baz danych
- Automatyczne generowanie baz danych
- Generowanie baz danych przez klienta
- Weryfikacja podpisów baz danych
- Kontrola poprawności baz danych
- Testy
- Lepsze GUI

View file

@ -6,9 +6,9 @@ android {
applicationId "us.spotco.malwarescanner"
minSdkVersion 16
targetSdkVersion 32
versionCode 91
versionName "2.28"
resConfigs 'en', 'af', 'de', 'es', 'fi', 'fr', 'it', 'pl', 'pt', 'ru'
versionCode 105
versionName "2.32"
resConfigs 'en', 'af', 'de', 'el', 'es', 'fi', 'fr', 'it', 'pl', 'pt', 'ru', 'tr', 'zh-rCN'
}
buildTypes {
debug {
@ -29,6 +29,6 @@ android {
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.5.1'
implementation 'com.google.android.material:material:1.6.1'
implementation 'commons-io:commons-io:2.5'
implementation 'org.bouncycastle:bcpg-jdk15to18:1.73'
}

View file

@ -18,14 +18,13 @@
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme"
android:theme="@android:style/Theme.DeviceDefault"
android:largeHeap="true"
android:requestLegacyExternalStorage="true">
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar"
android:screenOrientation="portrait"
android:configChanges="orientation|keyboardHidden"
android:exported="true">

View file

@ -20,6 +20,7 @@ package us.spotco.malwarescanner;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.TextView;
import java.io.BufferedReader;
@ -72,12 +73,15 @@ class Database {
public static void updateDatabase(Context context, ConcurrentLinkedQueue<SignatureDatabase> signatureDatabases) {
initDatabase(context);
log.append(context.getString(R.string.main_database_updating, signatureDatabases.size() + "") + "\n");
if(!Utils.getDatabaseURL(context).equals(Utils.DATABASE_URL_DEFAULT)) {
if (!Utils.getDatabaseURL(context).equals(Utils.DATABASE_URL_DEFAULT)) {
log.append(context.getString(R.string.main_database_override, Utils.getDatabaseURL(context)) + "\n");
}
for (SignatureDatabase signatureDatabase : signatureDatabases) {
boolean onionRouting = prefs.getBoolean("ONION_ROUTING", false);
new Downloader().executeOnExecutor(Utils.getThreadPoolExecutor(), onionRouting, Utils.getDatabaseURL(context) + "gpg.key", databasePath + "/gpg.key", Utils.getDatabaseURL(context));
for (SignatureDatabase signatureDatabase : signatureDatabases) {
new Downloader().executeOnExecutor(Utils.getThreadPoolExecutor(), onionRouting, signatureDatabase.getUrl(), databasePath + "/" + signatureDatabase.getName(), signatureDatabase.getBaseUrl());
new Downloader().executeOnExecutor(Utils.getThreadPoolExecutor(), onionRouting, signatureDatabase.getUrl() + ".sig", databasePath + "/" + signatureDatabase.getName() + ".sig", signatureDatabase.getBaseUrl());
}
}
@ -96,6 +100,9 @@ class Database {
if (prefs.getBoolean("SIGNATURES_AMNESTY", true)) {
signatureDatabases.add(new SignatureDatabase(baseURL, "amnesty.hsb.gz"));
}
if (prefs.getBoolean("SIGNATURES_STALKERWARE", true)) {
signatureDatabases.add(new SignatureDatabase(baseURL, "stalkerware.hsb.gz"));
}
if (prefs.getBoolean("SIGNATURES_ESET", true)) {
signatureDatabases.add(new SignatureDatabase(baseURL, "eset.hdb.gz"));
signatureDatabases.add(new SignatureDatabase(baseURL, "eset.hsb.gz"));
@ -123,10 +130,16 @@ class Database {
signaturesSHA1.clear();
signaturesSHA256.clear();
System.gc();
File publicKey = new File(databasePath + "/gpg.key");
GPGDetachedSignatureVerifier verifier = new GPGDetachedSignatureVerifier(Utils.getSigningKey(context));
for (SignatureDatabase database : signatureDatabases) {
File databaseLocation = new File(databasePath + "/" + database.getName());
if (databaseLocation.exists()) {
File databaseSigLocation = new File(databasePath + "/" + database.getName() + ".sig");
if (publicKey.exists() && databaseLocation.exists() && databaseSigLocation.exists()) {
try {
boolean validated = verifier.verify(databaseLocation, databaseSigLocation, publicKey);
if (validated) {
Log.d("Hypatia", "Successfully validated database");
BufferedReader reader;
if (databaseLocation.getName().endsWith(".gz")) {
reader = new BufferedReader(new InputStreamReader(new GZIPInputStream(new FileInputStream(databaseLocation))));
@ -156,6 +169,9 @@ class Database {
}
}
reader.close();
} else {
Log.w("Hypatia", "Failed to validate database");
}
} catch (Exception e) {
e.printStackTrace();
}

View file

@ -0,0 +1,133 @@
/*
* Source: https://github.com/arduino/Arduino/blob/master/arduino-core/src/cc/arduino/contributions/GPGDetachedSignatureVerifier.java
* This file is part of Arduino.
*
* Copyright 2015 Arduino LLC (http://www.arduino.cc/)
*
* Arduino is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*/
package us.spotco.malwarescanner;
import android.util.Log;
import org.apache.commons.io.IOUtils;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPObjectFactory;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
import org.bouncycastle.openpgp.PGPSignature;
import org.bouncycastle.openpgp.PGPSignatureList;
import org.bouncycastle.openpgp.PGPUtil;
import org.bouncycastle.openpgp.operator.bc.BcKeyFingerprintCalculator;
import org.bouncycastle.openpgp.operator.bc.BcPGPContentVerifierBuilderProvider;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
public class GPGDetachedSignatureVerifier {
private final String keyId;
public GPGDetachedSignatureVerifier() {
this(Utils.SIGNING_KEY_DEFAULT);
}
public GPGDetachedSignatureVerifier(String keyId) {
this.keyId = keyId;
}
public boolean verify(File signedFile, File signature, File publicKey) throws IOException {
FileInputStream signatureInputStream = null;
FileInputStream signedFileInputStream = null;
try {
signatureInputStream = new FileInputStream(signature);
PGPObjectFactory pgpObjectFactory = new PGPObjectFactory(signatureInputStream, new BcKeyFingerprintCalculator());
Object nextObject;
try {
nextObject = pgpObjectFactory.nextObject();
if (!(nextObject instanceof PGPSignatureList)) {
return false;
}
} catch (IOException e) {
return false;
}
PGPSignatureList pgpSignatureList = (PGPSignatureList) nextObject;
assert pgpSignatureList.size() == 1;
PGPSignature pgpSignature = pgpSignatureList.get(0);
PGPPublicKey pgpPublicKey = readPublicKey(publicKey, keyId);
pgpSignature.init(new BcPGPContentVerifierBuilderProvider(), pgpPublicKey);
signedFileInputStream = new FileInputStream(signedFile);
pgpSignature.update(IOUtils.toByteArray(signedFileInputStream));
return pgpSignature.verify();
} catch (PGPException e) {
throw new IOException(e);
} finally {
if (signatureInputStream != null) {
signatureInputStream.close();
}
if (signedFileInputStream != null) {
signedFileInputStream.close();
}
}
}
private PGPPublicKey readPublicKey(File file, String id) throws IOException, PGPException {
try (InputStream keyIn = new BufferedInputStream(new FileInputStream(file))) {
return readPublicKey(keyIn, id);
}
}
private PGPPublicKey readPublicKey(InputStream input, String id) throws IOException, PGPException {
PGPPublicKeyRingCollection pgpPub = new PGPPublicKeyRingCollection(PGPUtil.getDecoderStream(input), new BcKeyFingerprintCalculator());
Iterator<PGPPublicKeyRing> keyRingIter = pgpPub.getKeyRings();
while (keyRingIter.hasNext()) {
PGPPublicKeyRing keyRing = keyRingIter.next();
Iterator<PGPPublicKey> keyIter = keyRing.getPublicKeys();
while (keyIter.hasNext()) {
PGPPublicKey key = keyIter.next();
if (Long.toHexString(key.getKeyID()).toUpperCase().endsWith(id)) {
return key;
} else {
Log.d("Hypatia", "readPublicKey: No match found, have key: " + Long.toHexString(key.getKeyID()).toUpperCase());
}
}
}
throw new IllegalArgumentException("Can't find encryption key in key ring.");
}
}

View file

@ -20,15 +20,14 @@ package us.spotco.malwarescanner;
import static android.os.Build.VERSION.SDK_INT;
import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.res.ColorStateList;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
@ -43,23 +42,16 @@ import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.appcompat.widget.Toolbar;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import java.io.File;
import java.util.HashSet;
public class MainActivity extends AppCompatActivity {
public class MainActivity extends Activity {
private SharedPreferences prefs = null;
private MalwareScanner malwareScanner = null;
private TextView logView;
private Menu menu;
private static final String buildVersionName = BuildConfig.VERSION_NAME;
@ -72,12 +64,15 @@ public class MainActivity extends AppCompatActivity {
@Override
protected final void onCreate(Bundle savedInstanceState) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
setTheme(android.R.style.Theme_DeviceDefault_DayNight);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
}
super.onCreate(savedInstanceState);
Utils.setContext(getApplicationContext());
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
setContentView(R.layout.content_main);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
@ -94,17 +89,6 @@ public class MainActivity extends AppCompatActivity {
prefs = getSharedPreferences(BuildConfig.APPLICATION_ID, Context.MODE_PRIVATE);
final FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(view -> {
if (!malwareScanner.running) {
startScanner();
} else {
logView.append("\n" + getString(R.string.main_cancelling_scan) + "\n\n");
malwareScanner.cancel(true);
malwareScanner.running = false;
}
});
requestPermissions();
Utils.considerStartService(this);
@ -113,14 +97,18 @@ public class MainActivity extends AppCompatActivity {
@Override
public final boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
this.menu = menu;
menu.findItem(R.id.toggleRealtime).setChecked(Utils.isServiceRunning(MalwareScannerService.class, this));
menu.findItem(R.id.toggleOnionRouting).setChecked(prefs.getBoolean("ONION_ROUTING", false));
updateScanButton(false);
return true;
}
private void requestPermissions() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, REQUEST_PERMISSION_EXTERNAL_STORAGE);
if (SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, REQUEST_PERMISSION_EXTERNAL_STORAGE);
}
}
if (SDK_INT >= Build.VERSION_CODES.R) {
if (!Environment.isExternalStorageManager()) {
@ -161,14 +149,16 @@ public class MainActivity extends AppCompatActivity {
localizeDBDescription("ClamAV: Daily\n • SIZE: SIZE_LARGE\n • LICENSE: GPL-2.0\n • AUTHOR: Cisco\n • SOURCE: https://clamav.net\n"),
localizeDBDescription("ESET\n • SIZE: SIZE_SMALL\n • LICENSE: BSD 2-Clause\n • AUTHOR: ESET\n • SOURCE: https://github.com/eset/malware-ioc\n"),
localizeDBDescription("Targeted Threats\n • SIZE: SIZE_SMALL\n • LICENSE: CC BY-SA 4.0\n • AUTHOR: Nex\n • SOURCE: https://github.com/botherder/targetedthreats\n"),
localizeDBDescription("Amnesty Tech Investigations\n • SIZE: SIZE_SMALL\n • LICENSE: CC BY 2.0\n • AUTHOR: Amnesty International\n • SOURCE: https://github.com/amnestytech/investigations")};
localizeDBDescription("Amnesty Tech Investigations\n • SIZE: SIZE_SMALL\n • LICENSE: CC BY 2.0\n • AUTHOR: Amnesty International\n • SOURCE: https://github.com/amnestytech/investigations\n"),
localizeDBDescription("Stalkerware\n • SIZE: SIZE_SMALL\n • LICENSE: CC BY 4.0\n • AUTHOR: Echap\n • SOURCE: https://github.com/AssoEchap/stalkerware-indicators")};
final boolean[] databaseDefaults = {
prefs.getBoolean("SIGNATURES_CLAMAV-ANDROID", true),
prefs.getBoolean("SIGNATURES_CLAMAV-MAIN", false),
prefs.getBoolean("SIGNATURES_CLAMAV-DAILY", false),
prefs.getBoolean("SIGNATURES_ESET", true),
prefs.getBoolean("SIGNATURES_TARGETEDTHREATS", true),
prefs.getBoolean("SIGNATURES_AMNESTY", true)};
prefs.getBoolean("SIGNATURES_AMNESTY", true),
prefs.getBoolean("SIGNATURES_STALKERWARE", true)};
Dialog databaseDialog;
AlertDialog.Builder databaseBuilder = new AlertDialog.Builder(this);
@ -182,6 +172,7 @@ public class MainActivity extends AppCompatActivity {
prefs.edit().putBoolean("SIGNATURES_ESET", databaseDefaults[3]).apply();
prefs.edit().putBoolean("SIGNATURES_TARGETEDTHREATS", databaseDefaults[4]).apply();
prefs.edit().putBoolean("SIGNATURES_AMNESTY", databaseDefaults[5]).apply();
prefs.edit().putBoolean("SIGNATURES_STALKERWARE", databaseDefaults[6]).apply();
});
databaseDialog = databaseBuilder.create();
@ -207,42 +198,57 @@ public class MainActivity extends AppCompatActivity {
}
break;
case R.id.mnuUpdateDatabase:
if (malwareScanner.running) {
logView.append(getString(R.string.lblScanRunning) + "\n");
} else {
if (prefs.getBoolean("ONION_ROUTING", false)) {
Utils.requestStartOrbot(this);
logView.append(getString(R.string.lblOnionRoutingEnabledHint) + "\n");
}
updateDatabase();
}
break;
case R.id.mnuSelectDatabases:
selectDatabases();
break;
case R.id.mnuDatabaseServer:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(getString(R.string.lblDatabaseServer));
final EditText input = new EditText(this);
input.setInputType(InputType.TYPE_CLASS_TEXT);
input.setText(Utils.getDatabaseURL(this));
builder.setView(input);
builder.setPositiveButton(getString(R.string.lblOverride), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String newServer = input.getText().toString();
if(!newServer.endsWith("/")) {
AlertDialog.Builder builderServerOverride = new AlertDialog.Builder(this);
builderServerOverride.setTitle(getString(R.string.lblDatabaseServer));
final EditText inputServerOverride = new EditText(this);
inputServerOverride.setInputType(InputType.TYPE_CLASS_TEXT);
inputServerOverride.setText(Utils.getDatabaseURL(this));
builderServerOverride.setView(inputServerOverride);
builderServerOverride.setPositiveButton(getString(R.string.lblOverride), (dialog, which) -> {
String newServer = inputServerOverride.getText().toString();
if (!newServer.endsWith("/")) {
newServer += "/";
}
prefs.edit().putString("DATABASE_SERVER", newServer).apply();
}
});
builder.setNegativeButton(getString(R.string.lblReset), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
builderServerOverride.setNegativeButton(getString(R.string.lblReset), (dialog, which) -> {
prefs.edit().putString("DATABASE_SERVER", Utils.DATABASE_URL_DEFAULT).apply();
dialog.cancel();
}
});
builder.show();
builderServerOverride.show();
break;
case R.id.mnuSigningKey:
AlertDialog.Builder builderKey = new AlertDialog.Builder(this);
builderKey.setTitle(getString(R.string.lblSigningKey));
final EditText inputKey = new EditText(this);
inputKey.setInputType(InputType.TYPE_CLASS_TEXT);
inputKey.setText(Utils.getSigningKey(this));
builderKey.setView(inputKey);
builderKey.setPositiveButton(getString(R.string.lblOverride), (dialog, which) -> prefs.edit().putString("SIGNING_KEY", inputKey.getText().toString()).apply());
builderKey.setNegativeButton(getString(R.string.lblReset), (dialog, which) -> {
prefs.edit().putString("SIGNING_KEY", Utils.SIGNING_KEY_DEFAULT).apply();
dialog.cancel();
});
builderKey.show();
break;
case R.id.toggleRealtime:
if (malwareScanner.running) {
logView.append(getString(R.string.lblScanRunning) + "\n");
} else {
Intent realtimeScanner = new Intent(getApplicationContext(), MalwareScannerService.class);
if (!item.isChecked()) {
prefs.edit().putBoolean("autostart", true).apply();
@ -252,6 +258,7 @@ public class MainActivity extends AppCompatActivity {
prefs.edit().putBoolean("autostart", false).apply();
}
item.setChecked(!item.isChecked());
}
break;
case R.id.mnuScanSystem:
scanSystem = !item.isChecked();
@ -272,6 +279,15 @@ public class MainActivity extends AppCompatActivity {
case R.id.mnuFullCredits:
showCredits();
break;
case R.id.btnStartScan:
if (!malwareScanner.running) {
updateScanButton(true);
startScanner();
} else {
logView.append("\n" + getString(R.string.main_cancelling_scan) + "\n\n");
malwareScanner.cancel(true);
malwareScanner.running = false;
}
}
return super.onOptionsItemSelected(item);
}
@ -294,15 +310,48 @@ public class MainActivity extends AppCompatActivity {
if (scanExternal) {
filesToScan.add(new File("/storage"));
}
malwareScanner.executeOnExecutor(Utils.getThreadPoolExecutor(), filesToScan);
new Thread(() -> {
try {
while (malwareScanner.running) {
Thread.sleep(500);
}
runOnUiThread(() -> updateScanButton(false));
} catch (Exception e) {
e.printStackTrace();
}
}).start();
}
private void updateDatabase() {
new Database((TextView) findViewById(R.id.txtLogOutput));
new Database(findViewById(R.id.txtLogOutput));
Database.updateDatabase(this, Database.signatureDatabases);
if (Database.isDatabaseLoaded()) {
Utils.getThreadPoolExecutor().execute(() -> Database.loadDatabase(getApplicationContext(), true, Database.signatureDatabases));
}
}
private void updateScanButton(boolean running) {
if (menu == null || menu.findItem(R.id.btnStartScan) == null) {
return;
}
if (running) {
if (SDK_INT >= Build.VERSION_CODES.O) {
menu.findItem(R.id.btnStartScan).setIconTintList(getColorStateList(R.color.colorRed));
}
if (SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
menu.findItem(R.id.btnStartScan).setIcon(getDrawable(android.R.drawable.ic_menu_close_clear_cancel));
}
} else {
if (SDK_INT >= Build.VERSION_CODES.O) {
menu.findItem(R.id.btnStartScan).setIconTintList(getColorStateList(R.color.colorGreen));
}
if (SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
menu.findItem(R.id.btnStartScan).setIcon(getDrawable(android.R.drawable.ic_media_play));
}
}
}
}

View file

@ -28,8 +28,6 @@ import android.os.Environment;
import android.os.SystemClock;
import android.widget.TextView;
import androidx.core.app.NotificationCompat;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
@ -78,15 +76,15 @@ class MalwareScanner extends AsyncTask<HashSet<File>, Object, String> {
}
} else if (!userFacingOnly) {
String[] malwareDetect = result.split(" in ");
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(context)
Notification.Builder mBuilder =
new Notification.Builder(context)
.setSmallIcon(R.drawable.ic_notification)
.setContentTitle(context.getText(R.string.lblNotificationRealtimeDetection) + " " + malwareDetect[0])
.setContentText(malwareDetect[1])
.setPriority(Notification.PRIORITY_MAX)
.setDefaults(Notification.DEFAULT_VIBRATE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mBuilder.setVisibility(NotificationCompat.VISIBILITY_SECRET);
mBuilder.setVisibility(Notification.VISIBILITY_SECRET);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
mBuilder.setChannelId("DETECTION");

View file

@ -29,8 +29,6 @@ import android.os.FileObserver;
import android.os.IBinder;
import android.widget.Toast;
import androidx.core.app.NotificationCompat;
import java.io.File;
import java.text.NumberFormat;
import java.util.HashSet;
@ -40,7 +38,7 @@ public class MalwareScannerService extends Service {
private final HashSet<RecursiveFileObserver> malwareMonitors = new HashSet<>();
private ThreadPoolExecutor threadPoolExecutor = null;
private NotificationCompat.Builder foregroundNotification = null;
private Notification.Builder foregroundNotification = null;
private NotificationManager notificationManager = null;
@Override
@ -105,7 +103,7 @@ public class MalwareScannerService extends Service {
private void setForeground() {
foregroundNotification =
new NotificationCompat.Builder(this)
new Notification.Builder(this)
.setSmallIcon(R.drawable.ic_notification)
.setContentTitle(getText(R.string.lblNotificationRealtimeTitle))
.setContentText(getText(R.string.lblNotificationRealtimeText))

View file

@ -35,6 +35,8 @@ class SignatureDatabase {
return name;
}
public final String getUrl() { return baseURL + name; }
public final String getUrl() {
return baseURL + name;
}
}

View file

@ -38,8 +38,9 @@ class Utils {
public final static int MAX_SCAN_SIZE = (1000 * 1000) * 80; //80MB
public final static int MAX_SCAN_SIZE_REALTIME = MAX_SCAN_SIZE / 2; //40MB
public final static String DATABASE_URL_DEFAULT = "https://divested.dev/MalwareScannerSignatures/";
public final static String SIGNING_KEY_DEFAULT = "BADFCABDDBF5B694";
public final static int MAX_HASH_LENGTH = 10;
public final static int MAX_HASH_LENGTH = 12;
public static final AtomicInteger FILES_SCANNED = new AtomicInteger();
private static ThreadPoolExecutor threadPoolExecutor = null;
@ -52,7 +53,7 @@ class Utils {
}
public static ThreadPoolExecutor getNewThreadPoolExecutor(int threads) {
return new ThreadPoolExecutor(threads, threads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(16), new ThreadPoolExecutor.CallerRunsPolicy());
return new ThreadPoolExecutor(threads, threads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(32), new ThreadPoolExecutor.CallerRunsPolicy());
}
public static int getMaxThreads() {
@ -60,7 +61,7 @@ class Utils {
if (maxThreads > 4) {
maxThreads = 4;
}
if(maxThreads < 2) {
if (maxThreads < 2) {
maxThreads = 2;
}
return maxThreads;
@ -104,6 +105,11 @@ class Utils {
return prefs.getString("DATABASE_SERVER", DATABASE_URL_DEFAULT);
}
public static String getSigningKey(Context context) {
SharedPreferences prefs = context.getSharedPreferences(BuildConfig.APPLICATION_ID, Context.MODE_PRIVATE);
return prefs.getString("SIGNING_KEY", SIGNING_KEY_DEFAULT);
}
public static void considerStartService(Context context) {
if (!Utils.isServiceRunning(MalwareScannerService.class, context)) {
SharedPreferences prefs = context.getSharedPreferences(BuildConfig.APPLICATION_ID, Context.MODE_PRIVATE);

View file

@ -1,33 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="us.spotco.malwarescanner.MainActivity">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</com.google.android.material.appbar.AppBarLayout>
<include layout="@layout/content_main" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="@dimen/fab_margin"
app:srcCompat="@android:drawable/ic_media_play" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View file

@ -2,6 +2,11 @@
xmlns:tools="http://schemas.android.com/tools"
tools:context="us.spotco.malwarescanner.MainActivity">
<item
android:id="@+id/btnStartScan"
android:title="@string/scan_control"
android:icon="@android:drawable/ic_media_play"
android:showAsAction="always"/>
<item
android:id="@+id/toggleOnionRouting"
android:title="@string/lblOnionRoutingToggle"
@ -15,6 +20,9 @@
<item
android:id="@+id/mnuDatabaseServer"
android:title="@string/lblDatabaseServer" />
<item
android:id="@+id/mnuSigningKey"
android:title="@string/lblSigningKey" />
<item
android:id="@+id/toggleRealtime"
android:title="@string/lblRealtimeScannerToggle"

View file

@ -4,45 +4,53 @@
<string name="app_version">Versionsnummer: %s</string>
<string name="app_db_type_clamav">Basierend auf Signaturen im Stil von ClamAV</string>
<string name="lblOnionRoutingToggle">Download über Tor</string>
<string name="lblOnionRoutingEnabledHint">Download über Tor wurde ausgewählt, das kann etwas länger dauern. Bitte haben sie Geduld...</string>
<string name="lblOnionRoutingToggle">Über Tor laden</string>
<string name="lblOnionRoutingEnabledHint">Herunterladen wird zur Anonymisierung über das Tor-Netzwerk geleitet und kann daher länger dauern.</string>
<string name="lblOnionRoutingNotInstalled">Orbot ist nicht installiert!</string>
<string name="lblOnionRoutingNotRunning">Orbot läuft nicht!</string>
<string name="lblUpdateDatabase">Datenbanken aktualisieren</string>
<string name="lblSelectDatabases">Datenbanken auswählen</string>
<string name="lblSelectDatabasesTitle">Bitte gewünschte Datenbanken auswählen</string>
<string name="lblOnionRoutingNotRunning">Orbot wird nicht ausgeführt!</string>
<string name="lblUpdateDatabase">Datenbank aktualisieren</string>
<string name="lblSelectDatabases">Datenbank auswählen</string>
<string name="lblSelectDatabasesTitle">Zu aktivierende Datenbank(en) auswählen (Vorauswahl ausreichend)</string>
<string name="lblDatabaseServer">Datenbankserver überschreiben</string>
<string name="lblFullCredits">Mitwirkende</string>
<string name="lblScanSystem">/system scannen</string>
<string name="lblScanApps">APK-Dateien scannen</string>
<string name="lblScanInternal">Internen Speicher scannen</string>
<string name="lblScanExternal">Externen Speicher scannen</string>
<string name="lblNotificationMalwareDetectionTitle">Malware-Erkennung</string>
<string name="lblNotificationMalwareDetectionDescription">Dient zur Warnung in Echtzeit wenn Malware erkannt wird</string>
<string name="lblNotificationMalwareDetectionTitle">Schadsoftware-Erkennung</string>
<string name="lblNotificationMalwareDetectionDescription">Dient zur Warnung in Echtzeit wenn Schadsoftware erkannt wird</string>
<string name="lblNotificationRealtimeTitle">Echtzeit-Scanner</string>
<string name="lblNotificationRealtimeText">Bekannte Malware wird in Echtzeit erkannt</string>
<string name="lblNotificationRealtimeDescription">Dient dazu bereits durchsuchte Dateien aufzuzählen und den Echtzeit-Scanner aktiv zu halten</string>
<string name="lblNotificationRealtimeText">Bekannte Schadsoftware wird in Echtzeit erkannt</string>
<string name="lblNotificationRealtimeStopped">Hypatia: Echtzeit-Scanner wurde gestoppt</string>
<string name="lblNotificationRealtimeDetection">Malware gefunden:</string>
<string name="lblNotificationRealtimeDetection">Schadsoftware gefunden:</string>
<string name="lblRealtimeScannerToggle">Echtzeit-Scanner</string>
<string name="lblReset">Zurücksetzen</string>
<string name="lblOverride">Überschreiben</string>
<string name="main_database_updating">Update von %s Datenbank(en) ...</string>
<string name="main_database_downloading">Download von %s</string>
<string name="main_database_updating">%s Datenbank(en) wird/werden aktualisiert...</string>
<string name="main_database_override">Datenbankserver %s wird genutzt</string>
<string name="main_database_downloading">Lade %s herunter</string>
<string name="main_database_download_success">Erfolgreich heruntergeladen</string>
<string name="main_database_download_error">Datei wurde nicht heruntergeladen. Fehlercode %s</string>
<string name="main_no_database_available">Keine Datenbank verfügbar. Scan wird abgebrochen...</string>
<string name="main_database_download_error">Datenbank(en) nicht heruntergeladen. Fehlernummer %s</string>
<string name="main_no_database_available">Datenbank(en) nicht verfügbar. Schadsoftware-Prüfung nicht möglich...</string>
<string name="main_database_released_on">Veröffentlicht am %s</string>
<string name="main_database_not_changed">Datei wurde nicht geändert</string>
<string name="main_database_not_changed">Keine Veränderung der Datenbank(en)</string>
<string name="main_database_not_modified_since">seit %s</string>
<string name="main_database_download_error_logcat">Download ist fehlgeschlagen. Für weitere Details bitte in logcat nachsehen</string>
<string name="main_database_download_error_logcat">Herunterladen ist fehlgeschlagen. Details können im logcat eingesehen werden</string>
<string name="main_starting_scan">Scan startet...</string>
<string name="main_cancelling_scan">Scan wird abgebrochen...</string>
<string name="main_cancelled_scan">Scan wurde abgebrochen</string>
<string name="main_files_pending_scan">%s Dateien, die zur Überprüfung vorgesehen sind</string>
<string name="main_database_loaded">Datenbank mit %s Signaturen geladen</string>
<string name="main_hashing_files">Generiere Hashes für Dateien...</string>
<string name="main_hashing_done">Hashes für alle Dateien generiert</string>
<string name="main_hash_scan_done">Alle %s Hashes wurden mit den Signatur-Datenbanken abgeglichen</string>
<string name="main_scanning_done">Scan nach %s Sekunden abgeschlossen @ %sMB/s!</string>
<string name="main_files_scanned_count">%s Datei(en) gescannt</string>
<string name="main_starting_scan">Schadsoftware-Prüfung startet...</string>
<string name="main_cancelling_scan">Prüfung wird abgebrochen...</string>
<string name="main_cancelled_scan">Prüfung wurde abgebrochen</string>
<string name="main_files_pending_scan">%s Dateien sind zur Schadsoftware-Prüfung vorgesehen</string>
<string name="main_database_loading">Lade Datenbank(en)...</string>
<string name="main_database_loaded">Datenbank(en) mit %s Signaturen geladen</string>
<string name="main_hashing_files">Generiere Prüfsummen der Dateien...</string>
<string name="main_hashing_done">Prüfsummen für alle Dateien generiert</string>
<string name="main_hash_scan_done">Alle %s Prüfsummen wurden mit den Signaturen der Datenbank(en) verglichen</string>
<string name="main_scanning_done">Überprüfung nach %s Sekunden abgeschlossen @ %sMB/s!</string>
<string name="main_files_scanned_count">%s Dateien überprüft</string>
<string name="db_desc_author">Autor</string>
<string name="db_desc_license">Lizenz</string>
<string name="db_desc_size">Größe</string>
<string name="db_desc_source">Quelle</string>

View file

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<resources></resources>

View file

@ -0,0 +1,64 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_copyright">Πνευματικά δικαιώματα 2017-2023 Divested Computing Group</string>
<string name="app_license">Άδεια: GPL-3.0</string>
<string name="app_version">Έκδοση: %s</string>
<string name="app_db_type_clamav">Υποστηρίζεται από υπογραφές τύπου ClamAV</string>
<string name="lblOnionRoutingToggle">Πραγματοποιείται Λήψη μέσω Tor</string>
<string name="lblOnionRoutingEnabledHint">Λήψη μέσω Tor, αυτό μπορεί να πάρει κάποιο χρόνο...</string>
<string name="lblOnionRoutingNotInstalled">Το Orbot δεν είναι εγκατεστημένο!</string>
<string name="lblOnionRoutingNotRunning">Το Orbot δεν εκτελείται!</string>
<string name="lblUpdateDatabase">Ενημέρωση βάσεων δεδομένων</string>
<string name="lblSelectDatabases">Επιλογή βάσεων δεδομένων</string>
<string name="lblSelectDatabasesTitle">Επιλέξτε τις βάσεις δεδομένων που θέλετε να ενεργοποιήσετε</string>
<string name="lblDatabaseServer">Παράκαμψη διακομιστή βάσης δεδομένων</string>
<string name="lblFullCredits">Credits</string>
<string name="lblScanSystem">Σάρωση /system</string>
<string name="lblScanApps">Σάρωση των APKs των εφαρμογών</string>
<string name="lblScanInternal">Σάρωση εσωτερικού χώρου αποθήκευσης</string>
<string name="lblScanExternal">Σάρωση εξωτερικού χώρου αποθήκευσης</string>
<string name="lblNotificationMalwareDetectionTitle">Ανίχνευση κακόβουλου λογισμικού</string>
<string name="lblNotificationMalwareDetectionDescription">Ειδοποίησέ με όταν ανιχνεύεται κακόβουλο λογισμικό</string>
<string name="lblNotificationRealtimeTitle">Σάρωση σε πραγματικό χρόνο</string>
<string name="lblNotificationRealtimeDescription">Χρησιμοποιείται για να εμφανίζει τον αριθμό των αρχείων που σαρώνονται και για να διατηρεί την υπηρεσία στο παρασκήνιο</string>
<string name="lblNotificationRealtimeText">Το γνωστό κακόβουλο λογισμικό θα ανιχνεύεται σε πραγματικό χρόνο</string>
<string name="lblNotificationRealtimeStopped">Hypatia: Η σάρωση σε πραγματικό χρόνο σταμάτησε</string>
<string name="lblNotificationRealtimeDetection">Ανιχνεύτηκε κακόβουλο λογισμικό:</string>
<string name="lblRealtimeScannerToggle">Σάρωση σε πραγματικό χρόνο</string>
<string name="lblReset">Επαναφορά</string>
<string name="lblOverride">Παράκαμψη</string>
<string name="main_database_updating">Ενημέρωση %s βάσεων δεδομένων...</string>
<string name="main_database_override">Χρήση διακομιστή %s</string>
<string name="main_database_downloading">Λήψη %s</string>
<string name="main_database_download_success">Επιτυχής λήψη</string>
<string name="main_database_download_error">Δεν έγινε η λήψη του αρχείου, κωδικός απόκρισης %s</string>
<string name="main_no_database_available">Δεν υπάρχει διαθέσιμη βάση δεδομένων, δεν γίνεται σάρωση...</string>
<string name="main_database_released_on">Δημοσιεύτηκε στις %s</string>
<string name="main_database_not_changed">Το αρχείο δεν άλλαξε</string>
<string name="main_database_not_modified_since">από %s</string>
<string name="main_database_download_error_logcat">Αποτυχία λήψης, ελέγξτε το logcat</string>
<string name="main_starting_scan">Έναρξη σάρωσης...</string>
<string name="main_cancelling_scan">Ακύρωση σάρωσης...</string>
<string name="main_cancelled_scan">Ακυρώθηκε η σάρωση</string>
<string name="main_files_pending_scan">%s αρχεία περιμένουν σάρωση</string>
<string name="main_database_loading">Φόρτωση βάσης δεδομένων...</string>
<string name="main_database_loaded">Φορτώθηκε βάση δεδομένων με %s υπογραφές</string>
<string name="main_hashing_files">Καταγραφή αρχείων...</string>
<string name="main_hashing_done">Υπολογίστηκαν τα hashes για όλα τα αρχεία</string>
<string name="main_hash_scan_done">Έλεγθηκαν και τα %s hashes ως προς τις βάσεις υπογραφών</string>
<string name="main_scanning_done">Η σάρωση ολοκληρώθηκε σε %s δευτερόλεπτα @ %sMB/s!</string>
<string name="main_files_scanned_count">%s αρχεία σαρώθηκαν</string>
<string name="db_desc_author">Συντάκτης</string>
<string name="db_desc_license">Άδεια</string>
<string name="db_desc_size">Μέγεθος</string>
<string name="db_desc_source">Πηγή</string>
<string name="db_desc_size_small">Μικρό</string>
<string name="db_desc_size_medium">Μεσαίο</string>
<string name="db_desc_size_large">Μεγάλο</string>
<string name="scan_control">Έλεγχος σάρωσης</string>
<string name="lblScanRunning">Παράλειψη ενέργειας, μια σάρωση βρίσκεται ήδη σε εξέλιξη!</string>
<string name="lblSigningKey">Κλειδί υπογραφής της βάσης δεδομένων</string>
</resources>

View file

@ -1,2 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<resources></resources>
<resources>
<string-array name="fullCredits">
<item>• Petra Mirelli: traductions en allemand/espagnol/français/italien, bannière de l\'application, ajustements divers</item>
<item>• Jean-Luc Tibaux: traduction française</item>
<item>• @srccrow: traduction italienne</item>
<item>• @inkhorn: traduction portugaise</item>
<item>• @jontaix: traduction portugaise</item>
<item>• @q1011: traduction russe</item>
<item>• Oswald van Ginkel: traduction en afrikaans</item>>
<item>• huuhaa: traduction finlandaise</item>
<item>• Marcin Mikołajczak: traduction polonaise</item>
<item>• @Manuel-Senpai: traduction espagnole</item>
<item>• @Balthazar1234: German Translations</item>
<item>• @Sdarfeesh: Simplified Chinese Translations</item>
<item>• @cardpuncher: French/Turkish Translations</item>
<item>• Tommaso Fonda: Italian Translations</item>
<item>• ClamAV par Cisco: bases de données de signatures</item>
<item>• ESET: bases de données de signatures</item>
<item>• Nex (@botherder): bases de données de signatures</item>
<item>• Amnesty International: bases de données de signatures</item>
<item>• Echap: bases de données de signatures</item>
<item>• RecursiveFileObserver.java: Daniel Gultsch, ownCloud Inc., Bartek Przybylski</item>
<item>• GPGDetachedSignatureVerifier.java: Federico Fissore, Arduino LLC</item>
<item>• Google: icône de l\'application</item>
</string-array>
</resources>

View file

@ -1,5 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name" translatable="false">Hypatia</string>
<string name="app_copyright">Copyright 2017-2023 Divested Computing Group</string>
<string name="app_license">Licence: GPL-3.0</string>
<string name="app_version">Numéro de version: %s</string>
<string name="app_db_type_clamav">Propulsé par les signatures de style ClamAV</string>
@ -10,43 +12,53 @@
<string name="lblOnionRoutingNotRunning">Orbot n\'est pas en marche !</string>
<string name="lblUpdateDatabase">Mise à jour des bases de données</string>
<string name="lblSelectDatabases">Sélectionner les bases de données</string>
<string name="lblSelectDatabasesTitle">Sélectionner les bases de données pour permettre</string>
<string name="lblScanApps">Scanner les APK de l\'applis</string>
<string name="lblScanInternal">Scanner la mémoire interne</string>
<string name="lblScanExternal">Scanner la mémoire externe</string>
<string name="lblNotificationMalwareDetectionTitle">Détection des malwares</string>
<string name="lblSelectDatabasesTitle">Sélectionner les bases de données à activer</string>
<string name="lblDatabaseServer">Remplacer le serveur de base de données</string>
<string name="lblFullCredits">Crédits</string>
<string name="lblScanSystem">Analyser le /système</string>
<string name="lblScanApps">Analyser les APK des applis</string>
<string name="lblScanInternal">Analyser la mémoire interne</string>
<string name="lblScanExternal">Analyser la mémoire externe</string>
<string name="lblNotificationMalwareDetectionTitle">Détection des logiciels malveillants</string>
<string name="lblNotificationMalwareDetectionDescription">Utilisé pour alerter lorsqu\'un logiciel malveillant est détecté</string>
<string name="lblNotificationRealtimeTitle">Scanner en temps réel</string>
<string name="lblNotificationRealtimeTitle">Analyser en temps réel</string>
<string name="lblNotificationRealtimeDescription">Utilisé pour montrer les fichiers scannés compteur et maintenir le service de fond</string>
<string name="lblNotificationRealtimeText">Les logiciels malveillants connus seront détectés en temps réel</string>
<string name="lblNotificationRealtimeStopped">Hypatia: Scanner en temps réel a été arrêté</string>
<string name="lblNotificationRealtimeDetection">Malware détecté:</string>
<string name="lblNotificationRealtimeDetection">Logiciel malveillant détecté :</string>
<string name="lblRealtimeScannerToggle">Scanner en temps réel</string>
<string name="lblReset">Réinitialiser</string>
<string name="lblOverride">Remplacer</string>
<string name="main_database_updating">Mise à jour des %s bases de données ...</string>
<string name="main_database_updating">Mise à jour des %s bases de données...</string>
<string name="main_database_override">Utilisation du serveur %s</string>
<string name="main_database_downloading">Télécharger %s</string>
<string name="main_database_download_success">Téléchargement réussi</string>
<string name="main_database_download_success">Téléchargement réussi</string>
<string name="main_database_download_error">Fichier non téléchargé, code de réponse %s</string>
<string name="main_no_database_available">Pas de base de données disponible, pas de scannage...</string>
<string name="main_database_released_on">Publié le %s</string>
<string name="main_no_database_available">Pas de base de données disponible, pas d\'analyse...</string>
<string name="main_database_released_on">Publiée le %s</string>
<string name="main_database_not_changed">Fichier non modifié</string>
<string name="main_database_not_modified_since">depuis le %s</string>
<string name="main_database_download_error_logcat">Téléchargement échoué, vérifier le logcat</string>
<string name="main_starting_scan">Démarrage du scan...</string>
<string name="main_cancelling_scan">Le scan est annulé...</string>
<string name="main_cancelled_scan">Le scan a été annulé</string>
<string name="main_starting_scan">Démarrage de l\'analyse...</string>
<string name="main_cancelling_scan">L\'analyse est annulée...</string>
<string name="main_cancelled_scan">L\'analyse a été annulée</string>
<string name="main_files_pending_scan">%s dossiers en attente de scan</string>
<string name="main_database_loaded">Base de données chargée de %s signatures</string>
<string name="main_hashing_files">Hachage de fichiers...</string>
<string name="main_hashing_done">Hachages calculés pour tous les fichiers</string>
<string name="main_hash_scan_done">Vérification de tous les hachages %s par rapport aux bases de données de signatures</string>
<string name="main_scanning_done">Scan complété en %s secondes @ %sMB/s!</string>
<string name="main_files_scanned_count">%s fichiers scannés</string>
<string name="main_scanning_done">Analyse complétée en %s secondes @ %sMo/s!</string>
<string name="main_files_scanned_count">%s fichiers analysés</string>
<string name="db_desc_author">Auteur</string>
<string name="db_desc_license">Licence</string>
<string name="db_desc_size">Taille</string>
<string name="db_desc_source">La source</string>
<string name="db_desc_size_medium">Moyen</string>
<string name="db_desc_size_medium">Moyenne</string>
<string name="db_desc_size_large">Grande</string>
<string name="db_desc_size_small">Petite</string>
<string name="scan_control">Contrôle de l\'analyse</string>
<string name="lblScanRunning">Action ignorée, une analyse est en cours !</string>
<string name="lblSigningKey">Signature utilisée pour signer la base de données</string>
</resources>

View file

@ -2,29 +2,29 @@
<resources>
<string name="app_license">Licenza: GPL-3.0</string>
<string name="app_version">Versione: %s</string>
<string name="app_db_type_clamav">Potenziato dalle firme di stile ClamAV</string>
<string name="app_db_type_clamav">Basato su firme in stile ClamAV</string>
<string name="lblOnionRoutingToggle">Aggiorna tramite Tor</string>
<string name="lblOnionRoutingEnabledHint">Aggiornamento tramite Tor, potrebbe volerci un po\'...</string>
<string name="lblOnionRoutingNotInstalled">Orbot non è installato!</string>
<string name="lblOnionRoutingNotRunning">Orbot non è in esecuzione!</string>
<string name="lblUpdateDatabase">Aggiorna i database</string>
<string name="lblSelectDatabases">Seleziona un database</string>
<string name="lblSelectDatabasesTitle">Database disponibili</string>
<string name="lblSelectDatabases">Seleziona database</string>
<string name="lblSelectDatabasesTitle">Seleziona i database da abilitare</string>
<string name="lblDatabaseServer">Modifica il server dei database</string>
<string name="lblFullCredits">Crediti</string>
<string name="lblScanSystem">Scansiona le app di sistema</string>
<string name="lblScanApps">Scansiona le app</string>
<string name="lblScanInternal">Scansiona la Memoria Interna</string>
<string name="lblScanExternal">Scansiona la Memoria Esterna</string>
<string name="lblNotificationMalwareDetectionTitle">Malware Rilevato</string>
<string name="lblScanInternal">Scansiona la memoria interna</string>
<string name="lblScanExternal">Scansiona la memoria esterna</string>
<string name="lblNotificationMalwareDetectionTitle">Malware rilevato</string>
<string name="lblNotificationMalwareDetectionDescription">Indica quando il malware è rilevato</string>
<string name="lblNotificationRealtimeTitle">Scansione in Tempo Reale</string>
<string name="lblNotificationRealtimeTitle">Scansione in tempo reale</string>
<string name="lblNotificationRealtimeDescription">Indica il numero di file scansionati e mantiene il servizio in esecuzione in background</string>
<string name="lblNotificationRealtimeText">Il malware sarà rilevato in tempo reale</string>
<string name="lblNotificationRealtimeStopped">Hypatia: La Scansione in Tempo Reale è stata interrotta</string>
<string name="lblNotificationRealtimeDetection">Malware Rilevato:</string>
<string name="lblRealtimeScannerToggle">Scansione in Tempo Reale</string>
<string name="lblNotificationRealtimeStopped">Hypatia: la scansione in tempo reale è stata interrotta</string>
<string name="lblNotificationRealtimeDetection">Malware rilevato:</string>
<string name="lblRealtimeScannerToggle">Scansione in tempo reale</string>
<string name="lblReset">Reset</string>
<string name="lblOverride">Modifica</string>
@ -57,4 +57,7 @@
<string name="db_desc_size_medium">Medio</string>
<string name="db_desc_size_large">Grande</string>
<string name="db_desc_size_small">Piccola</string>
<string name="scan_control">Controllo scansione</string>
<string name="lblScanRunning">Azione saltata, è in corso una scansione!</string>
<string name="lblSigningKey">Chiave di firma del database</string>
</resources>

View file

@ -57,4 +57,7 @@
<string name="db_desc_size_small">Маленький</string>
<string name="db_desc_size_medium">Средний</string>
<string name="db_desc_size_large">Большой</string>
<string name="scan_control">Контроль сканирования</string>
<string name="lblScanRunning">Пропускаем действие, выполняется сканирование!</string>
<string name="lblSigningKey">Ключ подписи базы данных</string>
</resources>

View file

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="fullCredits">
<item>• Petra Mirelli: Almanca/İspanyolca/Fransızca/İtalyanca Tercüme, Uygulama Afişi, Çeşitli Değişiklikler</item>
<item>• Jean-Luc Tibaux: Fransızca Tercüme</item>
<item>• @srccrow: İtalyanca Tercüme</item>
<item>• @inkhorn: Portekizce Tercüme</item>
<item>• @jontaix: Portekizce Tercüme</item>
<item>• @q1011: Rusça Tercüme</item>
<item>• Oswald van Ginkel: Afrikaanca Tercüme</item>>
<item>• huuhaa: Fince Tercüme</item>
<item>• Marcin Mikołajczak: Lehçe Tercüme</item>
<item>• @Manuel-Senpai: İspanyolca Tercüme</item>
<item>• @Balthazar1234: German Translations</item>
<item>• @Sdarfeesh: Simplified Chinese Translations</item>
<item>• @cardpuncher: French/Turkish Translations</item>
<item>• Tommaso Fonda: Italian Translations</item>
<item>• Cisco tarafından ClamAV: İmza Veri Tabanları</item>
<item>• ESET: İmza Veri Tabanları</item>
<item>• Nex (@botherder): İmza Veri Tabanları</item>
<item>• Uluslararası Af Örgütü: İmza Veri Tabanları</item>
<item>• Echap: İmza Veri Tabanları</item>
<item>• RecursiveFileObserver.java: Daniel Gultsch, ownCloud Inc., Bartek Przybylski</item>
<item>• GPGDetachedSignatureVerifier.java: Federico Fissore, Arduino LLC</item>
<item>• Google: Uygulama İkonu</item>
</string-array>
</resources>

View file

@ -0,0 +1,65 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name" translatable="false">Hypatia</string>
<string name="app_copyright">Telif hakkı 2017-2023 Divested Computing Group</string>
<string name="app_license">Lisans: GPL-3.0</string>
<string name="app_version">Sürüm: %s</string>
<string name="app_db_type_clamav">ClamAV tarzı imzalarla güçlendirilmiştir</string>
<string name="lblOnionRoutingToggle">Tor üzerinden indir</string>
<string name="lblOnionRoutingEnabledHint">Tor üzerinden indiriliyor, bu uzun sürebilir...</string>
<string name="lblOnionRoutingNotInstalled">Orbot kurulu değil!</string>
<string name="lblOnionRoutingNotRunning">Orbot çalışır hâlde değil!</string>
<string name="lblUpdateDatabase">Veri tabanlarını güncelle</string>
<string name="lblSelectDatabases">Veri tabanlarını seç</string>
<string name="lblSelectDatabasesTitle">Etkinleştirilecek veri tabanlarını seç</string>
<string name="lblDatabaseServer">Veri tabanı sunucusu yerine koy</string>
<string name="lblFullCredits">Katkıda bulunanlar</string>
<string name="lblScanSystem">Sistemi /tara</string>
<string name="lblScanApps">Uygulama APK\'larını tara</string>
<string name="lblScanInternal">Dahili Depolamayı Tara</string>
<string name="lblScanExternal">Harici Depolamayı Tara</string>
<string name="lblNotificationMalwareDetectionTitle">Kötücül Yazılım Tespiti</string>
<string name="lblNotificationMalwareDetectionDescription">Kötücül yazılım bulunduğunda haber vermek için kullanılır</string>
<string name="lblNotificationRealtimeTitle">Gerçek zamanlı tarayıcı</string>
<string name="lblNotificationRealtimeDescription">Taranan dosya sayacını göstermek ve arka plan servisinin devamı için kullanılır</string>
<string name="lblNotificationRealtimeText">Bilinen kötücüller gerçek zamanlı olarak tespit edilecektir</string>
<string name="lblNotificationRealtimeStopped">Hypatia: Gerçek Zamanlı Tarama Durduruldu</string>
<string name="lblNotificationRealtimeDetection">Kötücül Yazılım Tespit Edildi:</string>
<string name="lblRealtimeScannerToggle">Gerçek Zamanlı Tarayıcı</string>
<string name="lblReset">Sıfırla</string>
<string name="lblOverride">Yerine Koy</string>
<string name="main_database_updating">%s veri tabanı güncelleniyor...</string>
<string name="main_database_override">%s sunucusu kullanılıyor</string>
<string name="main_database_downloading">%s indiriliyor</string>
<string name="main_database_download_success">Başarıyla indirildi</string>
<string name="main_database_download_error">Dosya indirilmedi, cevap kodu %s</string>
<string name="main_no_database_available">Hiçbir veri tabanı mevcut değil, tarama yapılmıyor...</string>
<string name="main_database_released_on">%s tarihinde yayınlandı</string>
<string name="main_database_not_changed">Dosya değiştirilmedi</string>
<string name="main_database_not_modified_since">%s tarihinden beri</string>
<string name="main_database_download_error_logcat">İndirme başarısız, logcat kontrolü yapın</string>
<string name="main_starting_scan">Tarama başlatılıyor...</string>
<string name="main_cancelling_scan">Tarama iptal ediliyor...</string>
<string name="main_cancelled_scan">Tarama iptal edildi</string>
<string name="main_files_pending_scan">%s dosya taranmayı bekliyor</string>
<string name="main_database_loading">Veri tabanı yükleniyor...</string>
<string name="main_database_loaded">Veri tabanı, %s imza ile yüklendi</string>
<string name="main_hashing_files">Dosyaların karma değeri hesaplanıyor...</string>
<string name="main_hashing_done">Tüm dosyaların karma değeri hesaplandı</string>
<string name="main_hash_scan_done">Tüm %s karma değer imza veri tabanlarıyla karşılaştırıldı</string>
<string name="main_scanning_done">Tarama % saniyede %sMB/s hızla tamamlandı!</string>
<string name="main_files_scanned_count">%s dosya tarandı</string>
<string name="db_desc_author">Yazar</string>
<string name="db_desc_license">Lisans</string>
<string name="db_desc_size">Boyut</string>
<string name="db_desc_source">Kaynak</string>
<string name="db_desc_size_small">Küçük</string>
<string name="db_desc_size_medium">Orta</string>
<string name="db_desc_size_large">Büyük</string>
<string name="scan_control">Tarama Kontrolü</string>
<string name="lblScanRunning">Faaliyet es geçiliyor, bir tarama devam etmekte!</string>
<string name="lblSigningKey">Veri tabanı imzalama anahtarı</string>
</resources>

View file

@ -0,0 +1,64 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name" translatable="false">Hypatia</string>
<string name="app_copyright">版权所有 2017-2023 Divested Computing Group</string>
<string name="app_license">许可证GPL-3.0</string>
<string name="app_version">版本:%s</string>
<string name="app_db_type_clamav">由 ClamAV 数据库特征码提供支持</string>
<string name="lblOnionRoutingToggle">通过 Tor 下载</string>
<string name="lblOnionRoutingEnabledHint">正在通过 Tor 下载,这可能需要一段时间...</string>
<string name="lblOnionRoutingNotInstalled">Orbot 未安装!</string>
<string name="lblOnionRoutingNotRunning">Orbot 未运行!</string>
<string name="lblUpdateDatabase">更新数据库</string>
<string name="lblSelectDatabases">选择数据库</string>
<string name="lblSelectDatabasesTitle">选择要启用的数据库</string>
<string name="lblDatabaseServer">数据库服务器覆盖</string>
<string name="lblFullCredits">致谢名单</string>
<string name="lblScanSystem">扫描 /system</string>
<string name="lblScanApps">扫描应用软件包</string>
<string name="lblScanInternal">扫描内部存储空间</string>
<string name="lblScanExternal">扫描外部存储空间</string>
<string name="lblNotificationMalwareDetectionTitle">恶意程序检测</string>
<string name="lblNotificationMalwareDetectionDescription">用于在检测到恶意程序时发出警报</string>
<string name="lblNotificationRealtimeTitle">实时扫描</string>
<string name="lblNotificationRealtimeDescription">用于显示已扫描文件数量和维护后台服务</string>
<string name="lblNotificationRealtimeText">实时检测已知恶意程序</string>
<string name="lblNotificationRealtimeStopped">Hypatia实时扫描已停止</string>
<string name="lblNotificationRealtimeDetection">检测到恶意程序:</string>
<string name="lblRealtimeScannerToggle">实时扫描</string>
<string name="lblReset">重置</string>
<string name="lblOverride">覆盖</string>
<string name="main_database_updating">正在更新 %s 个数据库...</string>
<string name="main_database_override">使用服务器 %s</string>
<string name="main_database_downloading">正在下载 %s</string>
<string name="main_database_download_success">下载成功</string>
<string name="main_database_download_error">文件未下载,响应代码 %s</string>
<string name="main_no_database_available">无可用数据库,不执行扫描...</string>
<string name="main_database_released_on">发布于 %s</string>
<string name="main_database_not_changed">文件无变更</string>
<string name="main_database_not_modified_since">%s 以来)</string>
<string name="main_database_download_error_logcat">下载失败,查看 Logcat</string>
<string name="main_starting_scan">开始扫描...</string>
<string name="main_cancelling_scan">正在取消扫描...</string>
<string name="main_cancelled_scan">扫描已取消</string>
<string name="main_files_pending_scan">%s 个文件等待扫描</string>
<string name="main_database_loading">正在加载数据库...</string>
<string name="main_database_loaded">已加载带有 %s 个特征码的数据库</string>
<string name="main_hashing_files">正在计算文件哈希值...</string>
<string name="main_hashing_done">已计算所有文件的哈希值</string>
<string name="main_hash_scan_done">已根据特征码数据库检查全部 %s 哈希值</string>
<string name="main_scanning_done">扫描在 %s 秒内完成 @ %sMB/s!</string>
<string name="main_files_scanned_count">已扫描 %s 个文件</string>
<string name="db_desc_author">作者</string>
<string name="db_desc_license">许可证</string>
<string name="db_desc_size">大小</string>
<string name="db_desc_source">来源</string>
<string name="db_desc_size_small"></string>
<string name="db_desc_size_medium"></string>
<string name="db_desc_size_large"></string>
<string name="scan_control">扫描控制</string>
<string name="lblScanRunning">跳过操作,扫描正在运行!</string>
</resources>

View file

@ -10,12 +10,19 @@
<item>• Oswald van Ginkel: Afrikaans Translations</item>>
<item>• huuhaa: Finnish Translations</item>
<item>• Marcin Mikołajczak: Polish Translations</item>
<item>• @senpai33: Spanish Translations</item>
<item>• @Manuel-Senpai: Spanish Translations</item>
<item>• @Balthazar1234: German Translations</item>
<item>• @Sdarfeesh: Simplified Chinese Translations</item>
<item>• @cardpuncher: French/Turkish Translations</item>
<item>• Tommaso Fonda: Italian Translations</item>
<item>• Dimitris Vagiakakos: Greek Translations</item>
<item>• ClamAV by Cisco: Signature Databases</item>
<item>• ESET: Signature Databases</item>
<item>• Nex (@botherder): Signature Databases</item>
<item>• Amnesty International: Signature Databases</item>
<item>• Echap: Signature Databases</item>
<item>• RecursiveFileObserver.java: Daniel Gultsch, ownCloud Inc., Bartek Przybylski</item>
<item>• GPGDetachedSignatureVerifier.java: Federico Fissore, Arduino LLC</item>
<item>• Google: App Icon</item>
</string-array>
</resources>

View file

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#4CAF50</color>
<color name="light_blue">#03a9f4</color>
<color name="red">#f44336</color>
<color name="colorRed">#FF0000</color>
<color name="colorGreen">#008000</color>
</resources>

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name" translatable="false">Hypatia</string>
<string name="app_copyright">Copyright 2017-2022 Divested Computing Group</string>
<string name="app_copyright">Copyright 2017-2023 Divested Computing Group</string>
<string name="app_license">License: GPL-3.0</string>
<string name="app_version">Version: %s</string>
<string name="app_db_type_clamav">Powered by ClamAV style signatures</string>
@ -59,4 +59,7 @@
<string name="db_desc_size_small">Small</string>
<string name="db_desc_size_medium">Medium</string>
<string name="db_desc_size_large">Large</string>
<string name="scan_control">Scan Control</string>
<string name="lblScanRunning">Skipping action, a scan is running!</string>
<string name="lblSigningKey">Database signing key</string>
</resources>

View file

@ -1,20 +0,0 @@
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.DayNight.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimary</item>
<item name="colorAccent">@color/light_blue</item>
</style>
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.DayNight.ActionBar" />
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.DayNight" />
</resources>

View file

@ -0,0 +1,5 @@
* This release brings new and updated translations:
* @Manuel-Senpai for updated Spanish translations.
* @Balthazar1234 for updated German translations.
* @Sdarfeesh for new Simplified Chinese translations.
* @cardpuncher for new Turkish and updated French translations.

View file

@ -0,0 +1 @@
* Fix the downloader when many databases are enabled

View file

@ -0,0 +1 @@
* Tommaso Fonda for updated Italian translations

View file

@ -0,0 +1 @@
Now translated into Greek thanks to Dimitris Vagiakakos!

View file

@ -0,0 +1 @@
* Don't trim hashes as much to reduce false positives

View file

@ -0,0 +1 @@
* Don't trim hashes as much to reduce false positives

View file

@ -0,0 +1,2 @@
* Make the app smalller
* Colorize the manual scan button when possible

View file

@ -0,0 +1,2 @@
* Fix crash on Android <8.0
* Skip certain actions when a manual scan is running

View file

@ -0,0 +1 @@
* Add support for the Echap stalkerware database

View file

@ -0,0 +1,4 @@
* Databases are now verified using GPG signatures
* Users must use "Update databases" before use after installing this update
* Databases that are not signed or fail to verify will be ignored
* A custom database key is allowed to maintain support for third party database repos

View file

@ -0,0 +1 @@
* Fix for Android pre-7.1

Binary file not shown.

File diff suppressed because it is too large Load diff

View file

@ -43,6 +43,7 @@
<trusting group="^com[.]fasterxml($|([.].*))" regex="true"/>
</trusted-key>
<trusted-key id="694621a7227d8d5289699830abe9f3126bb741c1" group="^com[.]google($|([.].*))" regex="true"/>
<trusted-key id="6bdaca2c0493cca133b372d09c4f7e9d98b1cc53" group="commons-io"/>
<trusted-key id="6dd3b8c64ef75253beb2c53ad908a43fb7ec07ac" group="jakarta.activation"/>
<trusted-key id="6f538074ccebf35f28af9b066a0975f8b1127b83" group="org.jetbrains.kotlin"/>
<trusted-key id="7615ad56144df2376f49d98b1669c4bb543e0445" group="com.google.errorprone"/>
@ -60,6 +61,7 @@
<trusted-key id="aa70c7c433d501636392ec02153e7a3c2b4e5118" group="org.eclipse.ee4j" name="project"/>
<trusted-key id="afcc4c7594d09e2182c60e0f7a01b0f236e5430f" group="com.google.code.gson"/>
<trusted-key id="b02335aa54ccf21e52bbf9abd9c565aa72ba2fdd" group="io.grpc"/>
<trusted-key id="b6e73d84ea4fcc47166087253faad2cd5ecbb314" group="org.apache.commons" name="commons-parent"/>
<trusted-key id="b801e2f8ef035068ec1139cc29579f18fa8fd93b" group="com.google.j2objc" name="j2objc-annotations" version="1.3"/>
<trusted-key id="bcc135fc7ed8214f823d73e97fe9900f412d622e" group="com.google.flatbuffers" name="flatbuffers-java" version="1.12.0"/>
<trusted-key id="bdb5fa4fe719d787fb3d3197f6d4a1d411e9d1ae" group="com.google.guava"/>
@ -69,10 +71,13 @@
<trusted-key id="db0597e3144342256bc81e3ec727d053c4481cf5" group="org.tensorflow" name="tensorflow-lite-metadata" version="0.1.0-rc2"/>
<trusted-key id="e62231331bca7e1f292c9b88c1b12a5d99c0729d" group="org.jetbrains"/>
<trusted-key id="e7dc75fc24fb3c8dfe8086ad3d5839a2262cbbfb" group="org.jetbrains.kotlinx"/>
<trusted-key id="ee0ca873074092f806f59b65d364abaa39a47320" group="com.google.errorprone"/>
<trusted-key id="f254b35617dc255d9344bcfa873a8e86b4372146" group="org.codehaus.mojo"/>
<trusted-key id="f3184bcd55f4d016e30d4c9bf42e87f9665015c9" group="org.jsoup" name="jsoup" version="1.13.1"/>
<trusted-key id="fa77dcfef2ee6eb2debedd2c012579464d01c06a" group="org.apache" name="apache"/>
<trusted-key id="fa7929f83ad44c4590f6cc6815c71c0a4e0b8edd" group="net.java.dev.jna"/>
<trusted-key id="fc411cd3cb7dcb0abc9801058118b3bcdb1a5000" group="jakarta.xml.bind"/>
<trusted-key id="ff6e2c001948c5f2f38b0cc385911f425ec61b51" group="org.junit" name="junit-bom" version="5.7.2"/>
</trusted-keys>
</configuration>
<components>
@ -92,6 +97,14 @@
<sha512 value="92302073f22a9fd6aad7808bed2ec0eecb571f66f569ae31533dd8785e0cd44fbacea1e76dc976f26da548783b29ad6ebfbf2c46840cfea38c7d500b137603a3" origin="Generated by Gradle because artifact wasn't signed"/>
</artifact>
</component>
<component group="androidx.activity" name="activity" version="1.6.0">
<artifact name="activity-1.6.0.aar">
<sha512 value="7f44ac877b856000f89099afdf4f6ab14a72c459c65b741ee716597492125a3b5d87c41357c9d4c7773e8a97aa14a3f3f29b2052d0d7715d9b75484bc6155768" origin="Generated by Gradle because artifact wasn't signed"/>
</artifact>
<artifact name="activity-1.6.0.module">
<sha512 value="c2218795bb2ea45677a1139866d55ecd8457991aa104eb691a7d290b5b198cbbcf1acd9961b45bb1320951ed457f3cf42cb99fcde429e44c6b843ab508122c9e" origin="Generated by Gradle because artifact wasn't signed"/>
</artifact>
</component>
<component group="androidx.annotation" name="annotation" version="1.3.0">
<artifact name="annotation-1.3.0.jar">
<sha512 value="63def0a638a01e3b04abf515b27b5250c24b9f95db0b08dde7c27094e1ebdfca79642fd06938843794827400ac1fd437e0f80881350f44adf1fef0e8f177a12f" origin="Generated by Gradle because artifact wasn't signed"/>
@ -113,6 +126,14 @@
<sha512 value="dc0d26d83c9b83a69f753730f01401a61e99cfb453dcce3d6a87ef2d347bdf3996839d8af48922ae6ce5ed946b61e0934eacc91376bf3d17810ac5660113bcf2" origin="Generated by Gradle because artifact wasn't signed"/>
</artifact>
</component>
<component group="androidx.annotation" name="annotation-experimental" version="1.3.0">
<artifact name="annotation-experimental-1.3.0.aar">
<sha512 value="fb738457a504d75e742f3de92cd32d37c9199747816274841d9dd7eb57343afa6e76e45c6aa1ea161187d15d2d4c396ea601fa3bbab69f75f09e5c48e7ee643a" origin="Generated by Gradle because artifact wasn't signed"/>
</artifact>
<artifact name="annotation-experimental-1.3.0.module">
<sha512 value="2cb371cc267c10827f1e92110765a57938e09fd74bd995b9185ffc95675c358421725eacf7fdf0d32c43db90a3432d8dd9c22e24c9bcc106bc58263f25501c74" origin="Generated by Gradle because artifact wasn't signed"/>
</artifact>
</component>
<component group="androidx.appcompat" name="appcompat" version="1.5.0">
<artifact name="appcompat-1.5.0.aar">
<sha512 value="0c0714425518230881eba9b29bcc27f3e573552b9e0e01463e1f3cc913abafb4c0b291c5c6dd7e3e40cf28a9c7bbcc084e62105932d1c100a59a7fcc92e10a90" origin="Generated by Gradle because artifact wasn't signed"/>
@ -129,6 +150,14 @@
<sha512 value="d611ced619f70d238b40ea685ff5acda40093220058412e0c1c7d98105480c8815d8b8d47a8ace17e734cfc77ab433ce152d78515da71f627c9d5fe45549315d" origin="Generated by Gradle because artifact wasn't signed"/>
</artifact>
</component>
<component group="androidx.appcompat" name="appcompat" version="1.6.0">
<artifact name="appcompat-1.6.0.aar">
<sha512 value="974b75d5297d3dcc4800fb3398564d02824dc11ef42ba4053c3fab72ec6e988bf27c96efe3f5bfda0bb886d182c00a71988f69f01b3e0e6df88ff32bc7f4b3c0" origin="Generated by Gradle because artifact wasn't signed"/>
</artifact>
<artifact name="appcompat-1.6.0.module">
<sha512 value="94139fa137f208dae44392dd9f8f458ac5c7671535f1696b4ed3c8bd858e1f28e7a877eb4111be28547ae50f0e784093d8ec7f0fe57983dd54f80be323f3b2ad" origin="Generated by Gradle because artifact wasn't signed"/>
</artifact>
</component>
<component group="androidx.appcompat" name="appcompat-resources" version="1.5.0">
<artifact name="appcompat-resources-1.5.0.aar">
<sha512 value="4b6f3f25253086cb599168276d6653ec471d79bd049506db00c8930302ba5928e683185fa170a438a43955969b2b8f39e837d3aa4c0fc89d1cfdd82c7dbeb7b3" origin="Generated by Gradle because artifact wasn't signed"/>
@ -145,6 +174,14 @@
<sha512 value="eb5f8868893fba40bd7d04885baa4db976a9d9b03eb5f4f19c1b7e897a9e922eb0b512fb08e59574aafd4bf77932fe399ca0e3c3edd379956b951d518308a359" origin="Generated by Gradle because artifact wasn't signed"/>
</artifact>
</component>
<component group="androidx.appcompat" name="appcompat-resources" version="1.6.0">
<artifact name="appcompat-resources-1.6.0.aar">
<sha512 value="e642bea266812afe62a4d82f5d566ef7cb92e38ba5ca8e3aa8b5f7480d49986679b017bd746c3f61ff1e4293dcbc7460b60ac694d7bc4e32d6852e028dbe8e87" origin="Generated by Gradle because artifact wasn't signed"/>
</artifact>
<artifact name="appcompat-resources-1.6.0.module">
<sha512 value="4e5f0ab2113ef2a95b0ac5c7a4613119f50aab1dae24a3f2d47cafd334a0457b99b65bc19aa30ea00d95bc939fc675e8076ec074f8a4c801c6cc8a236f907406" origin="Generated by Gradle because artifact wasn't signed"/>
</artifact>
</component>
<component group="androidx.arch.core" name="core-common" version="2.1.0">
<artifact name="core-common-2.1.0.jar">
<sha512 value="e90a8019dafec7cf795d36c14470511983b8fb53343f95c0169a99d110f4d5bd9cc70498d8084abcdf8d9d19699622b7b6ea4e3681cf46be9ed86e97f22ee196" origin="Generated by Gradle because artifact wasn't signed"/>
@ -230,6 +267,14 @@
<sha512 value="0edb94ec9c3095d4a04e6bd0837b05c54c4130a6fc283d02513bcc76366dacc5bda7d73ff93a5ce6391afd93800062a436e2ac634c4a4433d8cadc760a50cbd9" origin="Generated by Gradle because artifact wasn't signed"/>
</artifact>
</component>
<component group="androidx.core" name="core" version="1.9.0">
<artifact name="core-1.9.0.aar">
<sha512 value="4e20f84108645931c6cab2702f6bc920caa3f63d6495a883511c513bf132f3d2f79c528a29c982314b7f27b630c44a4ad8bb0b6997e1d93a269aa39ad94fa7e6" origin="Generated by Gradle"/>
</artifact>
<artifact name="core-1.9.0.module">
<sha512 value="6d30c1985abb279dab3c4cd760525d25c4ceb8635b933e7da945854a3673baff6bafea3f021fed338461f5f2b99bad8382f8273132560b983fdad44bdbacf405" origin="Generated by Gradle because artifact wasn't signed"/>
</artifact>
</component>
<component group="androidx.core" name="core-ktx" version="1.2.0">
<artifact name="core-ktx-1.2.0.aar">
<sha512 value="ebd67135811cc4e1f74a2178122cb5ce3802f5a2485c206d7f19e29fbc77c860201b7df80a0b10c724ed1a8b64494a3335b77b37234524256b48f9d68648af0a" origin="Generated by Gradle because artifact wasn't signed"/>
@ -246,6 +291,14 @@
<sha512 value="69f4f44dddc9c927ddd84ff1f22e2a9546788a0d8a04ad33d0678f9b49bf51f3680f63a13e26eee98d9d693eca9ccb65270fd38fbc5f02a7adcbb0accb2ce1b4" origin="Generated by Gradle because artifact wasn't signed"/>
</artifact>
</component>
<component group="androidx.core" name="core-ktx" version="1.9.0">
<artifact name="core-ktx-1.9.0.aar">
<sha512 value="ac296b336aa1c16ebf1466186fd3fab816a122b5dec17817ea78eb79807a30d8999b6a7828399912c1e96301abdd634d3266c0ae678dbf8e53cbac7c5539ceee" origin="Generated by Gradle because artifact wasn't signed"/>
</artifact>
<artifact name="core-ktx-1.9.0.module">
<sha512 value="42545d893d2a405043d94df6f0ad393bd7cc8ca47470d1c21168443545e40024a88a1ac0b13cf4d89f8d5383ac99b3eabec88a6f9c84e9369a162a5bb6c43c61" origin="Generated by Gradle because artifact wasn't signed"/>
</artifact>
</component>
<component group="androidx.cursoradapter" name="cursoradapter" version="1.0.0">
<artifact name="cursoradapter-1.0.0.aar">
<sha512 value="176ac8e4604749ef5bb7f444c24add479f1d2cc5caab1046bbb35f937bf1cfc4329786cd1fdac3d6ee92fec78cb55ab89e5169ae5c6ee24dd4d20243aa867891" origin="Generated by Gradle because artifact wasn't signed"/>
@ -254,6 +307,14 @@
<sha512 value="153f48762a02aa3d3591572f3d235b46ff90745be91acf731cb793815a4c0fd35d1d23f932a55f9bdcb95ad9d83efefa4cddaeae27c8448a806720245afd9de1" origin="Generated by Gradle because artifact wasn't signed"/>
</artifact>
</component>
<component group="androidx.customview" name="customview" version="1.0.0">
<artifact name="customview-1.0.0.aar">
<sha512 value="e30966e3e5bdfca7b6189d96d23af4b9224ff442634ce7957ae8b4975b3e9ae598f2cfc898b5844e6c7003533fd3d0715d6b59ed8cc86b1889d799c805321997" origin="Generated by Gradle because artifact wasn't signed"/>
</artifact>
<artifact name="customview-1.0.0.pom">
<sha512 value="a6abe5a6ee7d297c6cd3ec91260636caa9d251a41d7455d10560747d35d57da6e555403262735b5d1dbb7f8314a89ca0a1c882bc69de443cdfac207063ce5edd" origin="Generated by Gradle because artifact wasn't signed"/>
</artifact>
</component>
<component group="androidx.customview" name="customview" version="1.1.0">
<artifact name="customview-1.1.0.aar">
<sha512 value="7d6059b7d3aa26f9b8a98412f51ac6e9974cc0aff5c53c71fb8213f429b7511bf6650c7e8889cc1ecdc6f9a05c47025fe1450a7429d27309e7b302f300848465" origin="Generated by Gradle because artifact wasn't signed"/>
@ -287,6 +348,9 @@
</artifact>
</component>
<component group="androidx.drawerlayout" name="drawerlayout" version="1.0.0">
<artifact name="drawerlayout-1.0.0.aar">
<sha512 value="c3a92947b15af89d55a2268526579b7ad43cefde589f8824de0a9bf0dd1e3058e1853c046beb64be2df6a3a74ddf5ba494bafaf534e81c963b6fa9270e05a8ef" origin="Generated by Gradle because artifact wasn't signed"/>
</artifact>
<artifact name="drawerlayout-1.0.0.pom">
<sha512 value="4663df683bee7ab42fc95deabf249276f5a22f28830df5ba7ce292571ee3e6840d1503fb9dcdf5a3df742d863e74827ee2061494491d3cc2184b16a0d3f4a728" origin="Generated by Gradle because artifact wasn't signed"/>
</artifact>
@ -971,11 +1035,32 @@
<sha512 value="0899c5ee2c5c60ce00be2646ded07a43c81953010c07784992e65cb6e078d12c4bf37a63e965bd4216e6cfd320ebaf72debbc9f26e1f7a4b62b50d4e7b5ada62" origin="Generated by Gradle because artifact wasn't signed"/>
</artifact>
</component>
<component group="com.google.android.material" name="material" version="1.8.0">
<artifact name="material-1.8.0.aar">
<sha512 value="0309552e12e49a05ab9002b6cd687ebe5dabe9c7416a676453ef155c0228c4ddd10e8c25a02ef2bd2c320db0e2e88d1fbef9c94f8aa3d9678b47626291b5e979" origin="Generated by Gradle because artifact wasn't signed"/>
</artifact>
<artifact name="material-1.8.0.module">
<sha512 value="07517c0a9b9032f8862b89050f00527ebd4654d5233b195216c9557c7282a59465451e1dccde38944e39059f8e9b0148099c5a36b1acda752b51ae72ef9fe3f9" origin="Generated by Gradle because artifact wasn't signed"/>
</artifact>
</component>
<component group="com.google.auto" name="auto-parent" version="6">
<artifact name="auto-parent-6.pom">
<pgp value="6f7e5acbcd02db60dfd232e45e1f79a7c298661e"/>
</artifact>
</component>
<component group="com.google.errorprone" name="error_prone_annotations" version="2.15.0">
<artifact name="error_prone_annotations-2.15.0.jar">
<sha512 value="f057932e84e8a7ef0683cc7d0e08607bafc4cfb3cd4ab910345c2e42dbd26b511808a357dcda5f5ae44d2d77bac34adf51317e9b608525d56a83228dea56e236" origin="Generated by Gradle because a key couldn't be downloaded"/>
</artifact>
<artifact name="error_prone_annotations-2.15.0.pom">
<sha512 value="30989652831673095a2c43e12d66e4adbfa4472656ce009dc0152daf07ecbafc06ed2bfe9ba10989e699a7a1bfef0e256f6de5d9493c8d82b5d95bf87af8e345" origin="Generated by Gradle because a key couldn't be downloaded"/>
</artifact>
</component>
<component group="com.google.errorprone" name="error_prone_parent" version="2.15.0">
<artifact name="error_prone_parent-2.15.0.pom">
<sha512 value="1c9fbdafd52e855b3b59d25b7faef5bf983852af91d04094044462b045d863b66798a23ac58524e422d7e8794be15d18a85addea8cd512b9066743d80dabca60" origin="Generated by Gradle because a key couldn't be downloaded"/>
</artifact>
</component>
<component group="com.google.testing.platform" name="core-proto" version="0.0.8-alpha07">
<artifact name="core-proto-0.0.8-alpha07.jar">
<sha512 value="0a88a544bef14f152c470e9b1cce129602eff246f26e951e02b9b5d29aec72935068bbe0b459e377ea57511112eacdbc4af077ea18810d78b6e87f20296b1e70" origin="Generated by Gradle because artifact wasn't signed"/>
@ -1028,6 +1113,11 @@
<pgp value="6bdaca2c0493cca133b372d09c4f7e9d98b1cc53"/>
</artifact>
</component>
<component group="org.apache" name="apache" version="16">
<artifact name="apache-16.pom">
<pgp value="0cde80149711eb46dff17ae421a24b3f8b0f594a"/>
</artifact>
</component>
<component group="org.apache" name="apache" version="18">
<artifact name="apache-18.pom">
<pgp value="190d5a957ff22273e601f7a7c92c5fec70161c62"/>
@ -1049,6 +1139,11 @@
<pgp value="2db4f1ef0fa761ecc4ea935c86fdc7e2a11262cb"/>
</artifact>
</component>
<component group="org.apache.commons" name="commons-parent" version="39">
<artifact name="commons-parent-39.pom">
<pgp value="808d78b17a5a2d7c3668e31fbffc9b54721244ad"/>
</artifact>
</component>
<component group="org.apache.commons" name="commons-parent" version="48">
<artifact name="commons-parent-48.pom">
<pgp value="b6e73d84ea4fcc47166087253faad2cd5ecbb314"/>
@ -1074,6 +1169,11 @@
<sha512 value="c675dc20d3d192a4193d651a6fa3ddac3bfe97844be536146ca6e78c29c1559b06fe9495be39d4dbf606b8a2cb0720391a6fe53f37d628949659c3224e4eaa8d" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.junit" name="junit-bom" version="5.7.2">
<artifact name="junit-bom-5.7.2.pom">
<pgp value="ff6e2c001948c5f2f38b0cc385911f425ec61b51"/>
</artifact>
</component>
<component group="org.ow2" name="ow2" version="1.5">
<artifact name="ow2-1.5.pom">
<sha512 value="5445748e294cf9f23fe8f1e18e2ebb7108800d40f81a4566a73f9434fe21d2058d05acf3bc4d15f629151df47c42bcf948de3bba0b6a37982dfc3a8f1baf244d" origin="Generated by Gradle because artifact wasn't signed"/>

14
scripts/0stalkerware.sh Normal file
View file

@ -0,0 +1,14 @@
#!/bin/bash
#License: GPLv3
#Description: Hypatia conversion script for https://github.com/AssoEchap/stalkerware-indicators (CC BY 4.0)
while IFS=, read -r col1SHA col2Package col3Certificate col4Version col5Name
do
if [ -n "$col1SHA" ] && [ -n "$col5Name" ]; then
echo "$col1SHA:0:$col5Name" >> ./stalkerware.hsb;
fi;
done < samples.csv;
sed -i '1d' stalkerware.hsb;
gzip stalkerware.hsb;