19 package org.sleuthkit.autopsy.modules.android;
22 import java.sql.Connection;
23 import java.sql.DriverManager;
24 import java.sql.ResultSet;
25 import java.sql.SQLException;
26 import java.sql.Statement;
27 import java.util.List;
28 import java.util.logging.Level;
29 import org.apache.commons.codec.binary.Base64;
30 import org.openide.util.NbBundle;
45 class TangoMessageAnalyzer {
47 private static final String moduleName = AndroidModuleFactory.getModuleName();
48 private static final Logger logger = Logger.getLogger(TangoMessageAnalyzer.class.getName());
50 public static void findTangoMessages(Content dataSource, FileManager fileManager) {
51 List<AbstractFile> absFiles;
53 absFiles = fileManager.findFiles(dataSource,
"tc.db");
54 for (AbstractFile abstractFile : absFiles) {
56 File jFile =
new File(Case.getCurrentCase().getTempDirectory(), abstractFile.getName());
57 ContentUtils.writeToFile(abstractFile, jFile);
58 findTangoMessagesInDB(jFile.toString(), abstractFile);
59 }
catch (Exception e) {
60 logger.log(Level.SEVERE,
"Error parsing Tango messages", e);
63 }
catch (TskCoreException e) {
64 logger.log(Level.SEVERE,
"Error finding Tango messages", e);
68 private static void findTangoMessagesInDB(String DatabasePath, AbstractFile f) {
69 Connection connection = null;
70 ResultSet resultSet = null;
71 Statement statement = null;
73 if (DatabasePath == null || DatabasePath.isEmpty()) {
77 Class.forName(
"org.sqlite.JDBC");
78 connection = DriverManager.getConnection(
"jdbc:sqlite:" + DatabasePath);
79 statement = connection.createStatement();
80 }
catch (ClassNotFoundException | SQLException e) {
81 logger.log(Level.SEVERE,
"Error opening database", e);
86 resultSet = statement.executeQuery(
87 "Select conv_id, create_time,direction,payload FROM messages ORDER BY create_time DESC;");
93 while (resultSet.next()) {
94 conv_id = resultSet.getString(
"conv_id");
95 Long create_time = Long.valueOf(resultSet.getString(
"create_time")) / 1000;
96 if (resultSet.getString(
"direction").equals(
"1")) {
97 direction =
"Incoming";
99 direction =
"Outgoing";
101 payload = resultSet.getString(
"payload");
103 BlackboardArtifact bba = f.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE);
104 bba.addAttribute(
new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID(), moduleName, create_time));
105 bba.addAttribute(
new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DIRECTION.getTypeID(), moduleName, direction));
106 bba.addAttribute(
new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT.getTypeID(), moduleName, decodeMessage(conv_id, payload)));
107 bba.addAttribute(
new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_MESSAGE_TYPE.getTypeID(), moduleName,
108 NbBundle.getMessage(TangoMessageAnalyzer.class,
109 "TangoMessageAnalyzer.bbAttribute.tangoMessage")));
112 }
catch (Exception e) {
113 logger.log(Level.SEVERE,
"Error parsing Tango messages to the Blackboard", e);
116 if (resultSet != null) {
121 }
catch (Exception e) {
122 logger.log(Level.SEVERE,
"Error closing database", e);
128 private static String decodeMessage(String wrapper, String message) {
130 byte[] decoded = Base64.decodeBase64(message);
132 String Z =
new String(decoded,
"UTF-8");
133 result = Z.split(wrapper)[1];
134 }
catch (Exception e) {
135 logger.log(Level.SEVERE,
"Error decoding a Tango message", e);