Add the malware scanner task

This commit is contained in:
Tad 2018-10-21 23:00:39 -04:00
parent 0d6cbddecb
commit c40ff53cb0
3 changed files with 130 additions and 6 deletions

View file

@ -54,7 +54,7 @@ public class DatabaseManager {
new File(databasePath + "/" + name).delete(); new File(databasePath + "/" + name).delete();
} }
public void loadRemoteDatabases() { public static void loadRemoteDatabases() {
try { try {
signatureDatabases.clear(); signatureDatabases.clear();
String api = Utils.prefs.getString("database_repo", "https://spotco.us/MalwareScannerSignatures/api.php"); String api = Utils.prefs.getString("database_repo", "https://spotco.us/MalwareScannerSignatures/api.php");
@ -78,7 +78,7 @@ public class DatabaseManager {
} }
} }
public void updateDatabases() { public static void updateDatabases() {
loadRemoteDatabases(); loadRemoteDatabases();
for (Signatures.SignatureDatabase db : signatureDatabases) { for (Signatures.SignatureDatabase db : signatureDatabases) {
if (db.isAvailable()) { if (db.isAvailable()) {
@ -88,7 +88,7 @@ public class DatabaseManager {
loadAllAvailableDatabases(true); loadAllAvailableDatabases(true);
} }
public void loadAllAvailableDatabases(boolean forceReload) { public static void loadAllAvailableDatabases(boolean forceReload) {
if (!Signatures.available() || forceReload) { if (!Signatures.available() || forceReload) {
Signatures.clear(); Signatures.clear();
for (Signatures.SignatureDatabase db : signatureDatabases) { for (Signatures.SignatureDatabase db : signatureDatabases) {
@ -102,7 +102,7 @@ public class DatabaseManager {
} }
} }
private void loadDatabase(File database) { private static void loadDatabase(File database) {
try { try {
if (database.exists()) { if (database.exists()) {
BufferedReader reader; BufferedReader reader;

View file

@ -17,5 +17,128 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package us.spotco.malwarescanner; package us.spotco.malwarescanner;
public class MalwareScanner { import android.os.AsyncTask;
} import android.os.Environment;
import android.os.SystemClock;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
class MalwareScanner extends AsyncTask<Set<File>, Object, String> {
private boolean userFacing = false;
private long scanTime = 0;
private int hashMaxLength = 0;
private final HashMap<String, File> fileHashesMD5 = new HashMap<>();
private final HashMap<String, File> fileHashesSHA1 = new HashMap<>();
private final HashMap<String, File> fileHashesSHA256 = new HashMap<>();
public MalwareScanner(boolean userFacing) {
this.userFacing = userFacing;
hashMaxLength = Utils.prefs.getInt("database_hash_length", 12);
}
private void returnResult(String result, boolean userFacingOnly) {
//TODO HANDLE STATUS UPDATES
}
@Override
protected final void onPreExecute() {
scanTime = SystemClock.elapsedRealtime();
returnResult("Starting scan...", true);
}
@Override
protected final String doInBackground(Set<File>[] filesToScan) {
//Pre
fileHashesMD5.clear();
fileHashesSHA1.clear();
fileHashesSHA256.clear();
publishProgress(filesToScan[0].size() + " files pending scan\n", true);
DatabaseManager.loadAllAvailableDatabases(false);
if (Signatures.getSignatureCount() >= 0) {
publishProgress("Loaded database with " + Signatures.getSignatureCount() + " signatures\n", true);
//Get file hashes
publishProgress("Hashing files...", true);
for (File file : filesToScan[0]) {
getFileHashes(file);
}
publishProgress("Calculated MD5/SHA-1/SHA-256 hashes for all files\n", true);
//Check the hashes
checkSignature("MD5", fileHashesMD5, Signatures.MD5);
checkSignature("SHA-1", fileHashesSHA1, Signatures.SHA1);
checkSignature("SHA-256", fileHashesSHA256, Signatures.SHA256);
//Post
fileHashesMD5.clear();
fileHashesSHA1.clear();
fileHashesSHA256.clear();
System.gc();
Utils.amtFilesScanned += filesToScan[0].size();
publishProgress("Scan completed in " + ((SystemClock.elapsedRealtime() - scanTime) / 1000) + " seconds!\n\n\n\n", true);
} else {
publishProgress("No database available, not scanning...", true);
}
return null;
}
@Override
protected final void onProgressUpdate(Object... objects) {
returnResult((String) objects[0], (boolean) objects[1]);
}
private void checkSignature(String hashType, HashMap<String, File> signaturesToCheck, HashMap<String, String> signatureDatabase) {
if (signatureDatabase.size() > 0) {
for (Map.Entry<String, File> file : signaturesToCheck.entrySet()) {
if (signatureDatabase.containsKey(file.getKey())) {
String result = signatureDatabase.get(file.getKey());
publishProgress(result + " in " + file.getValue().toString().replaceAll(Environment.getExternalStorageDirectory().toString(), "~"), false);
}
}
publishProgress("Checked all " + hashType + " hashes against signature databases\n", true);
} else {
publishProgress("No " + hashType + " signatures available\n", true);
}
}
private void getFileHashes(File file) {
try {
InputStream fis = new FileInputStream(file);
byte[] buffer = new byte[4096];
int numRead;
MessageDigest digestMD5 = MessageDigest.getInstance("MD5");
MessageDigest digestSHA1 = MessageDigest.getInstance("SHA-1");
MessageDigest digestSHA256 = MessageDigest.getInstance("SHA-256");
do {
numRead = fis.read(buffer);
if (numRead > 0) {
digestMD5.update(buffer, 0, numRead);
digestSHA1.update(buffer, 0, numRead);
digestSHA256.update(buffer, 0, numRead);
}
} while (numRead != -1);
fis.close();
fileHashesMD5.put(String.format("%032x", new BigInteger(1, digestMD5.digest())).substring(0, hashMaxLength), file);
fileHashesSHA1.put(String.format("%032x", new BigInteger(1, digestSHA1.digest())).substring(0, hashMaxLength), file);
fileHashesSHA256.put(String.format("%064x", new BigInteger(1, digestSHA256.digest())).substring(0, hashMaxLength), file);
} catch (Exception e) {
e.printStackTrace();
}
}
}

View file

@ -36,6 +36,7 @@ import java.util.concurrent.ThreadPoolExecutor;
public class Utils { public class Utils {
public static int amtFilesScanned = 0;
public static SharedPreferences prefs = null; public static SharedPreferences prefs = null;
public Utils(Context context) { public Utils(Context context) {