19 package org.sleuthkit.autopsy.recentactivity;
21 import java.util.ArrayList;
22 import java.util.Collection;
23 import java.util.List;
24 import java.util.logging.Level;
25 import org.apache.commons.io.FilenameUtils;
26 import org.openide.util.NbBundle.Messages;
45 @Messages({
"DataSourceUsageAnalyzer.parentModuleName=Recent Activity"})
46 class DataSourceUsageAnalyzer extends Extract {
48 private static final Logger logger = Logger.getLogger(DataSourceUsageAnalyzer.class.getName());
49 private static final int FAT_EXFAT_FLAGS = TskData.TSK_FS_TYPE_ENUM.TSK_FS_TYPE_FAT16.getValue()
50 | TskData.TSK_FS_TYPE_ENUM.TSK_FS_TYPE_FAT32.getValue()
51 | TskData.TSK_FS_TYPE_ENUM.TSK_FS_TYPE_EXFAT.getValue();
52 private static final long HUNDRED_GB = 100 * 1024 * 1024 * 1024l;
54 private static final String ANDROID_MEDIACARD_ROOT_FILENAMES[]
56 {
".android_secure",
"android",
"audio",
57 "photos",
"dcim",
"music",
"pictures",
"videos"};
58 private Content dataSource;
62 "DataSourceUsageAnalyzer.customVolume.label=OS Drive ({0})",
63 "Progress_Message_Analyze_Usage=Data Sources Usage Analysis",})
65 void process(Content dataSource, IngestJobContext context, DataSourceIngestModuleProgress progressBar) {
66 this.dataSource = dataSource;
68 progressBar.progress(Bundle.Progress_Message_Analyze_Usage());
69 createDataSourceUsageArtifacts(context);
70 }
catch (TskCoreException ex) {
71 logger.log(Level.WARNING,
"Failed to check if datasource contained a volume with operating system specific files", ex);
76 private void createDataSourceUsageArtifacts(IngestJobContext context)
throws TskCoreException {
78 createOSInfoDataSourceUsageArtifacts();
80 if (context.dataSourceIngestIsCancelled()) {
84 createAndroidMediaCardArtifacts();
86 if (context.dataSourceIngestIsCancelled()) {
90 createDJIDroneDATArtitifacts();
99 private void createOSInfoDataSourceUsageArtifacts() throws TskCoreException {
100 boolean windowsOsDetected =
false;
101 List<BlackboardArtifact> osInfoArtifacts = tskCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_OS_INFO);
102 for (BlackboardArtifact osInfoArt : osInfoArtifacts) {
104 if (osInfoArt.getDataSource().getId() == dataSource.getId()) {
105 BlackboardAttribute progNameAttr = osInfoArt.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME));
106 if (progNameAttr != null) {
107 if (progNameAttr.getValueString().isEmpty()) {
109 }
else if (progNameAttr.getDisplayString().toLowerCase().contains(
"windows")) {
110 windowsOsDetected =
true;
112 createDataSourceUsageArtifact(Bundle.DataSourceUsageAnalyzer_customVolume_label(progNameAttr.getDisplayString()));
114 ExtractOs.OS_TYPE osType = ExtractOs.OS_TYPE.fromOsInfoLabel(progNameAttr.getValueString());
115 if (osType != null) {
116 createDataSourceUsageArtifact(osType.getDsUsageLabel());
119 createDataSourceUsageArtifact(Bundle.DataSourceUsageAnalyzer_customVolume_label(progNameAttr.getDisplayString()));
125 if (!windowsOsDetected) {
126 checkIfOsSpecificVolume(ExtractOs.OS_TYPE.WINDOWS);
139 private void createDataSourceUsageArtifact(String dataSourceUsageDescription)
throws TskCoreException {
141 List<BlackboardArtifact> artifacts = tskCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_DATA_SOURCE_USAGE, dataSource.getId());
142 for (BlackboardArtifact artifact : artifacts) {
143 if (artifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DESCRIPTION)).getValueString().equals(dataSourceUsageDescription)) {
147 Collection<BlackboardAttribute> bbattributes =
new ArrayList<>();
148 bbattributes.add(
new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DESCRIPTION,
149 Bundle.DataSourceUsageAnalyzer_parentModuleName(),
150 dataSourceUsageDescription));
151 postArtifact(createArtifactWithAttributes(BlackboardArtifact.ARTIFACT_TYPE.TSK_DATA_SOURCE_USAGE, dataSource, bbattributes));
161 private void checkIfOsSpecificVolume(ExtractOs.OS_TYPE osType) throws TskCoreException {
162 for (String filePath : osType.getFilePaths()) {
163 for (AbstractFile file : currentCase.getSleuthkitCase().getFileManager().findFilesExactNameExactPath(dataSource,
164 FilenameUtils.getName(filePath), FilenameUtils.getPath(filePath))) {
165 createDataSourceUsageArtifact(osType.getDsUsageLabel());
180 "DataSourceUsage_AndroidMedia=Android Media Card",
181 "DataSourceUsage_FlashDrive=Flash Drive"
183 private void createAndroidMediaCardArtifacts() {
185 if (dataSource instanceof Image) {
186 Image image = (Image) dataSource;
188 if (image.getSize() > HUNDRED_GB) {
192 List<FileSystem> fileSystems = image.getFileSystems();
193 if (fileSystems.isEmpty() || fileSystems.size() > 1) {
197 FileSystem fileSystem = fileSystems.get(0);
198 if (fileSystem == null || (fileSystem.getFsType().getValue() & FAT_EXFAT_FLAGS) == 0) {
202 if(hasAndroidMediaCardRootNames()) {
207 createDataSourceUsageArtifact(Bundle.DataSourceUsage_FlashDrive());
209 }
catch (TskCoreException ex) {
210 logger.log(Level.SEVERE,
"Exception while checking image: {0} for Andriod media card", image.getName() + ex.getMessage());
222 private boolean hasAndroidMediaCardRootNames() throws TskCoreException{
223 FileManager fileManager = currentCase.getServices().getFileManager();
224 for (String fileName : ANDROID_MEDIACARD_ROOT_FILENAMES) {
225 for (AbstractFile file : fileManager.findFiles(dataSource, fileName,
"/")) {
226 if (file.getParentPath().equals(
"/") && file.getName().equalsIgnoreCase(fileName)) {
227 createDataSourceUsageArtifact(Bundle.DataSourceUsage_AndroidMedia());
245 "DataSourceUsage_DJU_Drone_DAT=DJI Internal SD Card"
247 private void createDJIDroneDATArtitifacts() throws TskCoreException {
248 FileManager fileManager = currentCase.getServices().getFileManager();
250 List<AbstractFile> files = fileManager.findFiles(dataSource,
"FLY___.DAT");
251 if (files != null && !files.isEmpty()) {
252 createDataSourceUsageArtifact(Bundle.DataSourceUsage_DJU_Drone_DAT());