Autopsy 4.22.1
Graphical digital forensics platform for The Sleuth Kit and other tools.
ALeappAnalyzerIngestModule.java
Go to the documentation of this file.
1/*
2 * Autopsy Forensic Browser
3 *
4 * Copyright 2020-2021 Basis Technology Corp.
5 * Contact: carrier <at> sleuthkit <dot> org
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.modules.leappanalyzers;
20
21import java.io.BufferedReader;
22import java.io.File;
23import java.io.FileNotFoundException;
24import java.io.FileReader;
25import java.io.IOException;
26import java.io.UncheckedIOException;
27import java.nio.file.Files;
28import java.nio.file.Path;
29import java.nio.file.Paths;
30import java.text.SimpleDateFormat;
31import java.util.Arrays;
32import java.util.List;
33import java.util.ArrayList;
34import java.util.Locale;
35import java.util.logging.Level;
36import java.util.stream.Collectors;
37import java.util.stream.Stream;
38import org.apache.commons.io.FilenameUtils;
39import org.openide.modules.InstalledFileLocator;
40import org.openide.util.NbBundle;
41import org.sleuthkit.autopsy.casemodule.Case;
42import static org.sleuthkit.autopsy.casemodule.Case.getCurrentCase;
43import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
44import org.sleuthkit.autopsy.casemodule.services.FileManager;
45import org.sleuthkit.autopsy.coreutils.ExecUtil;
46import org.sleuthkit.autopsy.coreutils.Logger;
47import org.sleuthkit.autopsy.coreutils.PlatformUtil;
48import org.sleuthkit.autopsy.datamodel.ContentUtils;
49import org.sleuthkit.autopsy.ingest.DataSourceIngestModule;
50import org.sleuthkit.autopsy.ingest.DataSourceIngestModuleProcessTerminator;
51import org.sleuthkit.autopsy.ingest.DataSourceIngestModuleProgress;
52import org.sleuthkit.autopsy.ingest.IngestJobContext;
53import org.sleuthkit.autopsy.ingest.IngestMessage;
54import org.sleuthkit.autopsy.ingest.IngestServices;
55import org.sleuthkit.autopsy.ingest.IngestModule.IngestModuleException;
56import org.sleuthkit.datamodel.AbstractFile;
57import org.sleuthkit.datamodel.Content;
58import org.sleuthkit.datamodel.FileSystem;
59import org.sleuthkit.datamodel.Image;
60import org.sleuthkit.datamodel.LocalFilesDataSource;
61import org.sleuthkit.datamodel.ReadContentInputStream;
62import org.sleuthkit.datamodel.TskCoreException;
63import org.sleuthkit.datamodel.TskData;
64
68public class ALeappAnalyzerIngestModule implements DataSourceIngestModule {
69
70 private static final Logger logger = Logger.getLogger(ALeappAnalyzerIngestModule.class.getName());
71 private static final String MODULE_NAME = ALeappAnalyzerModuleFactory.getModuleName();
72
73 private static final String ALEAPP = "aLeapp"; //NON-NLS
74 private static final String ALEAPP_FS = "fs_"; //NON-NLS
75 private static final String ALEAPP_EXECUTABLE = "aleapp.exe";//NON-NLS
76 private static final String ALEAPP_PATHS_FILE = "aLeapp_paths.txt"; //NON-NLS
77
78 private static final String XMLFILE = "aleapp-artifact-attribute-reference.xml"; //NON-NLS
79
80 // Android-specific files used to detect whether the data source is from an Android device.
81 // Filename and parent-path pairs searched in order; finding any one is sufficient.
82 private static final List<String[]> ANDROID_INDICATOR_FILES = Arrays.asList(
83 new String[]{"build.prop", "/system/"}, //NON-NLS
84 new String[]{"packages.xml", "/data/system/"}, //NON-NLS
85 new String[]{"settings.db", "/data/com.android.providers.settings/databases/"}); //NON-NLS
86
87 private File aLeappExecutable;
88
90
92
93 ALeappAnalyzerIngestModule() {
94 // This constructor is intentionally empty. Nothing special is needed here.
95 }
96
97 @NbBundle.Messages({
98 "ALeappAnalyzerIngestModule.executable.not.found=aLeapp Executable Not Found.",
99 "ALeappAnalyzerIngestModule.requires.windows=aLeapp module requires windows.",
100 "ALeappAnalyzerIngestModule.error.aleapp.file.processor.init=Failure to initialize aLeappProcessFile"})
101 @Override
103 this.context = context;
104
105 if (false == PlatformUtil.is64BitOS()) {
106 throw new IngestModuleException(NbBundle.getMessage(this.getClass(), "AleappAnalyzerIngestModule.not.64.bit.os"));
107 }
108
109 if (false == PlatformUtil.isWindowsOS()) {
110 throw new IngestModuleException(Bundle.ALeappAnalyzerIngestModule_requires_windows());
111 }
112
113 try {
115 } catch (IOException | IngestModuleException | NoCurrentCaseException ex) {
116 throw new IngestModuleException(Bundle.ALeappAnalyzerIngestModule_error_aleapp_file_processor_init(), ex);
117 }
118
119 try {
121 } catch (FileNotFoundException exception) {
122 logger.log(Level.WARNING, "aLeapp executable not found.", exception); //NON-NLS
123 throw new IngestModuleException(Bundle.ALeappAnalyzerIngestModule_executable_not_found(), exception);
124 }
125
126 }
127
128 @NbBundle.Messages({
129 "ALeappAnalyzerIngestModule.error.running.aLeapp=Error running aLeapp, see log file.",
130 "ALeappAnalyzerIngestModule.error.creating.output.dir=Error creating aLeapp module output directory.",
131 "ALeappAnalyzerIngestModule.running.aLeapp=Running aLeapp",
132 "ALeappAnalyzerIngestModule_processing_aLeapp_results=Processing aLeapp results",
133 "ALeappAnalyzerIngestModule.has.run=aLeapp",
134 "ALeappAnalyzerIngestModule.aLeapp.cancelled=aLeapp run was canceled",
135 "ALeappAnalyzerIngestModule.completed=aLeapp Processing Completed",
136 "ALeappAnalyzerIngestModule.report.name=aLeapp Html Report",
137 "ALeappAnalyzerIngestModule.notAndroid.skipped=aLeapp skipped: data source does not appear to be an Android device."})
138 @Override
139 public ProcessResult process(Content dataSource, DataSourceIngestModuleProgress statusHelper) {
140
141 if (!isAndroidDataSource(dataSource)) {
142 logger.log(Level.INFO, "aLeapp: data source does not appear to be Android, skipping."); //NON-NLS
144 MODULE_NAME, Bundle.ALeappAnalyzerIngestModule_notAndroid_skipped());
146 return ProcessResult.OK;
147 }
148
149 statusHelper.switchToIndeterminate();
150 statusHelper.progress(Bundle.ALeappAnalyzerIngestModule_running_aLeapp());
151
152 Case currentCase = Case.getCurrentCase();
153 Path tempOutputPath = Paths.get(currentCase.getTempDirectory(), ALEAPP, ALEAPP_FS + dataSource.getId());
154 try {
155 Files.createDirectories(tempOutputPath);
156 } catch (IOException ex) {
157 logger.log(Level.SEVERE, String.format("Error creating aLeapp output directory %s", tempOutputPath.toString()), ex);
159 return ProcessResult.ERROR;
160 }
161
162 List<String> aLeappPathsToProcess;
163 ProcessBuilder aLeappCommand = buildaLeappListCommand(tempOutputPath);
164 try {
165 int result = ExecUtil.execute(aLeappCommand, new DataSourceIngestModuleProcessTerminator(context, true));
166 if (result != 0) {
167 logger.log(Level.SEVERE, String.format("Error when trying to execute aLeapp program getting file paths to search for result is %d", result));
169 return ProcessResult.ERROR;
170 }
171 aLeappPathsToProcess = loadAleappPathFile(tempOutputPath);
172 if (aLeappPathsToProcess.isEmpty()) {
173 logger.log(Level.SEVERE, String.format("Error getting file paths to search, list is empty"));
175 return ProcessResult.ERROR;
176 }
177 } catch (IOException ex) {
178 logger.log(Level.SEVERE, String.format("Error when trying to execute aLeapp program getting file paths to search"), ex);
180 return ProcessResult.ERROR;
181 }
182
183 if ((context.getDataSource() instanceof LocalFilesDataSource)) {
184 /*
185 * The data source may be local files from an iOS file system, or it
186 * may be a tarred/ZIP of an iOS file system. If it is the latter,
187 * extract the files we need to process.
188 */
189 List<AbstractFile> aLeappFilesToProcess = LeappFileProcessor.findLeappFilesToProcess(dataSource);
190 if (!aLeappFilesToProcess.isEmpty()) {
191 statusHelper.switchToDeterminate(aLeappFilesToProcess.size());
192 Integer filesProcessedCount = 0;
193 for (AbstractFile aLeappFile : aLeappFilesToProcess) {
194 processALeappFile(dataSource, currentCase, statusHelper, filesProcessedCount, aLeappFile);
195 filesProcessedCount++;
196 }
197 }
198 }
199
200 statusHelper.switchToIndeterminate();
201 statusHelper.progress(Bundle.ALeappAnalyzerIngestModule_processing_aLeapp_results());
202 extractFilesFromDataSource(dataSource, aLeappPathsToProcess, tempOutputPath);
203 processALeappFs(dataSource, currentCase, statusHelper, tempOutputPath.toString());
204
206 Bundle.ALeappAnalyzerIngestModule_has_run(),
207 Bundle.ALeappAnalyzerIngestModule_completed());
209 return ProcessResult.OK;
210 }
211
222 private void processALeappFile(Content dataSource, Case currentCase, DataSourceIngestModuleProgress statusHelper, int filesProcessedCount,
223 AbstractFile aLeappFile) {
224 statusHelper.progress(NbBundle.getMessage(this.getClass(), "ALeappAnalyzerIngestModule.processing.file", aLeappFile.getName()), filesProcessedCount);
225 String currentTime = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss z", Locale.US).format(System.currentTimeMillis());//NON-NLS
226 Path moduleOutputPath = Paths.get(currentCase.getModuleDirectory(), ALEAPP, currentTime);
227 try {
228 Files.createDirectories(moduleOutputPath);
229 } catch (IOException ex) {
230 logger.log(Level.SEVERE, String.format("Error creating aLeapp output directory %s", moduleOutputPath.toString()), ex);
231 return;
232 }
233
234 ProcessBuilder aLeappCommand = buildaLeappCommand(moduleOutputPath, aLeappFile.getLocalAbsPath(), aLeappFile.getNameExtension());
235 try {
236 int result = ExecUtil.execute(aLeappCommand, new DataSourceIngestModuleProcessTerminator(context, true));
237 if (result != 0) {
238 logger.log(Level.WARNING, String.format("Error when trying to execute aLeapp program getting file paths to search for result is %d", result));
239 return;
240 }
241
242 addALeappReportToReports(moduleOutputPath, currentCase);
243
244 } catch (IOException ex) {
245 logger.log(Level.SEVERE, String.format("Error when trying to execute aLeapp program against file %s", aLeappFile.getLocalAbsPath()), ex);
246 return;
247 }
248
249 if (context.dataSourceIngestIsCancelled()) {
250 logger.log(Level.INFO, "aLeapp Analyser ingest module run was canceled"); //NON-NLS
251 return;
252 }
253
254 aLeappFileProcessor.processFiles(dataSource, moduleOutputPath, aLeappFile, statusHelper);
255 }
256
266 private void processALeappFs(Content dataSource, Case currentCase, DataSourceIngestModuleProgress statusHelper, String directoryToProcess) {
267 statusHelper.progress(NbBundle.getMessage(this.getClass(), "ALeappAnalyzerIngestModule.processing.filesystem"));
268 String currentTime = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss z", Locale.US).format(System.currentTimeMillis());//NON-NLS
269 Path moduleOutputPath = Paths.get(currentCase.getModuleDirectory(), ALEAPP, currentTime);
270 try {
271 Files.createDirectories(moduleOutputPath);
272 } catch (IOException ex) {
273 logger.log(Level.SEVERE, String.format("Error creating aLeapp output directory %s", moduleOutputPath.toString()), ex);
274 return;
275 }
276
277 ProcessBuilder aLeappCommand = buildaLeappCommand(moduleOutputPath, directoryToProcess, "fs");
278 try {
279 int result = ExecUtil.execute(aLeappCommand, new DataSourceIngestModuleProcessTerminator(context, true));
280 if (result != 0) {
281 logger.log(Level.WARNING, String.format("Error when trying to execute aLeapp program getting file paths to search for result is %d", result));
282 return;
283 }
284
285 addALeappReportToReports(moduleOutputPath, currentCase);
286
287 } catch (IOException ex) {
288 logger.log(Level.SEVERE, String.format("Error when trying to execute aLeapp program against file system"), ex);
289 return;
290 }
291
292 if (context.dataSourceIngestIsCancelled()) {
293 logger.log(Level.INFO, "aLeapp Analyser ingest module run was canceled"); //NON-NLS
294 return;
295 }
296
297 aLeappFileProcessor.processFileSystem(dataSource, moduleOutputPath, statusHelper);
298 }
299
309 private ProcessBuilder buildaLeappCommand(Path moduleOutputPath, String sourceFilePath, String aLeappFileSystemType) {
310
311 ProcessBuilder processBuilder = buildProcessWithRunAsInvoker(
312 aLeappExecutable.getAbsolutePath(), //NON-NLS
313 "-t", aLeappFileSystemType, //NON-NLS
314 "-i", sourceFilePath, //NON-NLS
315 "-o", moduleOutputPath.toString(),
316 "-w"
317 );
318 processBuilder.directory(moduleOutputPath.toFile());
319 processBuilder.redirectError(moduleOutputPath.resolve("aLeapp_err.txt").toFile()); //NON-NLS
320 processBuilder.redirectOutput(moduleOutputPath.resolve("aLeapp_out.txt").toFile()); //NON-NLS
321 return processBuilder;
322 }
323
324 private ProcessBuilder buildaLeappListCommand(Path moduleOutputPath) {
325
326 ProcessBuilder processBuilder = buildProcessWithRunAsInvoker(
327 aLeappExecutable.getAbsolutePath(), //NON-NLS
328 "-p"
329 );
330 // leapp process creates a text file in addition to outputting to stdout.
331 processBuilder.directory(moduleOutputPath.toFile());
332 processBuilder.redirectError(moduleOutputPath.resolve("aLeapp_paths_error.txt").toFile()); //NON-NLS
333 processBuilder.redirectOutput(moduleOutputPath.resolve("aLeapp_paths.txt").toFile()); //NON-NLS
334 return processBuilder;
335 }
336
337 static private ProcessBuilder buildProcessWithRunAsInvoker(String... commandLine) {
338 ProcessBuilder processBuilder = new ProcessBuilder(commandLine);
339 /*
340 * Add an environment variable to force aLeapp to run with the same
341 * permissions Autopsy uses.
342 */
343 processBuilder.environment().put("__COMPAT_LAYER", "RunAsInvoker"); //NON-NLS
344 return processBuilder;
345 }
346
347 private static File locateExecutable(String executableName) throws FileNotFoundException {
348 String executableToFindName = Paths.get(ALEAPP, executableName).toString();
349
350 File exeFile = InstalledFileLocator.getDefault().locate(executableToFindName, ALeappAnalyzerIngestModule.class.getPackage().getName(), false);
351 if (null == exeFile || exeFile.canExecute() == false) {
352 throw new FileNotFoundException(executableName + " executable not found.");
353 }
354 return exeFile;
355 }
356
361 private void addALeappReportToReports(Path aLeappOutputDir, Case currentCase) {
362 List<String> allIndexFiles = new ArrayList<>();
363
364 try (Stream<Path> walk = Files.walk(aLeappOutputDir)) {
365
366 allIndexFiles = walk.map(x -> x.toString())
367 .filter(f -> f.toLowerCase().endsWith("index.html")).collect(Collectors.toList());
368
369 if (!allIndexFiles.isEmpty()) {
370 // Check for existance of directory that holds report data if does not exist then report contains no data
371 String filePath = FilenameUtils.getFullPathNoEndSeparator(allIndexFiles.get(0));
372 File dataFilesDir = new File(Paths.get(filePath, "_TSV Exports").toString());
373 if (dataFilesDir.exists()) {
374 currentCase.addReport(allIndexFiles.get(0), MODULE_NAME, Bundle.ALeappAnalyzerIngestModule_report_name());
375 }
376 }
377
378 } catch (IOException | UncheckedIOException | TskCoreException ex) {
379 // catch the error and continue on as report is not added
380 logger.log(Level.WARNING, String.format("Error finding index file in path %s", aLeappOutputDir.toString()), ex);
381 }
382
383 }
384
385 /*
386 * Reads the aLeapp paths file to get the paths that we want to extract
387 *
388 */
389 private List<String> loadAleappPathFile(Path moduleOutputPath) throws FileNotFoundException, IOException {
390 List<String> aLeappPathsToProcess = new ArrayList<>();
391
392 Path filePath = Paths.get(moduleOutputPath.toString(), ALEAPP_PATHS_FILE);
393
394 try (BufferedReader reader = new BufferedReader(new FileReader(filePath.toString()))) {
395 String line = reader.readLine();
396 while (line != null) {
397 if (line.contains("path list generation") || line.length() < 2) {
398 line = reader.readLine();
399 continue;
400 }
401 aLeappPathsToProcess.add(line.trim());
402 line = reader.readLine();
403 }
404 }
405
406 return aLeappPathsToProcess;
407 }
408
409 private void extractFilesFromDataSource(Content dataSource, List<String> aLeappPathsToProcess, Path moduleOutputPath) {
410 FileManager fileManager = getCurrentCase().getServices().getFileManager();
411
412 for (String fullFilePath : aLeappPathsToProcess) {
413
414 if (context.dataSourceIngestIsCancelled()) {
415 logger.log(Level.INFO, "aLeapp Analyser ingest module run was canceled"); //NON-NLS
416 break;
417 }
418
419 String ffp = fullFilePath.replaceAll("\\*", "%");
420 ffp = FilenameUtils.normalize(ffp, true);
421 String fileName = FilenameUtils.getName(ffp);
422 String filePath = FilenameUtils.getPath(ffp);
423
424 List<AbstractFile> aLeappFiles = new ArrayList<>();
425 try {
426 if (filePath.isEmpty()) {
427 aLeappFiles = fileManager.findFiles(dataSource, fileName); //NON-NLS
428 } else {
429 aLeappFiles = fileManager.findFiles(dataSource, fileName, filePath); //NON-NLS
430 }
431 } catch (TskCoreException ex) {
432 logger.log(Level.WARNING, "No files found to process"); //NON-NLS
433 return;
434 }
435
436 for (AbstractFile aLeappFile : aLeappFiles) {
437 Path parentPath = Paths.get(moduleOutputPath.toString(), aLeappFile.getParentPath());
438 File fileParentPath = new File(parentPath.toString());
439
440 extractFileToOutput(dataSource, aLeappFile, fileParentPath, parentPath);
441 }
442 }
443 }
444
445 private void extractFileToOutput(Content dataSource, AbstractFile aLeappFile, File fileParentPath, Path parentPath) {
446 if (fileParentPath.exists()) {
447 if (!aLeappFile.isDir()) {
448 writeaLeappFile(dataSource, aLeappFile, fileParentPath.toString());
449 } else {
450 try {
451 Files.createDirectories(Paths.get(parentPath.toString(), aLeappFile.getName()));
452 } catch (IOException ex) {
453 logger.log(Level.INFO, String.format("Error creating aLeapp output directory %s", parentPath.toString()), ex);
454 }
455 }
456 } else {
457 try {
458 Files.createDirectories(parentPath);
459 } catch (IOException ex) {
460 logger.log(Level.INFO, String.format("Error creating aLeapp output directory %s", parentPath.toString()), ex);
461 }
462 if (!aLeappFile.isDir()) {
463 writeaLeappFile(dataSource, aLeappFile, fileParentPath.toString());
464 } else {
465 try {
466 Files.createDirectories(Paths.get(parentPath.toString(), aLeappFile.getName()));
467 } catch (IOException ex) {
468 logger.log(Level.INFO, String.format("Error creating aLeapp output directory %s", parentPath.toString()), ex);
469 }
470 }
471 }
472 }
473
474 private void writeaLeappFile(Content dataSource, AbstractFile aLeappFile, String parentPath) {
475 String fileName = aLeappFile.getName().replace(":", "-");
476 if (!fileName.matches(".") && !fileName.matches("..") && !fileName.toLowerCase().endsWith("-slack")) {
477 Path filePath = Paths.get(parentPath, fileName);
478 File localFile = new File(filePath.toString());
479 try {
480 ContentUtils.writeToFile(aLeappFile, localFile, context::dataSourceIngestIsCancelled);
481 } catch (ReadContentInputStream.ReadContentInputStreamException ex) {
482 logger.log(Level.WARNING, String.format("Error reading file '%s' (id=%d).",
483 aLeappFile.getName(), aLeappFile.getId()), ex); //NON-NLS
484 } catch (IOException ex) {
485 logger.log(Level.WARNING, String.format("Error writing file local file '%s' (id=%d).",
486 filePath.toString(), aLeappFile.getId()), ex); //NON-NLS
487 }
488 }
489 }
490
502 private boolean isAndroidDataSource(Content dataSource) {
503 if (dataSource instanceof Image) {
504 try {
505 boolean hasAndroidFs = false;
506 boolean hasDefinitelyNonAndroidFs = false;
507 for (FileSystem fs : ((Image) dataSource).getFileSystems()) {
508 switch (fs.getFsType()) {
509 case TSK_FS_TYPE_EXT3:
510 case TSK_FS_TYPE_EXT4:
511 case TSK_FS_TYPE_YAFFS2:
512 case TSK_FS_TYPE_YAFFS2_DETECT:
513 // EXT3/4 and YAFFS2 are strongly associated with Android;
514 // no further indicator-file check needed.
515 hasAndroidFs = true;
516 break;
517 case TSK_FS_TYPE_NTFS:
518 case TSK_FS_TYPE_NTFS_DETECT:
519 case TSK_FS_TYPE_HFS:
520 case TSK_FS_TYPE_HFS_DETECT:
521 case TSK_FS_TYPE_APFS:
522 case TSK_FS_TYPE_APFS_DETECT:
523 hasDefinitelyNonAndroidFs = true;
524 break;
525 default:
526 break;
527 }
528 }
529 if (hasAndroidFs) {
530 return true;
531 }
532 if (hasDefinitelyNonAndroidFs) {
533 return false;
534 }
535 // FAT-only or no recognized FS: fall through to file check
536 } catch (TskCoreException ex) {
537 logger.log(Level.WARNING, "Error checking filesystem types for aLeapp Android detection", ex); //NON-NLS
538 }
539 }
540 return hasAndroidIndicatorFiles(dataSource);
541 }
542
551 private boolean hasAndroidIndicatorFiles(Content dataSource) {
552 FileManager fileManager = getCurrentCase().getServices().getFileManager();
553 for (String[] fileInfo : ANDROID_INDICATOR_FILES) {
554 try {
555 if (!fileManager.findFiles(dataSource, fileInfo[0], fileInfo[1]).isEmpty()) {
556 return true;
557 }
558 } catch (TskCoreException ex) {
559 logger.log(Level.WARNING, String.format("Error searching for Android indicator file '%s'", fileInfo[0]), ex); //NON-NLS
560 return true; // Fail open: an inconclusive search is not a negative result.
561 }
562 }
563 return false;
564 }
565
573 Bundle.ALeappAnalyzerIngestModule_error_running_aLeapp());
575 }
576
577}
void addReport(String localPath, String srcModuleName, String reportName)
Definition Case.java:1929
List< AbstractFile > findFiles(String fileName)
static int execute(ProcessBuilder processBuilder)
synchronized static Logger getLogger(String name)
Definition Logger.java:124
static< T > long writeToFile(Content content, java.io.File outputFile, ProgressHandle progress, Future< T > worker, boolean source)
static IngestMessage createMessage(MessageType messageType, String source, String subject, String detailsHtml)
void postMessage(final IngestMessage message)
static synchronized IngestServices getInstance()
void processALeappFile(Content dataSource, Case currentCase, DataSourceIngestModuleProgress statusHelper, int filesProcessedCount, AbstractFile aLeappFile)
void extractFilesFromDataSource(Content dataSource, List< String > aLeappPathsToProcess, Path moduleOutputPath)
void writeaLeappFile(Content dataSource, AbstractFile aLeappFile, String parentPath)
void processALeappFs(Content dataSource, Case currentCase, DataSourceIngestModuleProgress statusHelper, String directoryToProcess)
void extractFileToOutput(Content dataSource, AbstractFile aLeappFile, File fileParentPath, Path parentPath)
ProcessBuilder buildaLeappCommand(Path moduleOutputPath, String sourceFilePath, String aLeappFileSystemType)
ProcessResult process(Content dataSource, DataSourceIngestModuleProgress statusHelper)

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