Added cancelation

This commit is contained in:
Brian Carrier 2018-02-28 22:22:54 -05:00
parent a6fe670ab0
commit d801be4e5d
3 changed files with 56 additions and 29 deletions

View File

@ -1,5 +1,3 @@
package org.sleuthkit.autopsy.datasourceprocessors;
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
@ -18,7 +16,7 @@ package org.sleuthkit.autopsy.datasourceprocessors;
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.sleuthkit.autopsy.datasourceprocessors;
import java.io.File; import java.io.File;
import java.nio.file.Paths; import java.nio.file.Paths;
@ -48,6 +46,8 @@ final class AddMemoryImageTask implements Runnable {
private final DataSourceProcessorCallback callback; private final DataSourceProcessorCallback callback;
private boolean criticalErrorOccurred; private boolean criticalErrorOccurred;
private static final long TWO_GB = 2000000000L; 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. * 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. Image dataSource = caseDatabase.addImageInfo(0, imageFilePaths, timeZone); //TODO: change hard coded deviceId.
dataSources.add(dataSource); dataSources.add(dataSource);
if (isCancelled)
return;
/* call Volatility to process the image **/ /* call Volatility to process the image **/
VolatilityProcessor vp = new VolatilityProcessor(imageFilePath, PluginsToRun, dataSource, progressMonitor); volatilityProcessor = new VolatilityProcessor(imageFilePath, PluginsToRun, dataSource, progressMonitor);
vp.run(); volatilityProcessor.run();
} catch (TskCoreException ex) { } catch (TskCoreException ex) {
errorMessages.add(Bundle.AddMemoryImageTask_image_critical_error_adding() + imageFilePaths + Bundle.AddMemoryImageTask_for_device() + deviceId + ":" + ex.getLocalizedMessage()); 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(); caseDatabase.releaseExclusiveLock();
} }
} }
void cancelTask() {
if (volatilityProcessor != null) {
volatilityProcessor.cancel();
}
isCancelled = true;
}
} }

View File

