diff --git a/Core/src/org/sleuthkit/autopsy/datasourceprocessors/AddMemoryImageTask.java b/Core/src/org/sleuthkit/autopsy/datasourceprocessors/AddMemoryImageTask.java index 4f4b4a0964..a0a951def7 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourceprocessors/AddMemoryImageTask.java +++ b/Core/src/org/sleuthkit/autopsy/datasourceprocessors/AddMemoryImageTask.java @@ -27,14 +27,12 @@ import java.util.List; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback; import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorProgressMonitor; -import org.sleuthkit.autopsy.casemodule.LocalFilesDSProcessor; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.Image; import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.TskCoreException; import org.openide.util.NbBundle.Messages; -import org.sleuthkit.autopsy.datasourceprocessors.VolatilityProcessor; /* * A runnable that adds a raw data source to a case database. @@ -46,7 +44,6 @@ final class AddMemoryImageTask implements Runnable { private final String imageFilePath; private final String timeZone; private final List PluginsToRun; - private final long chunkSize; private final DataSourceProcessorProgressMonitor progressMonitor; private final DataSourceProcessorCallback callback; private boolean criticalErrorOccurred; @@ -73,7 +70,6 @@ final class AddMemoryImageTask implements Runnable { this.imageFilePath = imageFilePath; this.PluginsToRun = PluginsToRun; this.timeZone = timeZone; - this.chunkSize = chunkSize; this.callback = callback; this.progressMonitor = progressMonitor; } @@ -147,22 +143,15 @@ final class AddMemoryImageTask implements Runnable { Image dataSource = caseDatabase.addImageInfo(0, imageFilePaths, timeZone); //TODO: change hard coded deviceId. dataSources.add(dataSource); + /* call Volatility to process the image **/ + VolatilityProcessor vp = new VolatilityProcessor(imageFilePath, PluginsToRun, dataSource, progressMonitor); + vp.run(); + } catch (TskCoreException ex) { errorMessages.add(Bundle.AddMemoryImageTask_image_critical_error_adding() + imageFilePaths + Bundle.AddMemoryImageTask_for_device() + deviceId + ":" + ex.getLocalizedMessage()); criticalErrorOccurred = true; } finally { caseDatabase.releaseExclusiveLock(); - } - - try { - /** call Volatility to process the image **/ - VolatilityProcessor vp = new VolatilityProcessor(imageFilePath, PluginsToRun, deviceId); - vp.run(); - //LocalFilesDSProcessor localFilesDSP = new LocalFilesDSProcessor(); - //localFilesDSP.run(deviceId, archiveFileName, pathsList, progressMonitor, internalArchiveDspCallBack); - } catch (Exception e) { - - } - + } } } diff --git a/Core/src/org/sleuthkit/autopsy/datasourceprocessors/MemoryDSInputPanel.form b/Core/src/org/sleuthkit/autopsy/datasourceprocessors/MemoryDSInputPanel.form index 43da3a1d98..f70b0a4315 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourceprocessors/MemoryDSInputPanel.form +++ b/Core/src/org/sleuthkit/autopsy/datasourceprocessors/MemoryDSInputPanel.form @@ -151,6 +151,7 @@ + diff --git a/Core/src/org/sleuthkit/autopsy/datasourceprocessors/MemoryDSInputPanel.java b/Core/src/org/sleuthkit/autopsy/datasourceprocessors/MemoryDSInputPanel.java index 45a3fefc16..3f2eff61ed 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourceprocessors/MemoryDSInputPanel.java +++ b/Core/src/org/sleuthkit/autopsy/datasourceprocessors/MemoryDSInputPanel.java @@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.datasourceprocessors; import java.io.File; import java.util.ArrayList; +import java.util.Arrays; import java.util.Calendar; import java.util.HashMap; import java.util.List; @@ -49,14 +50,15 @@ final class MemoryDSInputPanel extends JPanel implements DocumentListener { private final String[] pluginList; private final PluginListTableModel tableModel = new PluginListTableModel(); private final List PluginListNames = new ArrayList<>(); - private final Map pluginListStates = new HashMap<>(); + private final Map pluginListStates = new HashMap<>(); // is set by listeners when users select and deselect items private final Boolean isEnabled = true; /** * Creates new form RawDSInputPanel */ private MemoryDSInputPanel(String context) { this.pluginList = new String[]{"amcache","cmdline","cmdscan","consoles","malfind","netscan","notepad","pslist","psxview","shellbags","shimcache","shutdown","userassist", "apihooks","connscan","devicetree","dlllist","envars","filescan","gahti","getservicesids","getsids","handles","hashdump","hivelist","hivescan","impscan","ldrmodules","lsadump","modules","mutantscan","privs","psscan","pstree","sockets","svcscan","shimcache","timeliner","unloadedmodules","userhandles","vadinfo","verinfo"}; - //this.tableModel = new AbstractTableModel(); + Arrays.sort(this.pluginList); + initComponents(); errorLabel.setVisible(false); @@ -144,10 +146,16 @@ final class MemoryDSInputPanel extends JPanel implements DocumentListener { PluginListNames.clear(); pluginListStates.clear(); - String[] pluginList = { "amcache","cmdline","cmdscan","consoles","malfind","netscan","notepad","pslist","psxview","shellbags","shimcache","shutdown","userassist", "apihooks","connscan","devicetree","dlllist","envars","filescan","gahti","getservicesids","getsids","handles","hashdump","hivelist","hivescan","impscan","ldrmodules","lsadump","modules","mutantscan","privs","psscan","pstree","sockets","svcscan","shimcache","timeliner","unloadedmodules","userhandles","vadinfo","verinfo"}; + // if the config file doesn't exist, then set them all to enabled + boolean allEnabled = !ModuleSettings.configExists(this.contextName); + Map pluginMap = ModuleSettings.getConfigSettings(this.contextName); + for (String plugin : pluginList) { PluginListNames.add(plugin); - pluginListStates.put(plugin, isEnabled); + if (allEnabled) + pluginListStates.put(plugin, true); + else + pluginListStates.put(plugin, pluginMap.containsKey(plugin)); } tableModel.fireTableDataChanged(); //this.tableModel = pluginsToRun.getModel(); @@ -196,6 +204,7 @@ final class MemoryDSInputPanel extends JPanel implements DocumentListener { org.openide.awt.Mnemonics.setLocalizedText(volExecutableLabel, org.openide.util.NbBundle.getMessage(MemoryDSInputPanel.class, "MemoryDSInputPanel.volExecutableLabel.text")); // NOI18N + volExecutableComboBox.setEnabled(false); volExecutableComboBox.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { volExecutableComboBoxActionPerformed(evt); @@ -315,11 +324,16 @@ final class MemoryDSInputPanel extends JPanel implements DocumentListener { List getPluginsToRun() { List enabledPlugins = new ArrayList<>(); + Map pluginMap = new HashMap<>(); for (String plugin : PluginListNames) { if (pluginListStates.get(plugin)) { enabledPlugins.add(plugin); + pluginMap.put(plugin, ""); } } + + ModuleSettings.setConfigSettings(this.contextName, pluginMap); + // @@ Could return keys of set return enabledPlugins; } diff --git a/Core/src/org/sleuthkit/autopsy/datasourceprocessors/VolatilityProcessor.java b/Core/src/org/sleuthkit/autopsy/datasourceprocessors/VolatilityProcessor.java index 7fbb4d6325..b1cdc4dd2a 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourceprocessors/VolatilityProcessor.java +++ b/Core/src/org/sleuthkit/autopsy/datasourceprocessors/VolatilityProcessor.java @@ -1,7 +1,20 @@ /* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. + * Autopsy + * + * Copyright 2018 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.sleuthkit.autopsy.datasourceprocessors; @@ -31,10 +44,8 @@ import org.sleuthkit.autopsy.ingest.ModuleDataEvent; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; -import org.sleuthkit.datamodel.Content; -import org.sleuthkit.datamodel.DerivedFile; +import org.sleuthkit.datamodel.Image; import org.sleuthkit.datamodel.TskCoreException; -import org.sleuthkit.datamodel.TskData; //@NbBundle.Messages({ // "VolatilityProcessor.PermissionsNotSufficient=Insufficient permissions accessing", @@ -47,33 +58,25 @@ import org.sleuthkit.datamodel.TskData; /** * - * @author mark */ -public class VolatilityProcessor implements Runnable{ +class VolatilityProcessor implements Runnable{ private static final String VOLATILITY_DIRECTORY = "Volatility"; //NON-NLS private static final String VOLATILITY_EXECUTABLE = "volatility_2.6_win64_standalone.exe"; //NON-NLS - private static final String TEMP_DIR_NAME = "temp"; // NON-NLS - private final String MemoryImage; + private final String memoryImagePath; private final List PluginsToRun; - private final String deviceId; - // private final Content dataSource; - //private final DataSourceProcessorProgressMonitor progressMonitor; + private final Image dataSource; private static final String SEP = System.getProperty("line.separator"); private static final Logger logger = Logger.getLogger(VolatilityProcessor.class.getName()); - private static Object Bundle; private String moduleOutputPath; private File executableFile; - private final Boolean isFile = true; private final IngestServices services = IngestServices.getInstance(); + private final DataSourceProcessorProgressMonitor progressMonitor; - public VolatilityProcessor(String ImagePath, List PlugInToRuns, String deviceId) { -// public VolatilityProcessor(String ImagePath, List PlugInToRuns, String deviceId, DataSourceProcessorProgressMonitor progressMonitor) { -// public VolatilityProcessor(String ImagePath) { - this.MemoryImage = ImagePath; + public VolatilityProcessor(String ImagePath, List PlugInToRuns, Image dataSource, DataSourceProcessorProgressMonitor progressMonitor) { + this.memoryImagePath = ImagePath; this.PluginsToRun = PlugInToRuns; - this.deviceId = deviceId; -// this.dataSource = dataSource; - //this.progressMonitor = progressMonitor; + this.dataSource = dataSource; + this.progressMonitor = progressMonitor; } @Override @@ -84,31 +87,42 @@ public class VolatilityProcessor implements Runnable{ final Case currentCase = Case.getCurrentCase(); final FileManager fileManager = currentCase.getServices().getFileManager(); - moduleOutputPath = currentCase.getModulesOutputDirAbsPath() + File.separator + "Volatility"; - + // make a unique folder for this image + moduleOutputPath = currentCase.getModulesOutputDirAbsPath() + File.separator + "Volatility" + File.separator + dataSource.getId(); File directory = new File(String.valueOf(moduleOutputPath)); if(!directory.exists()){ - directory.mkdir(); - executeVolatility(executableFile, MemoryImage, "", "imageinfo", "", fileManager); + directory.mkdirs(); + progressMonitor.setProgressText("Running imageinfo"); + executeVolatility(executableFile, memoryImagePath, "", "imageinfo", fileManager); } - PluginsToRun.forEach((pluginToRun) -> { - executeVolatility(executableFile, MemoryImage, "", pluginToRun, "", fileManager); - }); + progressMonitor.setIndeterminate(false); + for (int i = 0; i < PluginsToRun.size(); i++) { + String pluginToRun = PluginsToRun.get(i); + progressMonitor.setProgressText("Processing " + pluginToRun + " module"); + executeVolatility(executableFile, memoryImagePath, "", pluginToRun, fileManager); + progressMonitor.setProgress(i / PluginsToRun.size() * 100); + } + // @@@ NEed to report back here if there were errors } - private void executeVolatility(File VolatilityPath, String MemoryImage, String OutputPath, String PluginToRun, String MemoryProfile, FileManager fileManager) { - try { - + private void executeVolatility(File VolatilityPath, String MemoryImage, String OutputPath, String PluginToRun, FileManager fileManager) { + try { List commandLine = new ArrayList<>(); commandLine.add("\"" + VolatilityPath + "\""); File memoryImage = new File(MemoryImage); commandLine.add("--filename=" + memoryImage.getName()); //NON-NLS - File memoryProfile = new File(moduleOutputPath + "\\imageinfo.txt"); - if (memoryProfile.exists()) { - MemoryProfile = parseProfile(memoryProfile); - commandLine.add("--profile=" + MemoryProfile); + + File imageInfoOutputFile = new File(moduleOutputPath + "\\imageinfo.txt"); + if (imageInfoOutputFile.exists()) { + String memoryProfile = parseImageInfoOutput(imageInfoOutputFile); + if (memoryProfile == null) { + // @@@ LOG THIS + return; + } + commandLine.add("--profile=" + memoryProfile); } + commandLine.add(PluginToRun); //NON-NLS ProcessBuilder processBuilder = new ProcessBuilder(commandLine); @@ -119,12 +133,12 @@ public class VolatilityProcessor implements Runnable{ processBuilder.directory(new File(memoryImage.getParent())); int exitVal = ExecUtil.execute(processBuilder); -// int exitVal = 0; - if (exitVal == 0) { - ScanOutputFile(fileManager, PluginToRun, new File(moduleOutputPath + "\\" + PluginToRun + ".txt")); - } else { - logger.log(Level.INFO, "Exit Value is ", exitVal); + if (exitVal != 0) { + logger.log(Level.SEVERE, "Volatility non-0 exit value for module: " + PluginToRun); + return; } + scanOutputFile(fileManager, PluginToRun, new File(moduleOutputPath + "\\" + PluginToRun + ".txt")); + } catch (Exception ex) { logger.log(Level.SEVERE, "Unable to run Volatility", ex); //NON-NLS //this.addErrorMessage(NbBundle.getMessage(this.getClass(), "ExtractRegistry.execRegRip.errMsg.failedAnalyzeRegFile", this.getName())); @@ -159,7 +173,7 @@ public class VolatilityProcessor implements Runnable{ return exeFile; } - private String parseProfile(File memoryProfile) throws FileNotFoundException { + private String parseImageInfoOutput(File memoryProfile) throws FileNotFoundException { // create a Buffered Reader object instance with a FileReader try ( BufferedReader br = new BufferedReader(new FileReader(memoryProfile))) { @@ -169,14 +183,15 @@ public class VolatilityProcessor implements Runnable{ String[] profileLine = fileRead.split(":"); String[] memProfile = profileLine[1].split(",|\\("); return memProfile[0].replaceAll("\\s+",""); - } catch (IOException ex) { - Exceptions.printStackTrace(ex); - } + } catch (IOException ex) { + Exceptions.printStackTrace(ex); + // @@@ Need to log this or rethrow it + } return null; } - private void ScanOutputFile(FileManager fileManager, String pluginName, File PluginOutput) { + private void scanOutputFile(FileManager fileManager, String pluginName, File PluginOutput) { List fileNames = new ArrayList<>(); Blackboard blackboard = Case.getCurrentCase().getServices().getBlackboard(); @@ -273,11 +288,11 @@ public class VolatilityProcessor implements Runnable{ } } br.close(); - } catch (IOException ex) { + } catch (IOException ex) { + // @@@ NEed to log or rethrow Exceptions.printStackTrace(ex); } return fileNames; } - }