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;
29 import org.openide.util.NbBundle;
46 class CacheLocationAnalyzer {
48 private static final String moduleName = AndroidModuleFactory.getModuleName();
49 private static final Logger logger = Logger.getLogger(CacheLocationAnalyzer.class.getName());
50 private static Blackboard blackboard;
56 public static void findGeoLocations(Content dataSource, FileManager fileManager) {
58 blackboard = Case.getCurrentCase().getServices().getBlackboard();
60 List<AbstractFile> abstractFiles = fileManager.findFiles(dataSource,
"cache.cell");
61 abstractFiles.addAll(fileManager.findFiles(dataSource,
"cache.wifi"));
63 for (AbstractFile abstractFile : abstractFiles) {
65 if (abstractFile.getSize() == 0) {
68 File jFile =
new File(Case.getCurrentCase().getTempDirectory(), abstractFile.getName());
69 ContentUtils.writeToFile(abstractFile, jFile);
71 findGeoLocationsInFile(jFile, abstractFile);
72 }
catch (Exception e) {
73 logger.log(Level.SEVERE,
"Error parsing cached Location files", e);
76 }
catch (TskCoreException e) {
77 logger.log(Level.SEVERE,
"Error finding cached Location files", e);
81 private static void findGeoLocationsInFile(File file, AbstractFile f) {
85 InputStream inputStream =
new FileInputStream(file);
88 inputStream.read(bytes);
91 inputStream.read(bytes);
93 int iterations =
new BigInteger(bytes).intValue();
95 for (
int i = 0; i < iterations; i++) {
97 inputStream.read(bytes);
100 inputStream.read(bytes);
101 while (
new BigInteger(bytes).intValue() != 0) {
102 if (0 > inputStream.read(bytes)) {
107 inputStream.read(bytes);
108 if (
new BigInteger(bytes).intValue() <= 0) {
109 bytes =
new byte[28];
110 inputStream.read(bytes);
113 String accuracy =
"" +
new BigInteger(bytes).intValue();
116 inputStream.read(bytes);
117 String confidence =
"" +
new BigInteger(bytes).intValue();
120 inputStream.read(bytes);
121 double latitude = toDouble(bytes);
124 inputStream.read(bytes);
125 double longitude = toDouble(bytes);
128 inputStream.read(bytes);
129 Long timestamp =
new BigInteger(bytes).longValue() / 1000;
131 BlackboardArtifact bba = f.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_TRACKPOINT);
132 bba.addAttribute(
new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE, moduleName, latitude));
133 bba.addAttribute(
new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE, moduleName, longitude));
134 bba.addAttribute(
new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME, moduleName, timestamp));
135 bba.addAttribute(
new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME, moduleName,
136 NbBundle.getMessage(CacheLocationAnalyzer.class,
137 "CacheLocationAnalyzer.bbAttribute.fileLocationHistory",
146 blackboard.indexArtifact(bba);
147 }
catch (Blackboard.BlackboardException ex) {
148 logger.log(Level.SEVERE, NbBundle.getMessage(Blackboard.class,
"Blackboard.unableToIndexArtifact.error.msg", bba.getDisplayName()), ex);
149 MessageNotifyUtil.Notify.error(
150 NbBundle.getMessage(Blackboard.class,
"Blackboard.unableToIndexArtifact.exception.msg"), bba.getDisplayName());
154 }
catch (Exception e) {
155 logger.log(Level.SEVERE,
"Error parsing Cached GPS locations to Blackboard", e);
159 private static double toDouble(byte[] bytes) {
160 return ByteBuffer.wrap(bytes).getDouble();