Actually scan the files!

This commit is contained in:
Tad 2017-12-14 14:56:54 -05:00
parent cbc8c1e64a
commit 4fef7344e2
3 changed files with 87 additions and 47 deletions

View file

@ -20,13 +20,15 @@ public class Database {
private static TextView log = null; private static TextView log = null;
private static File databasePath = null; private static File databasePath = null;
private static HashMap<String, String> signaturesMD5 = new HashMap<String, String>(); public static HashMap<String, String> signaturesMD5 = new HashMap<String, String>();
private static HashMap<String, String> signaturesSHA256 = new HashMap<String, String>(); public static HashMap<String, String> signaturesSHA1 = new HashMap<String, String>();
public static HashMap<String, String> signaturesSHA256 = new HashMap<String, String>();
public Database(Context context, TextView log) { public Database(Context context, TextView log) {
this.context = context; this.context = context;
this.log = log; this.log = log;
this.databasePath = new File(context.getFilesDir() + "signatures/"); this.databasePath = new File(context.getFilesDir() + "/signatures/");
this.databasePath.mkdir();
} }
public static boolean doesDatabaseExist() { public static boolean doesDatabaseExist() {
@ -35,16 +37,14 @@ public class Database {
public static void updateDatabase(ArrayList<SignatureDatabase> signatureDatabases) { public static void updateDatabase(ArrayList<SignatureDatabase> signatureDatabases) {
for(SignatureDatabase signatureDatabase : 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<SignatureDatabase> signatureDatabases) { public static void loadDatabase(ArrayList<SignatureDatabase> signatureDatabases) {
for(SignatureDatabase database : signatureDatabases) { for(SignatureDatabase database : signatureDatabases) {
File databaseLocation = new File(databasePath + database.getName()); File databaseLocation = new File(databasePath + "/" + database.getName());
if(!databaseLocation.exists()) { if(databaseLocation.exists()) {
log.append("Database " + database.getName() + " doesn't exist!\n");
} else {
if (database.getName().contains(".hdb")) {//.hdb format: md5, size, name if (database.getName().contains(".hdb")) {//.hdb format: md5, size, name
try { try {
Scanner scanner = new Scanner(databaseLocation); Scanner scanner = new Scanner(databaseLocation);
@ -61,7 +61,11 @@ public class Database {
Scanner scanner = new Scanner(databaseLocation); Scanner scanner = new Scanner(databaseLocation);
while(scanner.hasNextLine()) { while(scanner.hasNextLine()) {
String[] line = scanner.nextLine().split(":"); 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(); scanner.close();
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
@ -77,6 +81,9 @@ public class Database {
if (signaturesMD5.containsKey(hash)) { if (signaturesMD5.containsKey(hash)) {
return signaturesMD5.get(hash); return signaturesMD5.get(hash);
} }
if (signaturesSHA1.containsKey(hash)) {
return signaturesSHA1.get(hash);
}
} else if(hash.length() == 64) { } else if(hash.length() == 64) {
if (signaturesSHA256.containsKey(hash)) { if (signaturesSHA256.containsKey(hash)) {
return signaturesSHA256.get(hash); return signaturesSHA256.get(hash);

View file

@ -10,9 +10,10 @@ import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.widget.TextView; import android.widget.TextView;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity { public class MainActivity extends AppCompatActivity {
private boolean checkUpdates = true;
private boolean scanSystem = true; private boolean scanSystem = true;
private boolean scanApps = true; private boolean scanApps = true;
private boolean scanInternal = true; private boolean scanInternal = true;
@ -29,10 +30,16 @@ public class MainActivity extends AppCompatActivity {
logView.setMovementMethod(new ScrollingMovementMethod()); logView.setMovementMethod(new ScrollingMovementMethod());
logView.append("Copyright 2017 Spot Communications, Inc.\n"); logView.append("Copyright 2017 Spot Communications, Inc.\n");
logView.append("License: GPLv3\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"); logView.append("\nDisclaimer: This is an extremely basic signature scanner\n\n");
final Database database = new Database(this, logView); final Database database = new Database(this, logView);
ArrayList<SignatureDatabase> signatureDatabases = new ArrayList<SignatureDatabase>();
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); final MalwareScanner scanner = new MalwareScanner(this, logView);
FloatingActionButton fab = findViewById(R.id.fab); FloatingActionButton fab = findViewById(R.id.fab);
@ -57,10 +64,6 @@ public class MainActivity extends AppCompatActivity {
@Override @Override
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) { switch (item.getItemId()) {
case R.id.mnuUpdateDatabase:
checkUpdates = !item.isChecked();
item.setChecked(checkUpdates);
break;
case R.id.mnuScanSystem: case R.id.mnuScanSystem:
scanSystem = !item.isChecked(); scanSystem = !item.isChecked();
item.setChecked(scanSystem); item.setChecked(scanSystem);

View file

@ -7,11 +7,13 @@ import android.os.AsyncTask;
import android.os.Environment; import android.os.Environment;
import android.widget.TextView; import android.widget.TextView;
import com.google.common.hash.HashFunction;
import com.google.common.hash.Hashing; import com.google.common.hash.Hashing;
import com.google.common.io.Files; import com.google.common.io.Files;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map; import java.util.Map;
@ -29,11 +31,11 @@ public class MalwareScanner {
} }
public void startScanner(boolean scanSystem, boolean scanApps, boolean scanInternal, boolean scanExternal) { 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); malwareScannerTask = new MalwareScannerTask().execute(scanSystem, scanApps, scanInternal, scanExternal);
} else { //} else {
log.append("No database found... download one first!\n"); // log.append("No database found... download one first!\n");
} //}
} }
public void stopScanner() { public void stopScanner() {
@ -85,28 +87,65 @@ public class MalwareScanner {
publishProgress(filesToScan.size() + " files pending scan"); publishProgress(filesToScan.size() + " files pending scan");
HashMap<String, File> fileHashesMD5 = new HashMap<String, File>(); HashMap<String, File> fileHashesMD5 = new HashMap<String, File>();
HashMap<String, File> fileHashesSHA1 = new HashMap<String, File>();
HashMap<String, File> fileHashesSHA256 = new HashMap<String, File>(); HashMap<String, File> fileHashesSHA256 = new HashMap<String, File>();
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<String, File> file : fileHashesMD5.entrySet()) { ArrayList<SignatureDatabase> signatureDatabases = new ArrayList<SignatureDatabase>();
String result = Database.checkInDatabase(file.getKey()); signatureDatabases.add(new SignatureDatabase("https://spotco.us/clamav-main.hdb", "clamav-main.hdb"));
if(result != null) { signatureDatabases.add(new SignatureDatabase("https://spotco.us/clamav-main.hsb", "clamav-main.hsb"));
publishProgress(file.getValue() + " detected as " + result); Database.loadDatabase(signatureDatabases);
} publishProgress("Loaded database with " + Database.signaturesMD5.size() + " signatures");
} publishProgress("Loaded database with " + Database.signaturesSHA1.size() + " signatures");
publishProgress("Checked all MD5 hashes against signature databases"); publishProgress("Loaded database with " + Database.signaturesSHA256.size() + " signatures");
for(Map.Entry<String, File> file : fileHashesSHA256.entrySet()) { if(Database.signaturesMD5.size() > 0) {
String result = Database.checkInDatabase(file.getKey()); for (File file : filesToScan) {
if(result != null) { fileHashesMD5.put(getFileHashSum(file, Hashing.md5()), file);
publishProgress(file.getValue() + " detected as " + result);
} }
publishProgress("Calculated MD5 hashes for all files");
for(Map.Entry<String, File> 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<String, File> 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<String, File> 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; return null;
} }
@ -142,18 +181,9 @@ public class MalwareScanner {
return filesAll; return filesAll;
} }
private String getFileMD5Sum(File file) { private String getFileHashSum(File file, HashFunction hash) {
try { try {
return Files.asByteSource(file).hash(Hashing.md5()).toString(); return Files.asByteSource(file).hash(hash).toString();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
private String getFileSHA256Sum(File file) {
try {
return Files.asByteSource(file).hash(Hashing.sha256()).toString();
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }