package gui;
import com.jgoodies.forms.factories.FormFactory;
import com.jgoodies.forms.layout.ColumnSpec;
import com.jgoodies.forms.layout.FormLayout;
import com.jgoodies.forms.layout.RowSpec;
import org.apache.commons.io.FileUtils;
import parser.apk.APK;
import parser.elf.Elf;
import parser.utils.FileTypesDetector;
import parser.utils.HashTool;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.sql.*;
import java.util.*;
/**
* Created with IntelliJ IDEA.
* User: lai
* Date: 5/29/13
* Time: 10:47 AM
*/
public class DetectorGUI extends JPanel {
private final JTextField filePath;
private JTextArea jTextAreaInfos = null;
private JTextArea jTextAreaCertificate = null;
private JTextArea jTextAreaActivities = null;
private JTextArea jTextAreaReceivers = null;
private JTextArea jTextAreaServices = null;
private JTextArea jTextAreaPermissions = null;
public DetectorGUI() {
// ----------------------------------------------- Layout ------------------------------------------------------
setLayout(new FormLayout(new ColumnSpec[]{ColumnSpec.decode("11dlu"),
ColumnSpec.decode("min:grow"),
FormFactory.LABEL_COMPONENT_GAP_COLSPEC,
ColumnSpec.decode("100px"), ColumnSpec.decode("10dlu"),},
new RowSpec[]{RowSpec.decode("15dlu"),
RowSpec.decode("23px"), RowSpec.decode("21px"),
RowSpec.decode("23px"),
FormFactory.RELATED_GAP_ROWSPEC,
RowSpec.decode("default:grow"),
FormFactory.DEFAULT_ROWSPEC,}
));
filePath = new JTextField();
filePath.setText("/home/lai/Work/samples/Test/Trojan-Spy.AndroidOS.Adrd/");
add(filePath, "2, 2, fill, fill");
// -------------------------------- Button -----------------------------------
final JButton jButtonFile = new JButton("File");
add(jButtonFile, "4, 2, fill, fill");
final JButton jButtonAnalysis = new JButton("Analysis");
add(jButtonAnalysis, "4, 3, fill, fill");
final JButton jButtonClearAll = new JButton("Clear");
add(jButtonClearAll, "4, 4, fill, fill");
// -------------------------------- Tab -----------------------------------
final JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.TOP);
add(tabbedPane, "2, 6, 3, 1, fill, fill");
final JScrollPane scrollPaneInfos = new JScrollPane();
tabbedPane.addTab("Infos", null, scrollPaneInfos, null);
jTextAreaInfos = new JTextArea();
scrollPaneInfos.setViewportView(jTextAreaInfos);
final JScrollPane scrollPaneCertificate = new JScrollPane();
tabbedPane.addTab("Certificate", null, scrollPaneCertificate, null);
jTextAreaCertificate = new JTextArea();
scrollPaneCertificate.setViewportView(jTextAreaCertificate);
final JScrollPane scrollPaneActivities = new JScrollPane();
tabbedPane.addTab("Activities", null, scrollPaneActivities, null);
jTextAreaActivities = new JTextArea();
scrollPaneActivities.setViewportView(jTextAreaActivities);
final JScrollPane scrollPaneReceivers = new JScrollPane();
tabbedPane.addTab("Receivers", null, scrollPaneReceivers, null);
jTextAreaReceivers = new JTextArea();
scrollPaneReceivers.setViewportView(jTextAreaReceivers);
final JScrollPane scrollPaneServices = new JScrollPane();
tabbedPane.addTab("Services", null, scrollPaneServices, null);
jTextAreaServices = new JTextArea();
scrollPaneServices.setViewportView(jTextAreaServices);
final JScrollPane scrollPanePermissions = new JScrollPane();
tabbedPane.addTab("Permissions", null, scrollPanePermissions, null);
jTextAreaPermissions = new JTextArea();
scrollPanePermissions.setViewportView(jTextAreaPermissions);
// ----------------------------------------------- Event -------------------------------------------------------
new FileDrop(System.out, filePath,
new FileDrop.Listener() {
@Override
public void filesDropped(File[] files) {
File f = files[0];
filePath.setText(f.getAbsolutePath());
}
}
);
jButtonFile.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
final JFileChooser fc = new JFileChooser();
final int returnVal = fc.showOpenDialog(null);
if (returnVal == JFileChooser.APPROVE_OPTION) {
filePath.setText(fc.getSelectedFile().getAbsolutePath());
}
}
});
jButtonAnalysis.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
final AnalysisTask task = new AnalysisTask(filePath.getText(), jTextAreaInfos, jTextAreaCertificate,
jTextAreaActivities, jTextAreaReceivers, jTextAreaServices, jTextAreaPermissions, jButtonAnalysis);
task.execute();
jButtonAnalysis.setEnabled(false);
}
});
jButtonClearAll.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
jTextAreaInfos.setText("");
jTextAreaCertificate.setText("");
jTextAreaActivities.setText("");
jTextAreaReceivers.setText("");
jTextAreaServices.setText("");
jTextAreaPermissions.setText("");
}
});
}
}
class AnalysisTask extends SwingWorker<HashMap<Byte, String>, String> {
private final Byte FLAG_INFOS = 0;
private final Byte FLAG_CERTIFICATE = 1;
private final Byte FLAG_ACTIVITIES = 2;
private final Byte FLAG_RECEIVERS = 3;
private final Byte FLAG_SERVICES = 4;
private final Byte FLAG_PERMISSIONS = 5;
private final JButton jButtonAnalysis;
private final String filePath;
private final HashMap<String, String> permissionsMap = new HashMap<>();
private final Connection conn;
private JTextArea jTextAreaInfos = null;
private JTextArea jTextAreaCertificate = null;
private JTextArea jTextAreaActivities = null;
private JTextArea jTextAreaReceivers = null;
private JTextArea jTextAreaServices = null;
private JTextArea jTextAreaPermissions = null;
// permission configure
private String PERMISSION_PATH = "conf/permissions.xml";
public AnalysisTask(String text, JTextArea jTextAreaInfos, JTextArea jTextAreaCertificate,
JTextArea jTextAreaActivities, JTextArea jTextAreaReceivers,
JTextArea jTextAreaServices, JTextArea jTextAreaPermissions, JButton jButtonAnalysis) {
this.filePath = text;
this.jTextAreaInfos = jTextAreaInfos;
this.jTextAreaCertificate = jTextAreaCertificate;
this.jTextAreaActivities = jTextAreaActivities;
this.jTextAreaReceivers = jTextAreaReceivers;
this.jTextAreaServices = jTextAreaServices;
this.jTextAreaPermissions = jTextAreaPermissions;
this.jButtonAnalysis = jButtonAnalysis;
conn = prepareDb();
}
private HashMap<Byte, String> getAPKInfo() throws Exception {
HashMap<Byte, String> hashMap = new HashMap<>();
APK apk = new APK(filePath, true, false, true);
System.out.println("--------------------->>>>>>>>>");
StringBuilder sb = new StringBuilder();
sb.append("FileName : ").append(apk.getFileName()).append("\n");
sb.append("PackageName : ").append(apk.getPackageName()).append("\n");
sb.append("Label : ").append(apk.getLabel()).append("\n");
sb.append("VersionCode : ").append(apk.getVersionCode()).append("\n");
sb.append("VersionName : ").append(apk.getVersionName()).append("\n\n");
hashMap.put(FLAG_INFOS, sb.toString());
sb.delete(0, sb.length());
if (apk.getCertificateInfos().keySet().size() == 0) {
hashMap.put(FLAG_CERTIFICATE, "This file has not certificate file.");
} else {
for (String key : apk.getCertificateInfos().keySet()) {
sb.append("MD5 : ").append(key).append("\n");
sb.append("Sub : ").append(apk.getCertificateInfos().get(key)).append("\n\n");
}
hashMap.put(FLAG_CERTIFICATE, sb.toString());
}
sb.delete(0, sb.length());
ArrayList<String> keyList = new ArrayList<>(apk.getActivities().keySet());
Collections.sort(keyList);
for (String key : keyList) {
sb.append(key).append("\n");
for (String action : apk.getActivities().get(key)) {
sb.append(" ").append(action).append("\n");
}
}
sb.append("\n\n");
hashMap.put(FLAG_ACTIVITIES, sb.toString());
keyList.clear();
keyList = new ArrayList<>(apk.getReceivers().keySet());
Collections.sort(keyList);
sb.delete(0, sb.length());
for (String key : keyList) {
sb.append(key).append("\n");
for (String action : apk.getReceivers().get(key)) {
sb.append(" ").append(action).append("\n");
}
}
sb.append("\n\n");
hashMap.put(FLAG_RECEIVERS, sb.toString());
sb.delete(0, sb.length());
for (String key : apk.getServices()) {
sb.append(key).append("\n");
}
sb.append("\n");
hashMap.put(FLAG_SERVICES, sb.toString());
sb.delete(0, sb.length());
for (String perm : apk.getPermissions()) {
sb.append(perm);
if (permissionsMap.keySet().contains(perm)) {
sb.append(" [ ").append(permissionsMap.get(perm)).append(" ] ");
}
sb.append("\n");
}
sb.append("\n");
hashMap.put(FLAG_PERMISSIONS, sb.toString());
return hashMap;
}
@Override
public HashMap<Byte, String> doInBackground() throws Exception {
final File file = new File(filePath);
if (file.isFile()) {
analysis(file);
return null;
} else if (file.isDirectory()) {
final Collection<File> files = FileUtils.listFiles(file, null, true);
publish("总" + files.size());
for (final File f : files) {
analysis(f);
publish("———————————————————————————————————————————————————————————————————————————————————————————————————————————");
}
}
return null;
}
private void analysisAXML() {
}
/**
* 对非 APK 文件的检测逻辑。
*
* @param f 文件
* @throws IOException
*/
private String analysisOtherFile(File f) throws IOException {
String str;
String fileHash = HashTool.getSHA256(f);
// 如果是 ELF 文件,则优先查询 ELF 表
if (FileTypesDetector.getType(new FileInputStream(f)).contains("ELF")) {
str = querySampleByElfSHA256(fileHash);
if (str != null) {
return str;
}
Elf elf = new Elf(f);
List<String> list = elf.loadStrings();
for (String item : list) {
str = querySampleByElfFeatureCode(item);
if (str != null) {
return str;
}
}
return "Not Found.";
}
// ELF表找不到,或其他文件,则找子文件字段
str = querySampleBySubFileSHA256(fileHash);
if (str != null) {
return str;
} else {
return "Not Found.";
}
}
/**
* 对于子包,也需要做同样的动作。
*
* @param apk
*/
private void analysisSubAPK(APK apk) {
publish("分析子包:" + apk.getFileName());
}
private void analysis(File f) throws IOException {
publish("分析:" + f.getAbsolutePath());
/*****************************************************
*
* 非APK文件分析逻辑
*
*****************************************************/
if (!FileTypesDetector.isAPK(f)) {
publish(analysisOtherFile(f));
publish("———————————————————————————————————————————————————————————————————————————————————————————————————————————");
return;
}
/*****************************************************
*
* APK文件样本检测逻辑
*
*****************************************************/
String tmpStr = querySampleByFileSHA256(HashTool.getSHA256(f));
if (tmpStr != null) {
publish("结果:" + tmpStr);
publish("———————————————————————————————————————————————————————————————————————————————————————————————————————————");
return;
}
/**************************************************************
*
* 基于已知样本的近似分析
* (dex-sha256、证书+清单、特征码、敏感子文件、elf文件)
*
*×************************************************************/
boolean flag;
APK apk = new APK(f);
tmpStr = querySampleByDexSHA256(apk.getDexSHA256());
if (tmpStr != null) {
publish("结果:" + tmpStr);
publish("———————————————————————————————————————————————————————————————————————————————————————————————————————————");
return;
}
// 基于证书的样本近似分析
// FIXME 找出证书一样的样本,然后,找出清单近似的样本。(可能需要持续完善)
SampleInfo displayInfo = null;
StringBuilder displayString = null;
StringBuilder displayLike = null;
for (String key : apk.getCertificateInfos().keySet()) {
ArrayList<SampleInfo> sampleInfos = querySampleByCertMD5(key);
if (sampleInfos != null) {
int maxValue = 0;
for (SampleInfo sampleInfo : sampleInfos) {
// type
StringBuilder stringBuilder = new StringBuilder("cert|");
// detail
StringBuilder likeBuilder = new StringBuilder();
// 证书+包名
if (apk.getPackageName().equals(sampleInfo.pkgName)) {
publish("结果:" + "CP-" + sampleInfo.varName + "|" + sampleInfo.fileName);
return;
}
// 证书+应用名
if (apk.getLabel().equals(sampleInfo.label)) {
publish("结果:" + "CL-" + sampleInfo.varName + "|" + sampleInfo.fileName);
return;
}
// TODO 证书+权限+接收器+服务+Intent ———— 这个还不足以判断近似,现阶段 ————但是因为证书的存在,噪音会小很多吧,得测试。
// FIXME 权限——敏感命中情况(也许需要加强) ————这个会干扰?
// FIXME Perm:Rec:Serv:Intent 0.2:0.3:0.3:0.2
double value = 0.5;
final double PERM_WEIGHT = 0.3;
final double RECV_WEIGHT = 0.2;
final double SERV_WEIGHT = 0.2;
final double INTE_WEIGHT = 0.2;
int count = 0;
likeBuilder.append("Perms:");
for (String perm : apk.getPermissions()) {
if (sampleInfo.permissions.contains(perm)) {
likeBuilder.append(perm).append("|");
count++;
}
}
int sum = apk.getPermissions().size();
likeBuilder.append("\n");
stringBuilder.append(count).append("/").
append(sum).append("Perms|");
if (sum != 0) {
value += (float) count / (float) sum * PERM_WEIGHT;
}
// 服务
count = 0;
likeBuilder.append("Services:");
for (String service : apk.getServices()) {
int lastIndex = service.lastIndexOf(".");
String str = service;
if (lastIndex != -1) {
int len = service.length();
str = service.substring(lastIndex, len);
}
if (sampleInfo.services.contains(str)) {
likeBuilder.append(str).append("|");
count++;
}
}
likeBuilder.append("\n");
sum = apk.getServices().size();
stringBuilder.append(count).append("/").
append(sum).append("services|");
if (sum != 0) {
value += (float) count / (float) sum * SERV_WEIGHT;
}
// 接收器/intents
int recCount = 0;
int recs = 0;
int intents = 0;
count = 0;
for (String rec : apk.getReceivers().keySet()) {
recs++;
if (sampleInfo.receivers.contains(rec)) {
likeBuilder.append("Receivers:").append(rec).append("|").append("\n");
recCount++;
}
for (String intent : apk.getReceivers().get(rec)) {
intents++;
if (sampleInfo.receivers.contains(intent)) {
likeBuilder.append("Intent:").append(intent).append("|");
count++;
}
}
likeBuilder.append("\n");
}
stringBuilder.append(recCount).append("/").
append(recs).append("receivers|");
stringBuilder.append(count).append("/").
append(intents).append("intents|");
if (recs != 0) {
value += (float) recCount / (float) recs * RECV_WEIGHT;
} else if (sampleInfo.receivers.length() == 0) {
value += RECV_WEIGHT;
}
if (intents != 0) {
value += (float) count / (float) intents * INTE_WEIGHT;
}
// publish("最终值==" + String.valueOf(value));
// publish("最终值==" + String.valueOf((int)(value * 100)));
// publish(stringBuilder.toString());
// publish("结果:" + "CPRSI-" + sampleInfo.varName + "|" + sampleInfo.fileName);
// publish(stringBuilder.toString());
// publish(sampleInfo.varName + "|" + sampleInfo.fileName);
// publish(sampleInfo.toString() + "\n");
// publish(likeBuilder.toString() + "\n");
if (value * 100 > maxValue ) {
displayInfo = sampleInfo;
displayString = stringBuilder;
displayLike = likeBuilder;
}
// if ((int) (value * 100) >= 70) {
// publish("结果:" + value * 100 + " CPRSI- " + sampleInfo.varName + "|" + sampleInfo.fileName);
// publish(stringBuilder.toString());
// publish(sampleInfo.varName + "|" + sampleInfo.fileName);
// publish(sampleInfo.toString() + "\n");
// publish(likeBuilder.toString() + "\n");
// return;
// }
} // End of for.
// TODO Find the best result......the most likely
if (displayInfo != null) {
publish("结果:" + maxValue * 100 + " CPRSI- " + displayInfo.varName + "|" + displayInfo.fileName);
publish(displayString.toString());
publish(displayInfo.toString() + "\n");
publish(displayLike.toString() + "\n");
}
}
}
for (String str : apk.getStrings()) {
String result = querySampleByFeatureCode(str);
if (result != null) {
publish(result + "\n");
publish("———————————————————————————————————————————————————————————————————————————————————————————————————————————");
return;
}
}
/** 敏感子文件(非elf/APK) Hash 查询 */
flag = false;
HashMap<String, String> subFileHash256Map = apk.getSubFileHash256Map();
for (String key : subFileHash256Map.keySet()) {
String r = querySampleBySubFileSHA256(subFileHash256Map.get(key));
if (r != null) {
publish("子文件命中:" + key);
publish(r);
flag = true;
break;
}
}
if (flag) {
publish("\n********************************************************************\n");
return;
}
/**
* elf 文件近似分析,若存在恶意 elf 类型文件
*/
HashMap<String, APK.ElfData> elfHashMap = apk.getElfDataHashMap();
for (String key : elfHashMap.keySet()) {
String str = querySampleByElfSHA256(elfHashMap.get(key).getHash());
if (str != null) {
publish("ELF 哈希命中:" + key);
publish(str + "\n");
continue;
}
for (String fc : elfHashMap.get(key).getStringList()) {
str = querySampleByElfFeatureCode(fc);
if (str != null) {
publish("ELF 特征命中:" + key);
publish(str + "\n");
break;
}
}
}
// HashMap<String, APK> apkHashMap = apk.getSubApkDataMap();
// for (String name : apkHashMap.keySet()) {
// analysis(apkHashMap.get(name));
// }
/**
* 未知恶意软件分析-HRUE
*/
// 敏感权限
ArrayList<String> apkPermissions = apk.getPermissions();
HashSet<String> perms = new HashSet<>();
for (String str : apkPermissions) {
if (str.contains("SMS")) {
perms.add(str);
continue;
}
if (str.contains("INTERNET")) {
perms.add(str);
continue;
}
if (str.contains("BOOT_COMPLETED")) {
perms.add(str);
continue;
}
if (str.contains("PHONE")) {
perms.add(str);
}
if (str.contains("ADMIN")) {
perms.add(str);
}
if (str.contains("CONTACTS")) {
perms.add(str);
}
}
publish("敏感权限:" + perms.toString());
publish("敏感API调用分析");
HashMap<String, String> methods = apk.getMethods();
HashSet<String> methodSet = new HashSet<>();
HashSet<String> callOnSet = new HashSet<>();
int value = 0;
System.out.println(methods.toString());
String systemApp = "/system";
searchCallOn(systemApp, methods, methodSet, callOnSet, 0);
if (!callOnSet.isEmpty()) {
publish(systemApp + callOnSet.toString());
value += callOnSet.toString().split(";.on").length - 1;
}
callOnSet.clear();
methodSet.clear();
searchCallOn("content://sms", methods, methodSet, callOnSet, 0);
if (!callOnSet.isEmpty()) {
publish("content://sms" + callOnSet.toString());
value += callOnSet.toString().split(";.on").length - 1;
}
callOnSet.clear();
methodSet.clear();
searchCallOn("Contacts;.CONTENT_URI", methods, methodSet, callOnSet, 0);
if (!callOnSet.isEmpty()) {
publish("Contacts;.CONTENT_URI" + callOnSet.toString());
value += callOnSet.toString().split(";.on").length - 1;
}
callOnSet.clear();
methodSet.clear();
searchCallOn("SmsManager;.sendTextMessage", methods, methodSet, callOnSet, 0);
if (!callOnSet.isEmpty()) {
publish("SmsManager;.sendTextMessage" + callOnSet.toString());
value += callOnSet.toString().split(";.on").length - 1;
}
callOnSet.clear();
methodSet.clear();
searchCallOn("Transport;.send", methods, methodSet, callOnSet, 0);
if (!callOnSet.isEmpty()) {
publish("mail/Transport;.send" + callOnSet.toString());
value += callOnSet.toString().split(";.on").length - 1;
}
callOnSet.clear();
methodSet.clear();
searchCallOn(";.abortBroadcast()V", methods, methodSet, callOnSet, 0);
if (!callOnSet.isEmpty()) {
publish(";.abortBroadcast()V" + callOnSet.toString());
value += callOnSet.toString().split(";.on").length - 1;
}
methodSet.clear();
callOnSet.clear();
searchCallOn("TelephonyManager;.getDeviceId", methods, methodSet, callOnSet, 0);
if (!callOnSet.isEmpty()) {
publish("TelephonyManager;.getDeviceId" + callOnSet.toString());
value += callOnSet.toString().split(";.on").length - 1;
}
callOnSet.clear();
methodSet.clear();
searchCallOn("URL;.openConnection", methods, methodSet, callOnSet, 0);
if (!callOnSet.isEmpty()) {
publish("URL;.openConnection" + callOnSet.toString());
value += callOnSet.toString().split(";.on").length - 1;
}
callOnSet.clear();
methodSet.clear();
searchCallOn("HttpClient;.execute", methods, methodSet, callOnSet, 0);
if (!callOnSet.isEmpty()) {
publish("HttpClient;.execute" + callOnSet.toString());
value += callOnSet.toString().split(";.on").length - 1;
}
callOnSet.clear();
methodSet.clear();
searchCallOn("Ljava/util/Timer;.schedule", methods, methodSet, callOnSet, 0);
if (!callOnSet.isEmpty()) {
publish("Ljava/util/Timer;.schedule" + callOnSet.toString());
value += callOnSet.toString().split(";.on").length - 1;
}
publish("可疑度:" + value);
}
/**
*
* @param method 方法
* @param methods apk 的方法集
* @param methodSet 已搜索過的調用方法集合
* @param callOnSet 最終調用集合
* @param i 搜索層/次數計數器
*/
private void searchCallOn(String method, HashMap<String, String> methods,
HashSet<String> methodSet, HashSet<String> callOnSet, int i) {
if (methodSet.contains(method)) {
return; // 已经搜索过的调用
}
methodSet.add(method);
String space = "";
for (int x = 0; x < i; x++) {
space += "-";
}
System.out.println(space + method);
i++;
/**
* 是否找到调用标志,找到则是调用,找不到则是最终调用。
*/
boolean flag = true;
for (String key : methods.keySet()) {
String methodBody = methods.get(key);
if (methodBody.contains(method)) {
flag = false;
if (key.contains(";.handleMessage")) {
key = "Handler;.send";
searchCallOn(key, methods, methodSet, callOnSet, i);
continue;
}
if (key.contains("$") && key.contains(";.run()V")) {
key = key.split(";.")[0] + ";.<init>";
searchCallOn(key, methods, methodSet, callOnSet, i);
continue;
}
if (key.contains("$") && key.contains(";.run()V")) {
key = key.split(";.")[0] + ";.start";
searchCallOn(key, methods, methodSet, callOnSet, i);
continue;
}
searchCallOn(key, methods, methodSet, callOnSet, i);
}
}
if (flag && i > 1) {
callOnSet.add(method);
}
}
private String sqliteEscape(String str) {
str = str.replace("/", "//");
str = str.replace("'", "''");
str = str.replace("\"", "/\"");
str = str.replace("[", "/[");
str = str.replace("]", "/]");
str = str.replace("%", "/%");
str = str.replace("&", "/&");
str = str.replace("_", "/_");
str = str.replace(")", "/)");
str = str.replace("(", "/(");
return str.trim();
}
private ArrayList<String> str2ArrayList(String str) {
String tmp = str.replace("[", "").replace("]", "");
String[] strings = tmp.split(", ");
return new ArrayList<>(Arrays.asList(strings));
}
@Override
protected void process(List<String> chunks) {
for (String str : chunks) {
if (str.contains("[LOG]")) {
jTextAreaCertificate.append(str + "\n");
continue;
}
jTextAreaInfos.append(str + "\n");
}
}
@Override
protected void done() {
publish("处理完毕");
jButtonAnalysis.setEnabled(true);
}
/********************************************************************
* 数据库操作等函数
*********************************************************************/
/**
* prepare database.
*
* @return Connection
*/
private Connection prepareDb() {
Connection conn = null;
try {
// load the sqlite-JDBC driver using the current class loader
Class.forName("org.sqlite.JDBC");
conn = DriverManager.getConnection("jdbc:sqlite:samples.db");
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
return conn;
}
/**
* 查询特征码库
*
* @param featureCode 特征码
* @return 查询结果
*/
private String querySampleByFeatureCode(String featureCode) {
featureCode = sqliteEscape(featureCode);
try {
Statement statement = conn.createStatement();
ResultSet resultSet = statement.executeQuery(
"select * from sample_info where feature_code like '" + featureCode + "' escape '/'");
if (resultSet.next()) {
return resultSet.getString("file_name") + "|" + resultSet.getString("var_name")
+ "|" + resultSet.getString("feature_code");
}
} catch (SQLException e) {
System.out.println("querySampleByFeatureCode 异常, 存在特殊字符:" + featureCode);
e.printStackTrace();
}
return null;
}
private String querySampleBySubFileSHA256(String sub_file_hash256) {
try {
Statement statement = conn.createStatement();
ResultSet resultSet = statement.executeQuery(
"select * from sample_info where sub_file_sha256 like \"%" + sub_file_hash256 + "%\"");
if (resultSet.next()) {
return resultSet.getString("var_name") + "|"
+ resultSet.getString("file_name");
}
} catch (SQLException e) {
System.out.println("语法错误:" + sub_file_hash256);
e.printStackTrace();
}
return null;
}
/**
* 查询样本 SHA256
*
* @param fileSHA256 文件sha256
* @return 查询结果
*/
private String querySampleByFileSHA256(String fileSHA256) {
try {
Statement statement = conn.createStatement();
ResultSet resultSet = statement.executeQuery("select * from sample_info where file_sha256 like \"%" + fileSHA256 + "%\"");
if (resultSet.next()) {
return resultSet.getString("var_name");
}
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
/**
* DEX sha256 查询
*
* @param dexSHA256 dex sha256
* @return 查询结果
*/
private String querySampleByDexSHA256(String dexSHA256) {
try {
Statement statement = conn.createStatement();
ResultSet resultSet = statement.executeQuery("select * from sample_info where dex_sha256 like \"%" + dexSHA256 + "%\"");
if (resultSet.next()) {
return resultSet.getString("file_name") + "|" + resultSet.getString("var_name");
}
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
/**
* 查询 elf_info 表的样本
*
* @param elfHash256 elf 文件的md5
* @return 结果
*/
private String querySampleByElfSHA256(String elfHash256) {
try {
Statement statement = conn.createStatement();
ResultSet resultSet = statement.executeQuery("select * from elf_info where file_sha256=\"" + elfHash256 + "\"");
if (resultSet.next()) {
return resultSet.getString("var_name") + "|"
+ resultSet.getString("file_name");
}
} catch (SQLException e) {
System.out.println("语法错误:" + elfHash256);
e.printStackTrace();
}
return null;
}
private String querySampleByElfFeatureCode2(String featureCode) {
try {
Statement statement = conn.createStatement();
ResultSet resultSet = statement.executeQuery("select * from elf_info where feature_code=\"" + featureCode + "\"");
while (resultSet.next()) {
System.out.println(resultSet.getString("var_name") + "|"
+ resultSet.getString("file_name") + "|"
+ resultSet.getString("feature_code"));
}
} catch (SQLException e) {
System.out.println("语法错误:" + featureCode);
e.printStackTrace();
}
return null;
}
private String querySampleByElfFeatureCode(String featureCode) {
featureCode = sqliteEscape(featureCode);
try {
Statement statement = conn.createStatement();
ResultSet resultSet = statement.executeQuery("select * from elf_info where feature_code like '" + featureCode + "' escape '/'");
if (resultSet.next()) {
return resultSet.getString("var_name") + "|"
+ resultSet.getString("file_name") + "|"
+ resultSet.getString("feature_code");
}
} catch (SQLException e) {
System.out.println("querySampleByElfFeatureCode, 特殊字符串:" + featureCode);
e.printStackTrace();
}
return null;
}
private ArrayList<SampleInfo> querySampleByCertMD5(String certMD5) {
ArrayList<SampleInfo> sampleInfos = new ArrayList<>();
try {
Statement statement = conn.createStatement();
ResultSet resultSet = statement.executeQuery("select * from sample_info where cert like \"%" + certMD5 + "%\"");
while (resultSet.next()) {
SampleInfo sampleInfo = new SampleInfo();
sampleInfo.fileSHA256 = resultSet.getString("file_sha256");
sampleInfo.fileName = resultSet.getString("file_name");
sampleInfo.pkgName = resultSet.getString("pkg_name");
sampleInfo.label = resultSet.getString("label");
sampleInfo.cert = resultSet.getString("cert");
sampleInfo.permissions = resultSet.getString("permissions");
sampleInfo.receivers = resultSet.getString("receivers");
sampleInfo.services = resultSet.getString("services");
sampleInfo.varName = resultSet.getString("var_name");
sampleInfos.add(sampleInfo);
}
} catch (SQLException e) {
e.printStackTrace();
}
if (sampleInfos.size() == 0) {
return null;
}
return sampleInfos;
}
}