Autopsy 4.22.1
Graphical digital forensics platform for The Sleuth Kit and other tools.
SampleFileIngestModule.java
Go to the documentation of this file.
1/*
2 * Sample module in the public domain. Feel free to use this as a template
3 * for your modules.
4 *
5 * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
6 *
7 * This is free and unencumbered software released into the public domain.
8 *
9 * Anyone is free to copy, modify, publish, use, compile, sell, or
10 * distribute this software, either in source code form or as a compiled
11 * binary, for any purpose, commercial or non-commercial, and by any
12 * means.
13 *
14 * In jurisdictions that recognize copyright laws, the author or authors
15 * of this software dedicate any and all copyright interest in the
16 * software to the public domain. We make this dedication for the benefit
17 * of the public at large and to the detriment of our heirs and
18 * successors. We intend this dedication to be an overt act of
19 * relinquishment in perpetuity of all present and future rights to this
20 * software under copyright law.
21 *
22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
25 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
26 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
27 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28 * OTHER DEALINGS IN THE SOFTWARE.
29 */
30package org.sleuthkit.autopsy.examples;
31
32import java.util.HashMap;
33import java.util.logging.Level;
34import org.sleuthkit.autopsy.coreutils.Logger;
35import org.sleuthkit.autopsy.ingest.FileIngestModule;
36import org.sleuthkit.autopsy.ingest.IngestJobContext;
37import org.sleuthkit.autopsy.ingest.IngestMessage;
38import org.sleuthkit.autopsy.ingest.IngestModule;
39import org.sleuthkit.autopsy.ingest.IngestModuleReferenceCounter;
40import org.sleuthkit.autopsy.ingest.IngestServices;
41import org.sleuthkit.datamodel.AbstractFile;
42import org.sleuthkit.datamodel.Blackboard;
43import org.sleuthkit.datamodel.BlackboardArtifact;
44import org.sleuthkit.datamodel.BlackboardAttribute;
45import org.sleuthkit.datamodel.TskCoreException;
46import org.sleuthkit.datamodel.TskData;
47
53class SampleFileIngestModule implements FileIngestModule {
54
55 private static final HashMap<Long, Long> artifactCountsForIngestJobs = new HashMap<>();
56 private static final BlackboardAttribute.ATTRIBUTE_TYPE ATTR_TYPE = BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COUNT;
57 private final boolean skipKnownFiles;
58 private IngestJobContext context = null;
59 private static final IngestModuleReferenceCounter refCounter = new IngestModuleReferenceCounter();
60
61 SampleFileIngestModule(SampleModuleIngestJobSettings settings) {
62 this.skipKnownFiles = settings.skipKnownFiles();
63 }
64
65 @Override
66 public void startUp(IngestJobContext context) throws IngestModuleException {
67 this.context = context;
68 refCounter.incrementAndGet(context.getJobId());
69 }
70
71 @Override
72 public IngestModule.ProcessResult process(AbstractFile file) {
73
74 // Skip anything other than actual file system files.
75 if ((file.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS)
76 || (file.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS)
77 || (file.isFile() == false)) {
78 return IngestModule.ProcessResult.OK;
79 }
80
81 // Skip NSRL / known files.
82 if (skipKnownFiles && file.getKnown() == TskData.FileKnown.KNOWN) {
83 return IngestModule.ProcessResult.OK;
84 }
85
86 // Do a nonsensical calculation of the number of 0x00 bytes
87 // in the first 1024-bytes of the file. This is for demo
88 // purposes only.
89 try {
90 byte buffer[] = new byte[1024];
91 int len = file.read(buffer, 0, 1024);
92 int count = 0;
93 for (int i = 0; i < len; i++) {
94 if (buffer[i] == 0x00) {
95 count++;
96 }
97 }
98
99 // Make an attribute using the ID for the attribute attrType that
100 // was previously created.
101 BlackboardAttribute attr = new BlackboardAttribute(ATTR_TYPE, SampleIngestModuleFactory.getModuleName(), count);
102
103 // Add the to the general info artifact for the file. In a
104 // real module, you would likely have more complex data types
105 // and be making more specific artifacts.
106 BlackboardArtifact art = file.getGenInfoArtifact();
107 art.addAttribute(attr);
108
109 // This method is thread-safe with per ingest job reference counted
110 // management of shared data.
111 addToBlackboardPostCount(context.getJobId(), 1L);
112
113 /*
114 * Post the artifact to the blackboard. Doing so will cause events
115 * to be published that will trigger additional analysis, if
116 * applicable. For example, the creation of timeline events,
117 * indexing of the artifact for keyword search, and analysis by the
118 * data artifact ingest modules if the artifact is a data artifact.
119 */
120 file.getSleuthkitCase().getBlackboard().postArtifact(art, SampleIngestModuleFactory.getModuleName(), context.getJobId());
121
122 return IngestModule.ProcessResult.OK;
123
124 } catch (TskCoreException | Blackboard.BlackboardException ex) {
125 IngestServices ingestServices = IngestServices.getInstance();
126 Logger logger = ingestServices.getLogger(SampleIngestModuleFactory.getModuleName());
127 logger.log(Level.SEVERE, "Error processing file (id = " + file.getId() + ")", ex);
128 return IngestModule.ProcessResult.ERROR;
129 }
130 }
131
132 @Override
133 public void shutDown() {
134 // This method is thread-safe with per ingest job reference counted
135 // management of shared data.
136 reportBlackboardPostCount(context.getJobId());
137 }
138
139 synchronized static void addToBlackboardPostCount(long ingestJobId, long countToAdd) {
140 Long fileCount = artifactCountsForIngestJobs.get(ingestJobId);
141
142 // Ensures that this job has an entry
143 if (fileCount == null) {
144 fileCount = 0L;
145 artifactCountsForIngestJobs.put(ingestJobId, fileCount);
146 }
147
148 fileCount += countToAdd;
149 artifactCountsForIngestJobs.put(ingestJobId, fileCount);
150 }
151
152 synchronized static void reportBlackboardPostCount(long ingestJobId) {
153 Long refCount = refCounter.decrementAndGet(ingestJobId);
154 if (refCount == 0) {
155 Long filesCount = artifactCountsForIngestJobs.remove(ingestJobId);
156 String msgText = String.format("Posted %d times to the blackboard", filesCount);
157 IngestMessage message = IngestMessage.createMessage(
158 IngestMessage.MessageType.INFO,
159 SampleIngestModuleFactory.getModuleName(),
160 msgText);
161 IngestServices.getInstance().postMessage(message);
162 }
163 }
164}

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