@ -37,7 +37,7 @@ import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
public class MemoryDSProcessor implements DataSourceProcessor { public class MemoryDSProcessor implements DataSourceProcessor {
private final MemoryDSInputPanel configPanel; private final MemoryDSInputPanel configPanel;
private AddMemoryImageTask addImageTask; private AddMemoryImageTask addImageTask = null;
/* /*
* Constructs a Memory data source processor that implements the * Constructs a Memory data source processor that implements the
@ -150,6 +150,9 @@ public class MemoryDSProcessor implements DataSourceProcessor {
@Override @Override
public void cancel() { public void cancel() {
if (addImageTask != null) {
addImageTask.cancelTask();
}
} }
/** /**

View File

@ -71,6 +71,8 @@ class VolatilityProcessor implements Runnable{
private File executableFile; private File executableFile;
private final IngestServices services = IngestServices.getInstance(); private final IngestServices services = IngestServices.getInstance();
private final DataSourceProcessorProgressMonitor progressMonitor; private final DataSourceProcessorProgressMonitor progressMonitor;
private boolean isCancelled;
private FileManager fileManager;
public VolatilityProcessor(String ImagePath, List<String> PlugInToRuns, Image dataSource, DataSourceProcessorProgressMonitor progressMonitor) { public VolatilityProcessor(String ImagePath, List<String> PlugInToRuns, Image dataSource, DataSourceProcessorProgressMonitor progressMonitor) {
this.memoryImagePath = ImagePath; this.memoryImagePath = ImagePath;
@ -80,12 +82,15 @@ class VolatilityProcessor implements Runnable{
} }
@Override @Override
public void run() { public void run() {
Path execName = Paths.get(VOLATILITY_DIRECTORY, VOLATILITY_EXECUTABLE); Path execName = Paths.get(VOLATILITY_DIRECTORY, VOLATILITY_EXECUTABLE);
executableFile = locateExecutable(execName.toString()); executableFile = locateExecutable(execName.toString());
if (executableFile == null) {
logger.log(Level.SEVERE, "Volatility exe not found");
return;
}
final Case currentCase = Case.getCurrentCase(); final Case currentCase = Case.getCurrentCase();
final FileManager fileManager = currentCase.getServices().getFileManager(); fileManager = currentCase.getServices().getFileManager();
// make a unique folder for this image // make a unique folder for this image
moduleOutputPath = currentCase.getModulesOutputDirAbsPath() + File.separator + "Volatility" + File.separator + dataSource.getId(); moduleOutputPath = currentCase.getModulesOutputDirAbsPath() + File.separator + "Volatility" + File.separator + dataSource.getId();
@ -93,24 +98,26 @@ class VolatilityProcessor implements Runnable{
if(!directory.exists()){ if(!directory.exists()){
directory.mkdirs(); directory.mkdirs();
progressMonitor.setProgressText("Running imageinfo"); progressMonitor.setProgressText("Running imageinfo");
executeVolatility(executableFile, memoryImagePath, "", "imageinfo", fileManager); executeVolatility("imageinfo");
} }
progressMonitor.setIndeterminate(false); progressMonitor.setIndeterminate(false);
for (int i = 0; i < PluginsToRun.size(); i++) { for (int i = 0; i < PluginsToRun.size(); i++) {
if (isCancelled)
break;
String pluginToRun = PluginsToRun.get(i); String pluginToRun = PluginsToRun.get(i);
progressMonitor.setProgressText("Processing " + pluginToRun + " module"); progressMonitor.setProgressText("Processing " + pluginToRun + " module");
executeVolatility(executableFile, memoryImagePath, "", pluginToRun, fileManager); executeVolatility(pluginToRun);
progressMonitor.setProgress(i / PluginsToRun.size() * 100); progressMonitor.setProgress(i / PluginsToRun.size() * 100);
} }
// @@@ NEed to report back here if there were errors // @@@ 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 { try {
List<String> commandLine = new ArrayList<>(); List<String> commandLine = new ArrayList<>();
commandLine.add("\"" + VolatilityPath + "\""); commandLine.add("\"" + executableFile + "\"");
File memoryImage = new File(MemoryImage); File memoryImage = new File(memoryImagePath);
commandLine.add("--filename=" + memoryImage.getName()); //NON-NLS commandLine.add("--filename=" + memoryImage.getName()); //NON-NLS
File imageInfoOutputFile = new File(moduleOutputPath + "\\imageinfo.txt"); File imageInfoOutputFile = new File(moduleOutputPath + "\\imageinfo.txt");
@ -123,21 +130,25 @@ class VolatilityProcessor implements Runnable{
commandLine.add("--profile=" + memoryProfile); commandLine.add("--profile=" + memoryProfile);
} }
commandLine.add(PluginToRun); //NON-NLS commandLine.add(pluginToRun); //NON-NLS
ProcessBuilder processBuilder = new ProcessBuilder(commandLine); ProcessBuilder processBuilder = new ProcessBuilder(commandLine);
// Add environment variable to force Volatility to run with the same permissions Autopsy uses // Add environment variable to force Volatility to run with the same permissions Autopsy uses
processBuilder.environment().put("__COMPAT_LAYER", "RunAsInvoker"); //NON-NLS 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.redirectError(new File(moduleOutputPath + "\\Volatility_Run.err"));
processBuilder.directory(new File(memoryImage.getParent())); processBuilder.directory(new File(memoryImage.getParent()));
int exitVal = ExecUtil.execute(processBuilder); int exitVal = ExecUtil.execute(processBuilder);
if (exitVal != 0) { 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; return;
} }
scanOutputFile(fileManager, PluginToRun, new File(moduleOutputPath + "\\" + PluginToRun + ".txt"));
if (isCancelled)
return;
scanOutputFile(pluginToRun, new File(moduleOutputPath + "\\" + pluginToRun + ".txt"));
} catch (Exception ex) { } catch (Exception ex) {
logger.log(Level.SEVERE, "Unable to run Volatility", ex); //NON-NLS 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 * @param executableToFindName The name of the executable to find
* *
* @return A File reference or throws an exception * @return A File reference or null
*
* @throws IngestModuleException
*/ */
// public static File locateExecutable(String executableToFindName) throws IngestModule.IngestModuleException { private static File locateExecutable(String executableToFindName) {
public static File locateExecutable(String executableToFindName) {
// Must be running under a Windows operating system. // Must be running under a Windows operating system.
if (!PlatformUtil.isWindowsOS()) { if (!PlatformUtil.isWindowsOS()) {
// throw new IngestModule.IngestModuleException(Bundle.unsupportedOS_message()); return null;
} }
File exeFile = InstalledFileLocator.getDefault().locate(executableToFindName, VolatilityProcessor.class.getPackage().getName(), false); File exeFile = InstalledFileLocator.getDefault().locate(executableToFindName, VolatilityProcessor.class.getPackage().getName(), false);
if (null == exeFile) { if (null == exeFile) {
//throw new IngestModule.IngestModuleException(Bundle.missingExecutable_message()); return null;
} }
if (!exeFile.canExecute()) { if (!exeFile.canExecute()) {
//throw new IngestModule.IngestModuleException(Bundle.cannotRunExecutable_message()); return null;
} }
return exeFile; 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 // create a Buffered Reader object instance with a FileReader
try ( try (
BufferedReader br = new BufferedReader(new FileReader(memoryProfile))) { BufferedReader br = new BufferedReader(new FileReader(imageOutputFile))) {
// read the first line from the text file // read the first line from the text file
String fileRead = br.readLine(); String fileRead = br.readLine();
br.close(); br.close();
@ -191,7 +199,7 @@ class VolatilityProcessor implements Runnable{
return null; return null;
} }
private void scanOutputFile(FileManager fileManager, String pluginName, File PluginOutput) { private void scanOutputFile(String pluginName, File PluginOutput) {
List<String> fileNames = new ArrayList<>(); List<String> fileNames = new ArrayList<>();
Blackboard blackboard = Case.getCurrentCase().getServices().getBlackboard(); Blackboard blackboard = Case.getCurrentCase().getServices().getBlackboard();
@ -204,6 +212,9 @@ class VolatilityProcessor implements Runnable{
} }
try { try {
fileNames.forEach((String fileName) -> { fileNames.forEach((String fileName) -> {
if (isCancelled)
return;
List<AbstractFile> volFiles = new ArrayList<>(); List<AbstractFile> volFiles = new ArrayList<>();
File volfile = new File(fileName); File volfile = new File(fileName);
String filename = volfile.getName(); String filename = volfile.getName();
@ -295,4 +306,8 @@ class VolatilityProcessor implements Runnable{
return fileNames; return fileNames;
} }
void cancel() {
isCancelled = true;
}
} }