diff --git a/app/src/main/java/us/spotco/malwarescanner/Database.java b/app/src/main/java/us/spotco/malwarescanner/Database.java index 7f10436..33a016e 100644 --- a/app/src/main/java/us/spotco/malwarescanner/Database.java +++ b/app/src/main/java/us/spotco/malwarescanner/Database.java @@ -20,13 +20,15 @@ public class Database { private static TextView log = null; private static File databasePath = null; - private static HashMap signaturesMD5 = new HashMap(); - private static HashMap signaturesSHA256 = new HashMap(); + public static HashMap signaturesMD5 = new HashMap(); + public static HashMap signaturesSHA1 = new HashMap(); + public static HashMap signaturesSHA256 = new HashMap(); public Database(Context context, TextView log) { this.context = context; this.log = log; - this.databasePath = new File(context.getFilesDir() + "signatures/"); + this.databasePath = new File(context.getFilesDir() + "/signatures/"); + this.databasePath.mkdir(); } public static boolean doesDatabaseExist() { @@ -35,16 +37,14 @@ public class Database { public static void updateDatabase(ArrayList signatureDatabases) { for(SignatureDatabase signatureDatabase : signatureDatabases) { - new Downloader().execute(signatureDatabase.getUrl(), context.getFilesDir() + signatureDatabase.getName()); + new Downloader().execute(signatureDatabase.getUrl(), databasePath + "/" + signatureDatabase.getName()); } } public static void loadDatabase(ArrayList signatureDatabases) { for(SignatureDatabase database : signatureDatabases) { - File databaseLocation = new File(databasePath + database.getName()); - if(!databaseLocation.exists()) { - log.append("Database " + database.getName() + " doesn't exist!\n"); - } else { + File databaseLocation = new File(databasePath + "/" + database.getName()); + if(databaseLocation.exists()) { if (database.getName().contains(".hdb")) {//.hdb format: md5, size, name try { Scanner scanner = new Scanner(databaseLocation); @@ -61,7 +61,11 @@ public class Database { Scanner scanner = new Scanner(databaseLocation); while(scanner.hasNextLine()) { String[] line = scanner.nextLine().split(":"); - signaturesSHA256.put(line[0], line[2]); + if(line[0].length() == 32) { + signaturesSHA1.put(line[0], line[2]); + } else { + signaturesSHA256.put(line[0], line[2]); + } } scanner.close(); } catch (FileNotFoundException e) { @@ -77,6 +81,9 @@ public class Database { if (signaturesMD5.containsKey(hash)) { return signaturesMD5.get(hash); } + if (signaturesSHA1.containsKey(hash)) { + return signaturesSHA1.get(hash); + } } else if(hash.length() == 64) { if (signaturesSHA256.containsKey(hash)) { return signaturesSHA256.get(hash); diff --git a/app/src/main/java/us/spotco/malwarescanner/MainActivity.java b/app/src/main/java/us/spotco/malwarescanner/MainActivity.java index 70659fc..c41d5ad 100644 --- a/app/src/main/java/us/spotco/malwarescanner/MainActivity.java +++ b/app/src/main/java/us/spotco/malwarescanner/MainActivity.java @@ -10,9 +10,10 @@ import android.view.MenuItem; import android.view.View; import android.widget.TextView; +import java.util.ArrayList; + public class MainActivity extends AppCompatActivity { - private boolean checkUpdates = true; private boolean scanSystem = true; private boolean scanApps = true; private boolean scanInternal = true; @@ -29,10 +30,16 @@ public class MainActivity extends AppCompatActivity { logView.setMovementMethod(new ScrollingMovementMethod()); logView.append("Copyright 2017 Spot Communications, Inc.\n"); logView.append("License: GPLv3\n"); - logView.append("Powered by ClamAV signatures, License: GPLv3\n"); + logView.append("Powered by ClamAV signatures\n"); logView.append("\nDisclaimer: This is an extremely basic signature scanner\n\n"); final Database database = new Database(this, logView); + + ArrayList signatureDatabases = new ArrayList(); + signatureDatabases.add(new SignatureDatabase("https://spotco.us/clamav-main.hdb", "clamav-main.hdb")); + signatureDatabases.add(new SignatureDatabase("https://spotco.us/clamav-main.hsb", "clamav-main.hsb")); + Database.updateDatabase(signatureDatabases); + final MalwareScanner scanner = new MalwareScanner(this, logView); FloatingActionButton fab = findViewById(R.id.fab); @@ -57,10 +64,6 @@ public class MainActivity extends AppCompatActivity { @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { - case R.id.mnuUpdateDatabase: - checkUpdates = !item.isChecked(); - item.setChecked(checkUpdates); - break; case R.id.mnuScanSystem: scanSystem = !item.isChecked(); item.setChecked(scanSystem); diff --git a/app/src/main/java/us/spotco/malwarescanner/MalwareScanner.java b/app/src/main/java/us/spotco/malwarescanner/MalwareScanner.java index 43ec20a..a600a7d 100644 --- a/app/src/main/java/us/spotco/malwarescanner/MalwareScanner.java +++ b/app/src/main/java/us/spotco/malwarescanner/MalwareScanner.java @@ -7,11 +7,13 @@ import android.os.AsyncTask; import android.os.Environment; import android.widget.TextView; +import com.google.common.hash.HashFunction; import com.google.common.hash.Hashing; import com.google.common.io.Files; import java.io.File; import java.io.IOException; +import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Map; @@ -29,11 +31,11 @@ public class MalwareScanner { } public void startScanner(boolean scanSystem, boolean scanApps, boolean scanInternal, boolean scanExternal) { - if(Database.doesDatabaseExist()) { + //if(Database.doesDatabaseExist()) { malwareScannerTask = new MalwareScannerTask().execute(scanSystem, scanApps, scanInternal, scanExternal); - } else { - log.append("No database found... download one first!\n"); - } + //} else { + // log.append("No database found... download one first!\n"); + //} } public void stopScanner() { @@ -85,28 +87,65 @@ public class MalwareScanner { publishProgress(filesToScan.size() + " files pending scan"); HashMap fileHashesMD5 = new HashMap(); + HashMap fileHashesSHA1 = new HashMap(); HashMap fileHashesSHA256 = new HashMap(); - for(File file : filesToScan) { - fileHashesMD5.put(getFileMD5Sum(file), file); - fileHashesSHA256.put(getFileSHA256Sum(file), file); - } - publishProgress("Calculated MD5 and SHA256 hashes for all files"); - for(Map.Entry file : fileHashesMD5.entrySet()) { - String result = Database.checkInDatabase(file.getKey()); - if(result != null) { - publishProgress(file.getValue() + " detected as " + result); - } - } - publishProgress("Checked all MD5 hashes against signature databases"); + ArrayList signatureDatabases = new ArrayList(); + signatureDatabases.add(new SignatureDatabase("https://spotco.us/clamav-main.hdb", "clamav-main.hdb")); + signatureDatabases.add(new SignatureDatabase("https://spotco.us/clamav-main.hsb", "clamav-main.hsb")); + Database.loadDatabase(signatureDatabases); + publishProgress("Loaded database with " + Database.signaturesMD5.size() + " signatures"); + publishProgress("Loaded database with " + Database.signaturesSHA1.size() + " signatures"); + publishProgress("Loaded database with " + Database.signaturesSHA256.size() + " signatures"); - for(Map.Entry file : fileHashesSHA256.entrySet()) { - String result = Database.checkInDatabase(file.getKey()); - if(result != null) { - publishProgress(file.getValue() + " detected as " + result); + if(Database.signaturesMD5.size() > 0) { + for (File file : filesToScan) { + fileHashesMD5.put(getFileHashSum(file, Hashing.md5()), file); } + publishProgress("Calculated MD5 hashes for all files"); + for(Map.Entry file : fileHashesMD5.entrySet()) { + String result = Database.checkInDatabase(file.getKey()); + if(result != null) { + publishProgress(file.getValue() + " detected as " + result); + } + } + publishProgress("Checked all MD5 hashes against signature databases"); + } else { + publishProgress("No MD5 signatures available"); } - publishProgress("Checked all SHA256 hashes against signature databases"); + + if(Database.signaturesSHA1.size() > 0) { + for (File file : filesToScan) { + fileHashesSHA1.put(getFileHashSum(file, Hashing.sha1()), file); + } + publishProgress("Calculated SHA1 hashes for all files"); + for(Map.Entry file : fileHashesSHA1.entrySet()) { + String result = Database.checkInDatabase(file.getKey()); + if(result != null) { + publishProgress(file.getValue() + " detected as " + result); + } + } + publishProgress("Checked all SHA1 hashes against signature databases"); + } else { + publishProgress("No SHA1 signatures available"); + } + + if(Database.signaturesSHA256.size() > 0) { + for (File file : filesToScan) { + fileHashesSHA256.put(getFileHashSum(file, Hashing.sha256()), file); + } + publishProgress("Calculated SHA256 hashes for all files"); + for(Map.Entry file : fileHashesSHA256.entrySet()) { + String result = Database.checkInDatabase(file.getKey()); + if(result != null) { + publishProgress(file.getValue() + " detected as " + result); + } + } + publishProgress("Checked all SHA256 hashes against signature databases"); + } else { + publishProgress("No SHA256 signatures available"); + } + return null; } @@ -142,18 +181,9 @@ public class MalwareScanner { return filesAll; } - private String getFileMD5Sum(File file) { + private String getFileHashSum(File file, HashFunction hash) { try { - return Files.asByteSource(file).hash(Hashing.md5()).toString(); - } catch (IOException e) { - e.printStackTrace(); - } - return null; - } - - private String getFileSHA256Sum(File file) { - try { - return Files.asByteSource(file).hash(Hashing.sha256()).toString(); + return Files.asByteSource(file).hash(hash).toString(); } catch (IOException e) { e.printStackTrace(); }