From d801be4e5db0a94c4870e27fb802c5c0dc83a3b9 Mon Sep 17 00:00:00 2001 From: Brian Carrier Date: Wed, 28 Feb 2018 22:22:54 -0500 Subject: [PATCH] Added cancelation --- .../AddMemoryImageTask.java | 19 ++++-- .../MemoryDSProcessor.java | 5 +- .../VolatilityProcessor.java | 61 ++++++++++++------- 3 files changed, 56 insertions(+), 29 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datasourceprocessors/AddMemoryImageTask.java b/Core/src/org/sleuthkit/autopsy/datasourceprocessors/AddMemoryImageTask.java index a0a951def7..fc1d53eaa9 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourceprocessors/AddMemoryImageTask.java +++ b/Core/src/org/sleuthkit/autopsy/datasourceprocessors/AddMemoryImageTask.java @@ -1,5 +1,3 @@ -package org.sleuthkit.autopsy.datasourceprocessors; - /* * Autopsy Forensic Browser * @@ -18,7 +16,7 @@ package org.sleuthkit.autopsy.datasourceprocessors; * See the License for the specific language governing permissions and * limitations under the License. */ - +package org.sleuthkit.autopsy.datasourceprocessors; import java.io.File; import java.nio.file.Paths; @@ -48,6 +46,8 @@ final class AddMemoryImageTask implements Runnable { private final DataSourceProcessorCallback callback; private boolean criticalErrorOccurred; private static final long TWO_GB = 2000000000L; + private boolean isCancelled = false; + private VolatilityProcessor volatilityProcessor = null; /** * Constructs a runnable that adds a raw data source to a case database. @@ -142,10 +142,12 @@ final class AddMemoryImageTask implements Runnable { */ Image dataSource = caseDatabase.addImageInfo(0, imageFilePaths, timeZone); //TODO: change hard coded deviceId. dataSources.add(dataSource); + if (isCancelled) + return; /* call Volatility to process the image **/ - VolatilityProcessor vp = new VolatilityProcessor(imageFilePath, PluginsToRun, dataSource, progressMonitor); - vp.run(); + volatilityProcessor = new VolatilityProcessor(imageFilePath, PluginsToRun, dataSource, progressMonitor); + volatilityProcessor.run(); } catch (TskCoreException ex) { errorMessages.add(Bundle.AddMemoryImageTask_image_critical_error_adding() + imageFilePaths + Bundle.AddMemoryImageTask_for_device() + deviceId + ":" + ex.getLocalizedMessage()); @@ -154,4 +156,11 @@ final class AddMemoryImageTask implements Runnable { caseDatabase.releaseExclusiveLock(); } } + + void cancelTask() { + if (volatilityProcessor != null) { + volatilityProcessor.cancel(); + } + isCancelled = true; + } } diff --git a/Core/src/org/sleuthkit/autopsy/datasourceprocessors/MemoryDSProcessor.java b/Core/src/org/sleuthkit/autopsy/datasourceprocessors/MemoryDSProcessor.java index ce0d2e1c34..de1baea13b 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourceprocessors/MemoryDSProcessor.java +++ b/Core/src/org/sleuthkit/autopsy/datasourceprocessors/MemoryDSProcessor.java @@ -37,7 +37,7 @@ import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor; public class MemoryDSProcessor implements DataSourceProcessor { private final MemoryDSInputPanel configPanel; - private AddMemoryImageTask addImageTask; + private AddMemoryImageTask addImageTask = null; /* * Constructs a Memory data source processor that implements the @@ -150,6 +150,9 @@ public class MemoryDSProcessor implements DataSourceProcessor { @Override public void cancel() { + if (addImageTask != null) { + addImageTask.cancelTask(); + } } /** diff --git a/Core/src/org/sleuthkit/autopsy/datasourceprocessors/VolatilityProcessor.java b/Core/src/org/sleuthkit/autopsy/datasourceprocessors/VolatilityProcessor.java index b1cdc4dd2a..746e793021 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourceprocessors/VolatilityProcessor.java +++ b/Core/src/org/sleuthkit/autopsy/datasourceprocessors/VolatilityProcessor.java @@ -71,6 +71,8 @@ class VolatilityProcessor implements Runnable{ private File executableFile; private final IngestServices services = IngestServices.getInstance(); private final DataSourceProcessorProgressMonitor progressMonitor; + private boolean isCancelled; + private FileManager fileManager; public VolatilityProcessor(String ImagePath, List PlugInToRuns, Image dataSource, DataSourceProcessorProgressMonitor progressMonitor) { this.memoryImagePath = ImagePath; @@ -80,12 +82,15 @@ class VolatilityProcessor implements Runnable{ } @Override - public void run() { - + public void run() { Path execName = Paths.get(VOLATILITY_DIRECTORY, VOLATILITY_EXECUTABLE); executableFile = locateExecutable(execName.toString()); + if (executableFile == null) { + logger.log(Level.SEVERE, "Volatility exe not found"); + return; + } final Case currentCase = Case.getCurrentCase(); - final FileManager fileManager = currentCase.getServices().getFileManager(); + fileManager = currentCase.getServices().getFileManager(); // make a unique folder for this image moduleOutputPath = currentCase.getModulesOutputDirAbsPath() + File.separator + "Volatility" + File.separator + dataSource.getId(); @@ -93,24 +98,26 @@ class VolatilityProcessor implements Runnable{ if(!directory.exists()){ directory.mkdirs(); progressMonitor.setProgressText("Running imageinfo"); - executeVolatility(executableFile, memoryImagePath, "", "imageinfo", fileManager); + executeVolatility("imageinfo"); } progressMonitor.setIndeterminate(false); for (int i = 0; i < PluginsToRun.size(); i++) { + if (isCancelled) + break; String pluginToRun = PluginsToRun.get(i); progressMonitor.setProgressText("Processing " + pluginToRun + " module"); - executeVolatility(executableFile, memoryImagePath, "", pluginToRun, fileManager); + executeVolatility(pluginToRun); 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, FileManager fileManager) { + private void executeVolatility(String pluginToRun) { try { List commandLine = new ArrayList<>(); - commandLine.add("\"" + VolatilityPath + "\""); - File memoryImage = new File(MemoryImage); + commandLine.add("\"" + executableFile + "\""); + File memoryImage = new File(memoryImagePath); commandLine.add("--filename=" + memoryImage.getName()); //NON-NLS File imageInfoOutputFile = new File(moduleOutputPath + "\\imageinfo.txt"); @@ -123,21 +130,25 @@ class VolatilityProcessor implements Runnable{ commandLine.add("--profile=" + memoryProfile); } - commandLine.add(PluginToRun); //NON-NLS + commandLine.add(pluginToRun); //NON-NLS ProcessBuilder processBuilder = new ProcessBuilder(commandLine); // Add environment variable to force Volatility to run with the same permissions Autopsy uses processBuilder.environment().put("__COMPAT_LAYER", "RunAsInvoker"); //NON-NLS - processBuilder.redirectOutput(new File(moduleOutputPath + "\\" + PluginToRun + ".txt")); + processBuilder.redirectOutput(new File(moduleOutputPath + "\\" + pluginToRun + ".txt")); processBuilder.redirectError(new File(moduleOutputPath + "\\Volatility_Run.err")); processBuilder.directory(new File(memoryImage.getParent())); int exitVal = ExecUtil.execute(processBuilder); if (exitVal != 0) { - logger.log(Level.SEVERE, "Volatility non-0 exit value for module: " + PluginToRun); + logger.log(Level.SEVERE, "Volatility non-0 exit value for module: " + pluginToRun); return; } - scanOutputFile(fileManager, PluginToRun, new File(moduleOutputPath + "\\" + PluginToRun + ".txt")); + + if (isCancelled) + return; + + scanOutputFile(pluginToRun, new File(moduleOutputPath + "\\" + pluginToRun + ".txt")); } catch (Exception ex) { logger.log(Level.SEVERE, "Unable to run Volatility", ex); //NON-NLS @@ -150,33 +161,30 @@ class VolatilityProcessor implements Runnable{ * * @param executableToFindName The name of the executable to find * - * @return A File reference or throws an exception - * - * @throws IngestModuleException + * @return A File reference or null */ -// public static File locateExecutable(String executableToFindName) throws IngestModule.IngestModuleException { - public static File locateExecutable(String executableToFindName) { + private static File locateExecutable(String executableToFindName) { // Must be running under a Windows operating system. if (!PlatformUtil.isWindowsOS()) { - // throw new IngestModule.IngestModuleException(Bundle.unsupportedOS_message()); + return null; } File exeFile = InstalledFileLocator.getDefault().locate(executableToFindName, VolatilityProcessor.class.getPackage().getName(), false); if (null == exeFile) { - //throw new IngestModule.IngestModuleException(Bundle.missingExecutable_message()); + return null; } if (!exeFile.canExecute()) { - //throw new IngestModule.IngestModuleException(Bundle.cannotRunExecutable_message()); + return null; } return exeFile; } - private String parseImageInfoOutput(File memoryProfile) throws FileNotFoundException { + private String parseImageInfoOutput(File imageOutputFile) throws FileNotFoundException { // create a Buffered Reader object instance with a FileReader try ( - BufferedReader br = new BufferedReader(new FileReader(memoryProfile))) { + BufferedReader br = new BufferedReader(new FileReader(imageOutputFile))) { // read the first line from the text file String fileRead = br.readLine(); br.close(); @@ -191,7 +199,7 @@ class VolatilityProcessor implements Runnable{ return null; } - private void scanOutputFile(FileManager fileManager, String pluginName, File PluginOutput) { + private void scanOutputFile(String pluginName, File PluginOutput) { List fileNames = new ArrayList<>(); Blackboard blackboard = Case.getCurrentCase().getServices().getBlackboard(); @@ -204,6 +212,9 @@ class VolatilityProcessor implements Runnable{ } try { fileNames.forEach((String fileName) -> { + if (isCancelled) + return; + List volFiles = new ArrayList<>(); File volfile = new File(fileName); String filename = volfile.getName(); @@ -295,4 +306,8 @@ class VolatilityProcessor implements Runnable{ return fileNames; } + + void cancel() { + isCancelled = true; + } }