19 package org.sleuthkit.autopsy.modules.android;
22 import java.io.FileInputStream;
23 import java.io.InputStream;
24 import java.math.BigInteger;
25 import java.nio.ByteBuffer;
26 import java.util.List;
27 import java.util.logging.Level;
28 import org.openide.util.NbBundle;
29 import org.openide.util.NbBundle.Messages;
47 class CacheLocationAnalyzer {
49 private static final String moduleName = AndroidModuleFactory.getModuleName();
50 private static final Logger logger = Logger.getLogger(CacheLocationAnalyzer.class.getName());
51 private static Blackboard blackboard;
57 public static void findGeoLocations(Content dataSource, FileManager fileManager,
58 IngestJobContext context) {
59 blackboard = Case.getCurrentCase().getServices().getBlackboard();
61 List<AbstractFile> abstractFiles = fileManager.findFiles(dataSource,
"cache.cell");
62 abstractFiles.addAll(fileManager.findFiles(dataSource,
"cache.wifi"));
64 for (AbstractFile abstractFile : abstractFiles) {
66 if (abstractFile.getSize() == 0) {
69 File jFile =
new File(Case.getCurrentCase().getTempDirectory(), abstractFile.getName());
70 ContentUtils.writeToFile(abstractFile, jFile, context::dataSourceIngestIsCancelled);
72 findGeoLocationsInFile(jFile, abstractFile);
73 }
catch (Exception e) {
74 logger.log(Level.SEVERE,
"Error parsing cached Location files", e);
77 }
catch (TskCoreException e) {
78 logger.log(Level.SEVERE,
"Error finding cached Location files", e);
82 @Messages({
"CacheLocationAnalyzer.indexError.message=Failed to index GPS trackpoint artifact for keyword search."})
83 private static void findGeoLocationsInFile(File file, AbstractFile f) {
87 InputStream inputStream =
new FileInputStream(file);
90 inputStream.read(bytes);
93 inputStream.read(bytes);
95 int iterations =
new BigInteger(bytes).intValue();
97 for (
int i = 0; i < iterations; i++) {
99 inputStream.read(bytes);
102 inputStream.read(bytes);
103 while (
new BigInteger(bytes).intValue() != 0) {
104 if (0 > inputStream.read(bytes)) {
109 inputStream.read(bytes);
110 if (
new BigInteger(bytes).intValue() <= 0) {
111 bytes =
new byte[28];
112 inputStream.read(bytes);
115 String accuracy =
"" +
new BigInteger(bytes).intValue();
118 inputStream.read(bytes);
119 String confidence =
"" +
new BigInteger(bytes).intValue();
122 inputStream.read(bytes);
123 double latitude = toDouble(bytes);
126 inputStream.read(bytes);
127 double longitude = toDouble(bytes);
130 inputStream.read(bytes);
131 Long timestamp =
new BigInteger(bytes).longValue() / 1000;
133 BlackboardArtifact bba = f.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_TRACKPOINT);
134 bba.addAttribute(
new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE, moduleName, latitude));
135 bba.addAttribute(
new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE, moduleName, longitude));
136 bba.addAttribute(
new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME, moduleName, timestamp));
137 bba.addAttribute(
new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME, moduleName,
138 NbBundle.getMessage(CacheLocationAnalyzer.class,
139 "CacheLocationAnalyzer.bbAttribute.fileLocationHistory",
147 blackboard.indexArtifact(bba);
148 }
catch (Blackboard.BlackboardException ex) {
149 logger.log(Level.SEVERE,
"Unable to index blackboard artifact " + bba.getArtifactID(), ex);
150 MessageNotifyUtil.Notify.error(
151 Bundle.CacheLocationAnalyzer_indexError_message(), bba.getDisplayName());
155 }
catch (Exception e) {
156 logger.log(Level.SEVERE,
"Error parsing Cached GPS locations to Blackboard", e);
160 private static double toDouble(byte[] bytes) {
161 return ByteBuffer.wrap(bytes).getDouble();