Hypatia/app/src/main/java/us/spotco/malwarescanner/Database.java
2017-12-16 15:02:10 -05:00

165 lines
7.6 KiB
Java

package us.spotco.malwarescanner;
import android.content.Context;
import android.os.AsyncTask;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
class Database {
private static TextView log = null;
private static File databasePath = null;
public final static ArrayList<SignatureDatabase> signatureDatabases = new ArrayList<>();
public final static HashMap<String, String> signaturesMD5 = new HashMap<>();
public final static HashMap<String, String> signaturesSHA1 = new HashMap<>();
public final static HashMap<String, String> signaturesSHA256 = new HashMap<>();
public Database(Context context, TextView log) {
Database.log = log;
databasePath = new File(context.getFilesDir() + "/signatures/");
databasePath.mkdir();
signatureDatabases.add(new SignatureDatabase("https://spotco.us/Theia/bofhland_malware_attach.hdb"));
signatureDatabases.add(new SignatureDatabase("https://spotco.us/Theia/crdfam.clamav.hdb"));
signatureDatabases.add(new SignatureDatabase("https://spotco.us/Theia/doppelstern.hdb"));
signatureDatabases.add(new SignatureDatabase("https://spotco.us/Theia/hackingteam.hsb"));
signatureDatabases.add(new SignatureDatabase("https://spotco.us/Theia/main.hdb"));
signatureDatabases.add(new SignatureDatabase("https://spotco.us/Theia/main.hsb"));
signatureDatabases.add(new SignatureDatabase("https://spotco.us/Theia/malware.expert.hdb"));
signatureDatabases.add(new SignatureDatabase("https://spotco.us/Theia/malwarehash.hsb"));
signatureDatabases.add(new SignatureDatabase("https://spotco.us/Theia/porcupine.hsb"));
signatureDatabases.add(new SignatureDatabase("https://spotco.us/Theia/rfxn.hdb"));
signatureDatabases.add(new SignatureDatabase("https://spotco.us/Theia/rogue.hdb"));
signatureDatabases.add(new SignatureDatabase("https://spotco.us/Theia/spamattach.hdb"));
signatureDatabases.add(new SignatureDatabase("https://spotco.us/Theia/spamimg.hdb"));
signatureDatabases.add(new SignatureDatabase("https://spotco.us/Theia/winnow.attachments.hdb"));
signatureDatabases.add(new SignatureDatabase("https://spotco.us/Theia/winnow_bad_cw.hdb"));
signatureDatabases.add(new SignatureDatabase("https://spotco.us/Theia/winnow_extended_malware.hdb"));
signatureDatabases.add(new SignatureDatabase("https://spotco.us/Theia/winnow_malware.hdb"));
}
public static boolean areDatabasesAvailable() {
return databasePath.listFiles().length > 0;
}
public static boolean isDatabaseLoaded() {
return signaturesMD5.size() > 0 && signaturesSHA1.size() > 0 && signaturesSHA256.size() > 0;
}
public static int getSignatureCount() {
return signaturesMD5.size() + signaturesSHA1.size() + signaturesSHA256.size();
}
public static void updateDatabase(ArrayList<SignatureDatabase> signatureDatabases) {
for (SignatureDatabase signatureDatabase : signatureDatabases) {
new Downloader().execute(signatureDatabase.getUrl(), databasePath + "/" + signatureDatabase.getName());
}
}
public static void loadDatabase(boolean ignoreifLoaded, ArrayList<SignatureDatabase> signatureDatabases) {
if (!isDatabaseLoaded() || !ignoreifLoaded && isDatabaseLoaded()) {
signaturesMD5.clear();
signaturesSHA1.clear();
signaturesSHA256.clear();
System.gc();
for (SignatureDatabase database : signatureDatabases) {
File databaseLocation = new File(databasePath + "/" + database.getName());
if (databaseLocation.exists()) {
if (database.getName().contains(".hdb")) {//.hdb format: md5, size, name
try {
BufferedReader reader = new BufferedReader(new FileReader(databaseLocation));
String line;
while ((line = reader.readLine()) != null) {
String[] lineS = line.split(":");
signaturesMD5.put(lineS[0], lineS[2]);
}
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
} else if (database.getName().contains(".hsb")) {//.hsb format: sha256, size, name
try {
BufferedReader reader = new BufferedReader(new FileReader(databaseLocation));
String line;
while ((line = reader.readLine()) != null) {
String[] lineS = line.split(":");
if (lineS[0].length() == 32) {
signaturesSHA1.put(lineS[0], lineS[2]);
} else {
signaturesSHA256.put(lineS[0], lineS[2]);
}
}
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
System.gc();
}
}
public static class Downloader extends AsyncTask<String, String, String> {
@Override
protected String doInBackground(String... strings) {
String url = strings[0];
File out = new File(strings[1]);
publishProgress("Downloading " + url);
try {
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
connection.setConnectTimeout(45000);
connection.setReadTimeout(45000);
connection.addRequestProperty("User-Agent", "Theia: Open Source Android Malware Scanner - Database Updater");
if (out.exists()) {
connection.setIfModifiedSince(out.lastModified());
}
connection.connect();
int res = connection.getResponseCode();
if (res != 304) {
if (res == 200) {
if (out.exists()) {
out.delete();
}
FileOutputStream fileOutputStream = new FileOutputStream(out);
final byte data[] = new byte[1024];
int count;
while ((count = connection.getInputStream().read(data, 0, 1024)) != -1) {
fileOutputStream.write(data, 0, count);
}
fileOutputStream.close();
publishProgress("Successfully downloaded\n");
} else {
publishProgress("File not downloaded, response code " + res + "\n");
}
} else {
publishProgress("File not changed\n");
}
connection.disconnect();
} catch (Exception e) {
e.printStackTrace();
out.delete();
publishProgress("Failed to download, check logcat\n");
}
return null;
}
@Override
protected final void onProgressUpdate(String... progress) {
log.append(progress[0] + "\n");
}
}
}