diff --git a/.idea/misc.xml b/.idea/misc.xml index 47eabe0..6faa303 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -24,7 +24,7 @@ - + diff --git a/app/src/main/java/us/spotco/malwarescanner/Database.java b/app/src/main/java/us/spotco/malwarescanner/Database.java index 32cb505..7f10436 100644 --- a/app/src/main/java/us/spotco/malwarescanner/Database.java +++ b/app/src/main/java/us/spotco/malwarescanner/Database.java @@ -6,43 +6,82 @@ import android.view.MenuItem; import android.widget.TextView; import java.io.File; +import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.net.HttpURLConnection; import java.net.URL; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Scanner; public class Database { private static Context context = null; private static TextView log = null; - private static MenuItem databaseUpdateCheckOption = null; private static File databasePath = null; - private static String databaseName = "clamav-main.hsb"; - private static final String databaseUpdateURL = "https://spotco.us/clamav-main.hsb"; - public Database(Context context, TextView log, MenuItem databaseUpdateCheckOption) { + private static HashMap signaturesMD5 = new HashMap(); + private static HashMap signaturesSHA256 = new HashMap(); + + public Database(Context context, TextView log) { this.context = context; this.log = log; - this.databaseUpdateCheckOption = databaseUpdateCheckOption; - databasePath = new File(context.getFilesDir() + databaseName); + this.databasePath = new File(context.getFilesDir() + "signatures/"); } public static boolean doesDatabaseExist() { - return databasePath.exists(); + return databasePath.listFiles().length > 0; } - public static boolean shouldUpdateDatabase() { - return databaseUpdateCheckOption.isChecked(); + public static void updateDatabase(ArrayList signatureDatabases) { + for(SignatureDatabase signatureDatabase : signatureDatabases) { + new Downloader().execute(signatureDatabase.getUrl(), context.getFilesDir() + signatureDatabase.getName()); + } } - public static void updateDatabase() { - new Downloader().execute(databaseUpdateURL, databasePath.toString()); - } - - public static void loadDatabase() { - //Database format: md5, size, name, unknown + 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 { + if (database.getName().contains(".hdb")) {//.hdb format: md5, size, name + try { + Scanner scanner = new Scanner(databaseLocation); + while(scanner.hasNextLine()) { + String[] line = scanner.nextLine().split(":"); + signaturesMD5.put(line[0], line[2]); + } + scanner.close(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + } else if (database.getName().contains(".hsb")) {//.hsb format: sha256, size, name + try { + Scanner scanner = new Scanner(databaseLocation); + while(scanner.hasNextLine()) { + String[] line = scanner.nextLine().split(":"); + signaturesSHA256.put(line[0], line[2]); + } + scanner.close(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + } + } + } } public static String checkInDatabase(String hash) { + if(hash.length() == 32) { + if (signaturesMD5.containsKey(hash)) { + return signaturesMD5.get(hash); + } + } else if(hash.length() == 64) { + if (signaturesSHA256.containsKey(hash)) { + return signaturesSHA256.get(hash); + } + } return null; } diff --git a/app/src/main/java/us/spotco/malwarescanner/MainActivity.java b/app/src/main/java/us/spotco/malwarescanner/MainActivity.java index 5bdb096..70659fc 100644 --- a/app/src/main/java/us/spotco/malwarescanner/MainActivity.java +++ b/app/src/main/java/us/spotco/malwarescanner/MainActivity.java @@ -32,9 +32,7 @@ public class MainActivity extends AppCompatActivity { logView.append("Powered by ClamAV signatures, License: GPLv3\n"); logView.append("\nDisclaimer: This is an extremely basic signature scanner\n\n"); - MenuItem databaseUpdateCheckOption = findViewById(R.id.mnuUpdateDatabase); - - final Database database = new Database(this, logView, databaseUpdateCheckOption); + final Database database = new Database(this, logView); final MalwareScanner scanner = new MalwareScanner(this, logView); FloatingActionButton fab = findViewById(R.id.fab); diff --git a/app/src/main/java/us/spotco/malwarescanner/MalwareScanner.java b/app/src/main/java/us/spotco/malwarescanner/MalwareScanner.java index 3678e10..43ec20a 100644 --- a/app/src/main/java/us/spotco/malwarescanner/MalwareScanner.java +++ b/app/src/main/java/us/spotco/malwarescanner/MalwareScanner.java @@ -12,7 +12,9 @@ import com.google.common.io.Files; import java.io.File; import java.io.IOException; +import java.util.HashMap; import java.util.HashSet; +import java.util.Map; import java.util.Set; public class MalwareScanner { @@ -30,8 +32,7 @@ public class MalwareScanner { if(Database.doesDatabaseExist()) { malwareScannerTask = new MalwareScannerTask().execute(scanSystem, scanApps, scanInternal, scanExternal); } else { - log.append("No database found... downloading!\n"); - Database.updateDatabase(); + log.append("No database found... download one first!\n"); } } @@ -83,8 +84,29 @@ public class MalwareScanner { } publishProgress(filesToScan.size() + " files pending scan"); - //TODO: Hash the files - //TODO: Check the status of the files + HashMap fileHashesMD5 = 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"); + + 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"); return null; } @@ -129,4 +151,13 @@ public class MalwareScanner { return null; } + private String getFileSHA256Sum(File file) { + try { + return Files.asByteSource(file).hash(Hashing.sha256()).toString(); + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + } diff --git a/app/src/main/java/us/spotco/malwarescanner/SignatureDatabase.java b/app/src/main/java/us/spotco/malwarescanner/SignatureDatabase.java new file mode 100644 index 0000000..167fbc4 --- /dev/null +++ b/app/src/main/java/us/spotco/malwarescanner/SignatureDatabase.java @@ -0,0 +1,21 @@ +package us.spotco.malwarescanner; + +public class SignatureDatabase { + + private String url = null; + private String name = null; + + public SignatureDatabase(String url, String name) { + this.url = url; + this.name = name; + } + + public String getUrl() { + return url; + } + + public String getName() { + return name; + } + +} diff --git a/app/src/main/res/menu/menu_main.xml b/app/src/main/res/menu/menu_main.xml index 90f2924..481b174 100644 --- a/app/src/main/res/menu/menu_main.xml +++ b/app/src/main/res/menu/menu_main.xml @@ -3,11 +3,6 @@ xmlns:tools="http://schemas.android.com/tools" tools:context="us.spotco.malwarescanner.MainActivity"> -