Autopsy 4.22.1
Graphical digital forensics platform for The Sleuth Kit and other tools.
ExtractThumbcache.java
Go to the documentation of this file.
1/*
2 *
3 * Autopsy Forensic Browser
4 *
5 * Copyright 2020-2025 Sleuth Kit Labs.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19package org.sleuthkit.autopsy.recentactivity;
20
21import java.io.File;
22import java.io.FileNotFoundException;
23import java.io.IOException;
24import java.nio.file.Files;
25import java.nio.file.Path;
26import java.nio.file.Paths;
27import java.nio.file.attribute.BasicFileAttributes;
28import java.util.ArrayList;
29import java.util.Arrays;
30import java.util.List;
31import java.util.concurrent.TimeUnit;
32import java.util.logging.Level;
33import org.apache.commons.io.FileUtils;
34import org.openide.modules.InstalledFileLocator;
35import org.openide.util.NbBundle.Messages;
36import org.sleuthkit.autopsy.casemodule.Case;
37import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
38import org.sleuthkit.autopsy.casemodule.services.FileManager;
39import org.sleuthkit.autopsy.coreutils.ExecUtil;
40import org.sleuthkit.autopsy.coreutils.Logger;
41import org.sleuthkit.autopsy.coreutils.PlatformUtil;
42import org.sleuthkit.autopsy.datamodel.ContentUtils;
43import org.sleuthkit.autopsy.ingest.DataSourceIngestModuleProcessTerminator;
44import org.sleuthkit.autopsy.ingest.DataSourceIngestModuleProgress;
45import org.sleuthkit.autopsy.ingest.IngestJobContext;
46import org.sleuthkit.autopsy.ingest.IngestServices;
47import org.sleuthkit.autopsy.ingest.ModuleContentEvent;
48import org.sleuthkit.datamodel.AbstractFile;
49import org.sleuthkit.datamodel.Content;
50import org.sleuthkit.datamodel.DerivedFile;
51import org.sleuthkit.datamodel.TskCoreException;
52import org.sleuthkit.datamodel.TskData;
53
58final class ExtractThumbcache extends Extract {
59
60 private static final Logger logger = Logger.getLogger(ExtractThumbcache.class.getName());
61
62 private static final String THUMBCACHE_TOOL_FOLDER = "thumbcache_parser"; //NON-NLS
63 private static final String THUMBCACHE_TOOL_NAME_WINDOWS = "thumbcache_viewer_cmd.exe"; //NON-NLS
64 private static final String THUMBCACHE_OUTPUT_FILE_NAME = "Output.txt"; //NON-NLS
65 private static final String THUMBCACHE_ERROR_FILE_NAME = "Error.txt"; //NON-NLS
66
67 private final IngestJobContext context;
68
69 @Messages({"ExtractThumbcache_module_name=Thumbcache Analyzer"})
70
71 ExtractThumbcache(IngestJobContext context) {
72 super(Bundle.ExtractThumbcache_module_name(), context);
73 this.context = context;
74 }
75
76 @Messages({
77 "Thumbcache_Files_Not_Found=Thumbcache files not found",
78 "ExtractThumbcache_error_finding_program=Could not find thumbcache_viewer_cmd.exe program",
79 "Thumbcache_process_error_executing_export_thumbcache_program=Error running thumbcache program",
80 "Thumbcache_Files_TSK_Error=TSK error searching for thumbcache files"
81 })
82
83 @Override
84 void process(Content dataSource, DataSourceIngestModuleProgress progressBar) {
85
86 if (!PlatformUtil.isWindowsOS()) {
87 logger.log(Level.WARNING,"Thumbcache only Supported on Windows Platform."); //NON-NLS
88 return; // No need to continue
89 }
90
91 String modOutPath = RAImageIngestModule.getRAOutputPath(Case.getCurrentCase(), "thumbcache", context.getJobId());
92 File dir = new File(modOutPath);
93 if (dir.exists() == false) {
94 dir.mkdirs();
95 }
96
97 String tempDirPath = RAImageIngestModule.getRATempPath(Case.getCurrentCase(), "thumbcache", context.getJobId()); //NON-NLS
98 List<AbstractFile> thumbcacheFiles = getThumbcacheFiles(dataSource, tempDirPath);
99 if (thumbcacheFiles == null) {
100 this.addErrorMessage(Bundle.Thumbcache_Files_TSK_Error());
101 return; //If we cannot find the thumbcache files we cannot proceed
102 }
103
104 if (thumbcacheFiles.isEmpty()) {
105 logger.log(Level.WARNING, "Error finding thumbcache files"); //NON-NLS
106 return; //If we cannot find the thumbcache files we cannot proceed
107 }
108
109 final String thumbcacheDumper = getPathForThumbcacheDumper();
110 if (thumbcacheDumper == null) {
111 this.addErrorMessage(Bundle.ExtractThumbcache_error_finding_program());
112 logger.log(Level.WARNING, "Error finding thumbcache parsing program"); //NON-NLS
113 return; //If we cannot find the thumbcache parser program we cannot proceed
114 }
115
116 if (context.dataSourceIngestIsCancelled()) {
117 return;
118 }
119
120 String thumbcacheFileLocation = null;
121 for (AbstractFile thumbcacheFile: thumbcacheFiles) {
122 if (context.dataSourceIngestIsCancelled()) {
123 return;
124 }
125 try {
126 File thumbcacheFileName = new File(tempDirPath + File.separator + thumbcacheFile.getId() + "_" + thumbcacheFile.getName());
127 if (thumbcacheFileName.exists()) {
128 String modOutFile = modOutPath + File.separator + thumbcacheFile.getId() + "_" +thumbcacheFile.getName();
129 thumbcacheFileLocation = tempDirPath + File.separator + thumbcacheFile.getId() + "_" + thumbcacheFile.getName();
130
131 dir = new File(modOutFile);
132 if (dir.exists() == false) {
133 dir.mkdirs();
134 }
135
136 extractThumbcacheFiles(thumbcacheDumper, modOutFile, thumbcacheFileLocation);
137 addThumbcacheDerivedFiles(modOutFile, thumbcacheFile);
138 }
139 } catch (IOException ex) {
140 logger.log(Level.SEVERE, String.format("Error processing thumbcache file %s", thumbcacheFile.getId() + "_" + thumbcacheFile.getName()), ex); //NON-NLS=
141 }
142 }
143 }
144
153 List<AbstractFile> getThumbcacheFiles(Content dataSource, String tempDirPath) {
154 FileManager fileManager = Case.getCurrentCase().getServices().getFileManager();
155
156 List<AbstractFile> thumbcacheFiles;
157
158 try {
159 thumbcacheFiles = fileManager.findFiles(dataSource, "thumbcache_%.db", ""); //NON-NLS
160 } catch (TskCoreException ex) {
161 logger.log(Level.SEVERE,"TskCoreException Looking for thumbcache file.", ex); //NON-NLS
162 return null; // No need to continue
163 }
164
165 if (thumbcacheFiles.isEmpty()) {
166 return new ArrayList<>(); // No thumbcache files found
167 }
168
169 for (AbstractFile thumbcacheFile : thumbcacheFiles) {
170 String thumbcacheFileName = tempDirPath + File.separator + thumbcacheFile.getId() + "_" + thumbcacheFile.getName();
171
172 try {
173 ContentUtils.writeToFile(thumbcacheFile, new File(thumbcacheFileName));
174 } catch (IOException ex) {
175 logger.log(Level.WARNING, String.format("Unable to write %s to temp directory. File name: %s", thumbcacheFile.getName(), thumbcacheFile), ex); //NON-NLS
176 }
177 }
178
179 return thumbcacheFiles;
180 }
181
192 void extractThumbcacheFiles(String thumbcacheExePath, String thumbcacheFilePath, String thumbcacheFile) throws IOException {
193 final Path outputFilePath = Paths.get(thumbcacheFilePath, THUMBCACHE_OUTPUT_FILE_NAME);
194 final Path errFilePath = Paths.get(thumbcacheFilePath, THUMBCACHE_ERROR_FILE_NAME);
195
196
197 List<String> commandLine = new ArrayList<>();
198 commandLine.add(thumbcacheExePath);
199 commandLine.add("-O"); //NON-NLS
200 commandLine.add(thumbcacheFilePath);
201 commandLine.add(thumbcacheFile);
202
203
204 ProcessBuilder processBuilder = new ProcessBuilder(commandLine);
205 processBuilder.redirectOutput(outputFilePath.toFile());
206 processBuilder.redirectError(errFilePath.toFile());
207
208 ExecUtil.execute(processBuilder, new DataSourceIngestModuleProcessTerminator(context, true));
209 }
210
211 private String getPathForThumbcacheDumper() {
212 Path path = Paths.get(THUMBCACHE_TOOL_FOLDER, THUMBCACHE_TOOL_NAME_WINDOWS);
213 File thumbcacheToolFile = InstalledFileLocator.getDefault().locate(path.toString(),
214 ExtractThumbcache.class.getPackage().getName(), false);
215 if (thumbcacheToolFile != null) {
216 return thumbcacheToolFile.getAbsolutePath();
217 }
218
219 return null;
220 }
221
222 private void addThumbcacheDerivedFiles(String outputFolder, AbstractFile thumbcacheFile) {
223 Path outputFolderPath = Paths.get(outputFolder);
224 java.util.Collection<File> files = (List<File>) FileUtils.listFiles(outputFolderPath.toFile(), null, true);
225 for (File file : files) {
226 if (context.dataSourceIngestIsCancelled()) {
227 return;
228 }
229
230 Path candidate = file.toPath();
231
232 if (candidate.getFileName().toString().equals(THUMBCACHE_ERROR_FILE_NAME) || candidate.getFileName().toString().equals(THUMBCACHE_OUTPUT_FILE_NAME)) {
233 continue;
234 }
235 try {
236 final Case currentCase = Case.getCurrentCaseThrows();
237 final Path caseDirectory = Paths.get(currentCase.getCaseDirectory());
238 final BasicFileAttributes attrs = Files.readAttributes(candidate, BasicFileAttributes.class);
239 final Path localCasePath = caseDirectory.relativize(candidate);
240
241 final DerivedFile tcacheFile = currentCase.getSleuthkitCase()
242 .addDerivedFile(candidate.getFileName().toString(),
243 localCasePath.toString(), attrs.size(), 0L,
244 attrs.creationTime().to(TimeUnit.SECONDS),
245 attrs.lastAccessTime().to(TimeUnit.SECONDS),
246 attrs.lastModifiedTime().to(TimeUnit.SECONDS),
247 attrs.isRegularFile(), thumbcacheFile, "",
248 "", "", "", TskData.EncodingType.NONE);
249
250 context.addFilesToJob(Arrays.asList(tcacheFile));
251 IngestServices.getInstance().fireModuleContentEvent(new ModuleContentEvent(tcacheFile));
252 dataFound = true;
253 } catch (IOException ex) {
254 logger.log(Level.WARNING, "I/O error encountered during thumbcache processing.", ex);
255 } catch (TskCoreException ex) {
256 logger.log(Level.SEVERE, "Unable to add thumbcache as derived files.", ex);
257 } catch (NoCurrentCaseException ex) {
258 logger.log(Level.WARNING, "No open case!", ex);
259 }
260 }
261 }
262}

Copyright © 2012-2024 Sleuth Kit Labs. Generated on:
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.