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.displayName=Data Source Usage Analyzer"})
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;
59 private final IngestJobContext context;
61 DataSourceUsageAnalyzer(IngestJobContext context) {
62 super(Bundle.DataSourceUsageAnalyzer_displayName(), context);
63 this.context = context;
68 "DataSourceUsageAnalyzer.customVolume.label=OS Drive ({0})",
69 "Progress_Message_Analyze_Usage=Data Sources Usage Analysis",})
71 void process(Content dataSource, DataSourceIngestModuleProgress progressBar) {
72 this.dataSource = dataSource;
74 progressBar.progress(Bundle.Progress_Message_Analyze_Usage());
75 createDataSourceUsageArtifacts();
76 }
catch (TskCoreException ex) {
77 logger.log(Level.WARNING,
"Failed to check if datasource contained a volume with operating system specific files", ex);
82 private void createDataSourceUsageArtifacts() throws TskCoreException {
83 createOSInfoDataSourceUsageArtifacts();
84 if (context.dataSourceIngestIsCancelled()) {
87 createAndroidMediaCardArtifacts();
88 if (context.dataSourceIngestIsCancelled()) {
91 createDJIDroneDATArtitifacts();
100 private void createOSInfoDataSourceUsageArtifacts() throws TskCoreException {
101 boolean windowsOsDetected =
false;
102 List<BlackboardArtifact> osInfoArtifacts = tskCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_OS_INFO);
103 for (BlackboardArtifact osInfoArt : osInfoArtifacts) {
105 if (osInfoArt.getDataSource().getId() == dataSource.getId()) {
106 BlackboardAttribute progNameAttr = osInfoArt.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME));
107 if (progNameAttr != null) {
108 if (progNameAttr.getValueString().isEmpty()) {
110 }
else if (progNameAttr.getDisplayString().toLowerCase().contains(
"windows")) {
111 windowsOsDetected =
true;
113 createDataSourceUsageArtifact(Bundle.DataSourceUsageAnalyzer_customVolume_label(progNameAttr.getDisplayString()));
115 ExtractOs.OS_TYPE osType = ExtractOs.OS_TYPE.fromOsInfoLabel(progNameAttr.getValueString());
116 if (osType != null) {
117 createDataSourceUsageArtifact(osType.getDsUsageLabel());
120 createDataSourceUsageArtifact(Bundle.DataSourceUsageAnalyzer_customVolume_label(progNameAttr.getDisplayString()));
126 if (!windowsOsDetected) {
127 checkIfOsSpecificVolume(ExtractOs.OS_TYPE.WINDOWS);
140 private void createDataSourceUsageArtifact(String dataSourceUsageDescription)
throws TskCoreException {
142 List<BlackboardArtifact> artifacts = tskCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_DATA_SOURCE_USAGE, dataSource.getId());
143 for (BlackboardArtifact artifact : artifacts) {
144 if (artifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DESCRIPTION)).getValueString().equals(dataSourceUsageDescription)) {
148 Collection<BlackboardAttribute> bbattributes =
new ArrayList<>();
149 bbattributes.add(
new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DESCRIPTION,
151 dataSourceUsageDescription));
152 postArtifact(createArtifactWithAttributes(BlackboardArtifact.Type.TSK_DATA_SOURCE_USAGE, dataSource, bbattributes));
162 private void checkIfOsSpecificVolume(ExtractOs.OS_TYPE osType) throws TskCoreException {
163 for (String filePath : osType.getFilePaths()) {
164 for (AbstractFile file : currentCase.getSleuthkitCase().getFileManager().findFilesExactNameExactPath(dataSource,
165 FilenameUtils.getName(filePath), FilenameUtils.getPath(filePath))) {
166 createDataSourceUsageArtifact(osType.getDsUsageLabel());
181 "DataSourceUsage_AndroidMedia=Android Media Card",
182 "DataSourceUsage_FlashDrive=Flash Drive"
184 private void createAndroidMediaCardArtifacts() {
186 if (dataSource instanceof Image) {
187 Image image = (Image) dataSource;
189 if (image.getSize() > HUNDRED_GB) {
193 List<FileSystem> fileSystems = image.getFileSystems();
194 if (fileSystems.isEmpty() || fileSystems.size() > 1) {
198 FileSystem fileSystem = fileSystems.get(0);
199 if (fileSystem == null || (fileSystem.getFsType().getValue() & FAT_EXFAT_FLAGS) == 0) {
203 if (hasAndroidMediaCardRootNames()) {
208 createDataSourceUsageArtifact(Bundle.DataSourceUsage_FlashDrive());
210 }
catch (TskCoreException ex) {
211 logger.log(Level.SEVERE,
"Exception while checking image: {0} for Andriod media card", image.getName() + ex.getMessage());
223 private boolean hasAndroidMediaCardRootNames() throws TskCoreException {
224 FileManager fileManager = currentCase.getServices().getFileManager();
225 for (String fileName : ANDROID_MEDIACARD_ROOT_FILENAMES) {
226 for (AbstractFile file : fileManager.findFiles(dataSource, fileName,
"/")) {
227 if (file.getParentPath().equals(
"/") && file.getName().equalsIgnoreCase(fileName)) {
228 createDataSourceUsageArtifact(Bundle.DataSourceUsage_AndroidMedia());
246 "DataSourceUsage_DJU_Drone_DAT=DJI Internal SD Card"
248 private void createDJIDroneDATArtitifacts() throws TskCoreException {
249 FileManager fileManager = currentCase.getServices().getFileManager();
251 List<AbstractFile> files = fileManager.findFiles(dataSource,
"FLY___.DAT");
252 if (files != null && !files.isEmpty()) {
253 createDataSourceUsageArtifact(Bundle.DataSourceUsage_DJU_Drone_DAT());