mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-17 02:07:42 +00:00
This commit is contained in:
commit
7c655956e3
@ -20,6 +20,10 @@ needed even if you have a 64-bit system).
|
||||
Note: Netbeans IDE is not required to build and run Autopsy,
|
||||
but it is a recommended IDE to use for development of Autopsy modules.
|
||||
|
||||
1d) (opetional) If you are going to package Autopsy, then you'll also
|
||||
need to set JRE_HOME to the root JRE directory.
|
||||
|
||||
|
||||
|
||||
2) Get Sleuth Kit Setup
|
||||
2a) Download and build the release version of Libewf2 (20120304 or
|
||||
|
@ -53,6 +53,7 @@ final class AddImageVisualPanel2 extends JPanel {
|
||||
infoPanel.add(progressLabel);
|
||||
infoPanel.add(Box.createRigidArea(new Dimension(10, 10))); //spacer
|
||||
this.jScrollPane1.setBorder(null);
|
||||
this.TextArea_CurrentDirectory.setBackground(this.getBackground());
|
||||
}
|
||||
|
||||
void resetInfoPanel() {
|
||||
@ -108,7 +109,15 @@ final class AddImageVisualPanel2 extends JPanel {
|
||||
* @param dir the text to update with
|
||||
*/
|
||||
public void changeCurrentDir(String dir){
|
||||
this.TextArea_CurrentDirectory.setText(dir.trim().isEmpty() ? "Folder Information Unavailable" : dir);
|
||||
this.TextArea_CurrentDirectory.setText(dir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the CurrentlyProcessing tag and text area to be invisible
|
||||
*/
|
||||
public void setProcessInvis(){
|
||||
this.Label_CurrentDirectory_Static.setVisible(false);
|
||||
this.TextArea_CurrentDirectory.setVisible(false);
|
||||
}
|
||||
|
||||
|
||||
|
@ -41,8 +41,8 @@ import org.sleuthkit.datamodel.TskDataException;
|
||||
import org.sleuthkit.datamodel.TskException;
|
||||
|
||||
/**
|
||||
* The "Add Image" wizard panel3. Presents the
|
||||
* options to finish/cancel image-add and run ingest.
|
||||
* The "Add Image" wizard panel3. Presents the options to finish/cancel
|
||||
* image-add and run ingest.
|
||||
*/
|
||||
class AddImageWizardPanel3 implements WizardDescriptor.Panel<WizardDescriptor> {
|
||||
|
||||
@ -53,10 +53,9 @@ class AddImageWizardPanel3 implements WizardDescriptor.Panel<WizardDescriptor> {
|
||||
* component from this class, just use getComponent().
|
||||
*/
|
||||
private Component component = null;
|
||||
private Image newImage = null;
|
||||
private volatile Image newImage = null;
|
||||
private boolean ingested = false;
|
||||
private boolean readyToIngest = false;
|
||||
|
||||
// the paths of the image files to be added
|
||||
private String imgPath;
|
||||
// the time zone where the image is added
|
||||
@ -67,13 +66,12 @@ class AddImageWizardPanel3 implements WizardDescriptor.Panel<WizardDescriptor> {
|
||||
private AddImageAction.CleanupTask cleanupImage; // initialized to null in readSettings()
|
||||
// flag to control the availiablity of next action
|
||||
private boolean imgAdded; // initalized to false in readSettings()
|
||||
|
||||
private CurrentDirectoryFetcher fetcher;
|
||||
private AddImageProcess process;
|
||||
private AddImageAction action;
|
||||
private AddImgTask addImageTask;
|
||||
private AddImageWizardPanel2 wizPanel;
|
||||
|
||||
|
||||
AddImageWizardPanel3(AddImageAction action, AddImageWizardPanel2 wizPanel) {
|
||||
this.action = action;
|
||||
this.wizPanel = wizPanel;
|
||||
@ -85,7 +83,7 @@ class AddImageWizardPanel3 implements WizardDescriptor.Panel<WizardDescriptor> {
|
||||
* but never displayed, or not all panels are displayed, it is better to
|
||||
* create only those which really need to be visible.
|
||||
*
|
||||
* @return component the UI component of this wizard panel
|
||||
* @return component the UI component of this wizard panel
|
||||
*/
|
||||
@Override
|
||||
public Component getComponent() {
|
||||
@ -99,7 +97,7 @@ class AddImageWizardPanel3 implements WizardDescriptor.Panel<WizardDescriptor> {
|
||||
* Help for this panel. When the panel is active, this is used as the help
|
||||
* for the wizard dialog.
|
||||
*
|
||||
* @return HelpCtx.DEFAULT_HELP the help for this panel
|
||||
* @return HelpCtx.DEFAULT_HELP the help for this panel
|
||||
*/
|
||||
@Override
|
||||
public HelpCtx getHelp() {
|
||||
@ -113,7 +111,7 @@ class AddImageWizardPanel3 implements WizardDescriptor.Panel<WizardDescriptor> {
|
||||
* Tests whether the panel is finished. If the panel is valid, the "Finish"
|
||||
* button will be enabled.
|
||||
*
|
||||
* @return true the finish button should be always enabled at this point
|
||||
* @return true the finish button should be always enabled at this point
|
||||
*/
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
@ -129,7 +127,7 @@ class AddImageWizardPanel3 implements WizardDescriptor.Panel<WizardDescriptor> {
|
||||
/**
|
||||
* Adds a listener to changes of the panel's validity.
|
||||
*
|
||||
* @param l the change listener to add
|
||||
* @param l the change listener to add
|
||||
*/
|
||||
@Override
|
||||
public final void addChangeListener(ChangeListener l) {
|
||||
@ -138,7 +136,7 @@ class AddImageWizardPanel3 implements WizardDescriptor.Panel<WizardDescriptor> {
|
||||
/**
|
||||
* Removes a listener to changes of the panel's validity.
|
||||
*
|
||||
* @param l the change listener to move
|
||||
* @param l the change listener to move
|
||||
*/
|
||||
@Override
|
||||
public final void removeChangeListener(ChangeListener l) {
|
||||
@ -154,7 +152,7 @@ class AddImageWizardPanel3 implements WizardDescriptor.Panel<WizardDescriptor> {
|
||||
* buttons. This method can be called multiple times on one instance of
|
||||
* WizardDescriptor.Panel.
|
||||
*
|
||||
* @param settings the setting to be read from
|
||||
* @param settings the setting to be read from
|
||||
*/
|
||||
@Override
|
||||
public void readSettings(WizardDescriptor settings) {
|
||||
@ -164,19 +162,19 @@ class AddImageWizardPanel3 implements WizardDescriptor.Panel<WizardDescriptor> {
|
||||
imgPath = (String) settings.getProperty(AddImageAction.IMGPATH_PROP);
|
||||
timeZone = settings.getProperty(AddImageAction.TIMEZONE_PROP).toString();
|
||||
noFatOrphans = ((Boolean) settings.getProperty(AddImageAction.NOFATORPHANS_PROP)).booleanValue();
|
||||
|
||||
|
||||
addImageTask = new AddImgTask(settings);
|
||||
addImageTask.execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the wizard panel with the opportunity to update the settings
|
||||
* with its current customized state. Rather than updating its settings
|
||||
* with every change in the GUI, it should collect them, and then only save
|
||||
* them when requested to by this method. This method can be called multiple
|
||||
* with its current customized state. Rather than updating its settings with
|
||||
* every change in the GUI, it should collect them, and then only save them
|
||||
* when requested to by this method. This method can be called multiple
|
||||
* times on one instance of WizardDescriptor.Panel.
|
||||
*
|
||||
* @param settings the setting to be stored to
|
||||
* @param settings the setting to be stored to
|
||||
*/
|
||||
@Override
|
||||
public void storeSettings(WizardDescriptor settings) {
|
||||
@ -186,10 +184,10 @@ class AddImageWizardPanel3 implements WizardDescriptor.Panel<WizardDescriptor> {
|
||||
readyToIngest = true;
|
||||
startIngest();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Start ingest after verifying we have a new image, we are
|
||||
* ready to ingest, and we haven't already ingested.
|
||||
* Start ingest after verifying we have a new image, we are ready to ingest,
|
||||
* and we haven't already ingested.
|
||||
*/
|
||||
private void startIngest() {
|
||||
if (newImage != null && readyToIngest && !ingested) {
|
||||
@ -199,47 +197,58 @@ class AddImageWizardPanel3 implements WizardDescriptor.Panel<WizardDescriptor> {
|
||||
wizPanel.getComponent().appendProgressText(" Ingest started.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
* Class for getting the currently processing directory.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
private class CurrentDirectoryFetcher extends SwingWorker<Integer,Integer> {
|
||||
private static class CurrentDirectoryFetcher extends SwingWorker<Integer,Integer> {
|
||||
AddImgTask task;
|
||||
JProgressBar prog;
|
||||
AddImageVisualPanel2 wiz;
|
||||
AddImageProcess proc;
|
||||
|
||||
CurrentDirectoryFetcher(AddImgTask task){
|
||||
this.task = task;
|
||||
CurrentDirectoryFetcher(JProgressBar prog, AddImageVisualPanel2 wiz, AddImageProcess proc){
|
||||
this.wiz = wiz;
|
||||
this.proc = proc;
|
||||
this.prog = prog;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the currently processing directory
|
||||
*/
|
||||
@Override
|
||||
protected Integer doInBackground(){
|
||||
try{
|
||||
while(task.progressBar.getValue() < 100 || task.progressBar.isIndeterminate()){
|
||||
while(prog.getValue() < 100 || prog.isIndeterminate()){ //TODO Rely on state variable in AddImgTask class
|
||||
|
||||
EventQueue.invokeLater(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
wizPanel.getComponent().changeCurrentDir(process.currentDirectory());
|
||||
public void run() {
|
||||
wiz.changeCurrentDir(proc.currentDirectory());
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
||||
Thread.sleep(2 * 1000);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
catch(InterruptedException ie){
|
||||
} catch (InterruptedException ie) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* When done, set the Wizards processing tags to be invisible
|
||||
*/
|
||||
@Override
|
||||
protected void done() {
|
||||
wiz.setProcessInvis();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Thread that will make the JNI call to ingest the image.
|
||||
*/
|
||||
@ -251,9 +260,9 @@ class AddImageWizardPanel3 implements WizardDescriptor.Panel<WizardDescriptor> {
|
||||
private boolean interrupted = false;
|
||||
private boolean hasCritError = false;
|
||||
private String errorString = null;
|
||||
|
||||
private long start;
|
||||
private WizardDescriptor settings;
|
||||
private Logger logger = Logger.getLogger(AddImgTask.class.getName());
|
||||
|
||||
protected AddImgTask(WizardDescriptor settings) {
|
||||
this.progressBar = wizPanel.getComponent().getCrDbProgressBar();
|
||||
@ -304,7 +313,7 @@ class AddImageWizardPanel3 implements WizardDescriptor.Panel<WizardDescriptor> {
|
||||
|
||||
|
||||
process = currentCase.makeAddImageProcess(timeZone, true, noFatOrphans);
|
||||
fetcher = new CurrentDirectoryFetcher(this);
|
||||
fetcher = new CurrentDirectoryFetcher(this.progressBar, wizPanel.getComponent(), process);
|
||||
cancelledWhileRunning.enable();
|
||||
try {
|
||||
wizPanel.setStateStarted();
|
||||
@ -321,15 +330,26 @@ class AddImageWizardPanel3 implements WizardDescriptor.Panel<WizardDescriptor> {
|
||||
} finally {
|
||||
// process is over, doesn't need to be dealt with if cancel happens
|
||||
cancelledWhileRunning.disable();
|
||||
|
||||
//enqueue what would be in done() to EDT thread
|
||||
EventQueue.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
postProcessImage();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
this.setProgress(100);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Commit the finished AddImageProcess, and cancel the CleanupTask that
|
||||
* would have reverted it.
|
||||
* @param settings property set to get AddImageProcess and CleanupTask from
|
||||
*
|
||||
* @param settings property set to get AddImageProcess and CleanupTask
|
||||
* from
|
||||
* @throws Exception if commit or adding the image to the case failed
|
||||
*/
|
||||
private void commitImage(WizardDescriptor settings) throws Exception {
|
||||
@ -341,11 +361,9 @@ class AddImageWizardPanel3 implements WizardDescriptor.Panel<WizardDescriptor> {
|
||||
long imageId = 0;
|
||||
try {
|
||||
imageId = process.commit();
|
||||
}
|
||||
catch (TskException e) {
|
||||
} catch (TskException e) {
|
||||
logger.log(Level.WARNING, "Errors occured while committing the image", e);
|
||||
}
|
||||
finally {
|
||||
} finally {
|
||||
//commit done, unlock db write in EWT thread
|
||||
//before doing anything else
|
||||
SleuthkitCase.dbWriteUnlock();
|
||||
@ -366,37 +384,28 @@ class AddImageWizardPanel3 implements WizardDescriptor.Panel<WizardDescriptor> {
|
||||
*
|
||||
* (called by EventDispatch Thread after doInBackground finishes)
|
||||
*/
|
||||
@Override
|
||||
protected void done() {
|
||||
protected void postProcessImage() {
|
||||
progressBar.setIndeterminate(false);
|
||||
setProgress(100);
|
||||
|
||||
// attempt actions that might fail and force the process to stop
|
||||
|
||||
try {
|
||||
//get() will block until doInBackground done and throw any exceptions
|
||||
//that were thrown in the background task
|
||||
//if process was stopped, stop should have been complete (otherwise, unsafe to revert() )
|
||||
get();
|
||||
logger.log(Level.INFO, "Adding image took " + (System.currentTimeMillis() - start) + " ms.");
|
||||
} catch (InterruptedException e) {
|
||||
} catch (ExecutionException e) {
|
||||
} finally {
|
||||
if (interrupted || hasCritError) {
|
||||
logger.log(Level.INFO, "Handling errors or interruption that occured in add image process");
|
||||
revert();
|
||||
if (hasCritError) {
|
||||
//core error
|
||||
wizPanel.getComponent().setErrors(errorString, true);
|
||||
}
|
||||
return;
|
||||
} else if (errorString != null) {
|
||||
//data error (non-critical)
|
||||
logger.log(Level.INFO, "Handling non-critical errors that occured in add image process");
|
||||
wizPanel.getComponent().setErrors(errorString, false);
|
||||
if (interrupted || hasCritError) {
|
||||
logger.log(Level.INFO, "Handling errors or interruption that occured in add image process");
|
||||
revert();
|
||||
if (hasCritError) {
|
||||
//core error
|
||||
wizPanel.getComponent().setErrors(errorString, true);
|
||||
}
|
||||
return;
|
||||
} else if (errorString != null) {
|
||||
//data error (non-critical)
|
||||
logger.log(Level.INFO, "Handling non-critical errors that occured in add image process");
|
||||
wizPanel.getComponent().setErrors(errorString, false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
try {
|
||||
// When everything happens without an error:
|
||||
|
||||
@ -427,10 +436,11 @@ class AddImageWizardPanel3 implements WizardDescriptor.Panel<WizardDescriptor> {
|
||||
|
||||
// Tell the panel we're done
|
||||
wizPanel.setStateFinished();
|
||||
|
||||
|
||||
// Commit the image
|
||||
if (newImage != null) //already commited
|
||||
{
|
||||
logger.log(Level.INFO, "Assuming image already committed, will not commit.");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -445,7 +455,7 @@ class AddImageWizardPanel3 implements WizardDescriptor.Panel<WizardDescriptor> {
|
||||
} else {
|
||||
logger.log(Level.SEVERE, "Missing image process object");
|
||||
}
|
||||
|
||||
|
||||
// Start ingest if we can
|
||||
startIngest();
|
||||
|
||||
@ -457,7 +467,7 @@ class AddImageWizardPanel3 implements WizardDescriptor.Panel<WizardDescriptor> {
|
||||
wizPanel.getComponent().changeProgressBarTextAndColor("*Failed to add image.", 0, Color.black); // set error message
|
||||
|
||||
// Log error/display warning
|
||||
Logger logger = Logger.getLogger(AddImgTask.class.getName());
|
||||
|
||||
logger.log(Level.SEVERE, "Error adding image to case", ex);
|
||||
} finally {
|
||||
}
|
||||
|
@ -173,11 +173,13 @@ public class Case {
|
||||
|
||||
String oldCaseName = oldCase != null ? oldCase.name : "";
|
||||
|
||||
doCaseChange(null); //closes windows, etc
|
||||
pcs.firePropertyChange(CASE_CURRENT_CASE, oldCase, null);
|
||||
doCaseChange(null);
|
||||
|
||||
|
||||
pcs.firePropertyChange(CASE_NAME, oldCaseName, "");
|
||||
doCaseNameChange("");
|
||||
pcs.firePropertyChange(CASE_NAME, oldCaseName, "");
|
||||
|
||||
|
||||
|
||||
|
||||
@ -827,14 +829,16 @@ public class Case {
|
||||
Case.runAddImageAction();
|
||||
}
|
||||
} else { // case is closed
|
||||
// close all top components first
|
||||
CoreComponentControl.closeCoreWindows();
|
||||
|
||||
// disable these menus
|
||||
CallableSystemAction.get(AddImageAction.class).setEnabled(false); // Add Image menu
|
||||
CallableSystemAction.get(CaseCloseAction.class).setEnabled(false); // Case Close menu
|
||||
CallableSystemAction.get(CasePropertiesAction.class).setEnabled(false); // Case Properties menu
|
||||
CallableSystemAction.get(CaseDeleteAction.class).setEnabled(false); // Delete Case menu
|
||||
|
||||
// close all top components
|
||||
CoreComponentControl.closeCoreWindows();
|
||||
|
||||
|
||||
Frame f = WindowManager.getDefault().getMainWindow();
|
||||
f.setTitle(Case.getAppName()); // set the window name to just application name
|
||||
|
@ -6,9 +6,9 @@
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
|
||||
<!-- definition of simple elements -->
|
||||
<xs:element name="Name" type="xs:string"/>
|
||||
<xs:element name="Name" type="String"/>
|
||||
|
||||
<xs:element name="Number" type="Integer" nillable="true"/>
|
||||
<xs:element name="Number" type="String" nillable="true"/>
|
||||
|
||||
<xs:element name="Examiner" type="String" nillable="true"/>
|
||||
|
||||
|
@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.datamodel;
|
||||
|
||||
import javax.swing.Action;
|
||||
import org.openide.nodes.Sheet;
|
||||
import org.sleuthkit.autopsy.directorytree.ExtractUnallocAction;
|
||||
import org.sleuthkit.datamodel.Volume;
|
||||
|
||||
/**
|
||||
@ -66,6 +67,7 @@ public class VolumeNode extends AbstractContentNode<Volume> {
|
||||
public Action[] getActions(boolean popup) {
|
||||
return new Action[]{ //new ShowDetailAction("Volume Details", this.getName(), this),
|
||||
//new ShowDetailAction("File System Details", this.getName(), this)
|
||||
//new ExtractUnallocAction("Extract Unallocated Files to single Single", this)
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -160,7 +160,6 @@ public class DataResultFilterNode extends FilterNode {
|
||||
List<Action> actions = new ArrayList<Action>();
|
||||
actions.add(new NewWindowViewAction("View in New Window", vol));
|
||||
actions.addAll(ShowDetailActionVisitor.getActions(vol.getLookup().lookup(Content.class)));
|
||||
|
||||
return actions;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,279 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2011 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> 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.directorytree;
|
||||
|
||||
import java.awt.Frame;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.SwingWorker;
|
||||
import org.netbeans.api.progress.ProgressHandle;
|
||||
import org.netbeans.api.progress.ProgressHandleFactory;
|
||||
import org.openide.util.Cancellable;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.datamodel.VolumeNode;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.datamodel.ContentVisitor;
|
||||
import org.sleuthkit.datamodel.Directory;
|
||||
import org.sleuthkit.datamodel.FileSystem;
|
||||
import org.sleuthkit.datamodel.LayoutDirectory;
|
||||
import org.sleuthkit.datamodel.LayoutFile;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.sleuthkit.datamodel.Volume;
|
||||
|
||||
/**
|
||||
* Extracts all the unallocated space as a single file
|
||||
*/
|
||||
public final class ExtractUnallocAction extends AbstractAction{
|
||||
|
||||
private List<LayoutFile> llf;
|
||||
long VolumeId;
|
||||
String ImageName;
|
||||
long ImageId;
|
||||
volatile static boolean running = false;
|
||||
private static final Logger logger = Logger.getLogger(ExtractUnallocAction.class.getName());
|
||||
|
||||
public ExtractUnallocAction(String title, Volume volu){
|
||||
super(title);
|
||||
VolumeId = volu.getId();
|
||||
try{
|
||||
ImageName = volu.getImage().getName();
|
||||
ImageId = volu.getImage().getId();
|
||||
} catch(TskCoreException tce){
|
||||
logger.log(Level.WARNING, "Unable to properly create ExtractUnallocAction, extraction may be incomplete", tce);
|
||||
ImageName = "";
|
||||
ImageId = 0;
|
||||
}
|
||||
llf = getUnallocFiles(volu);
|
||||
Collections.sort(llf, new SortObjId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the unallocated files to $CaseDir/Export/ImgName-Unalloc-ImgObjectID-VolumeID.dat
|
||||
* @param e
|
||||
*/
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (llf != null && llf.size() > 0) {
|
||||
String UnallocName = ImageName + "-Unalloc-" + ImageId + "-" + VolumeId + ".dat";
|
||||
//Format for single Unalloc File is ImgName-Unalloc-ImgObjectID-VolumeID.dat
|
||||
File unalloc = new File(Case.getCurrentCase().getCaseDirectory() + File.separator + "Export" + File.separator + UnallocName);
|
||||
if(running){
|
||||
JOptionPane.showMessageDialog(new Frame(), "Unallocated Space is already running on this volume. Please select a different volume.");
|
||||
return;
|
||||
}
|
||||
if (unalloc.exists()) {
|
||||
int res = JOptionPane.showConfirmDialog(new Frame(), "The Unalloc File for this volume, " + UnallocName + " already exists, do you want to replace it?");
|
||||
if (res == JOptionPane.YES_OPTION) {
|
||||
unalloc.delete();
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
ExtractUnallocWorker uw = new ExtractUnallocWorker(unalloc);
|
||||
uw.execute();
|
||||
} else {
|
||||
logger.log(Level.WARNING, "Tried to get unallocated content from volume ID " + VolumeId + ", but its list of unallocated files was empty or null");
|
||||
}
|
||||
}
|
||||
|
||||
private List<LayoutFile> getUnallocFiles(Content c) {
|
||||
UnallocVisitor uv = new UnallocVisitor();
|
||||
logger.log(Level.INFO, "Sending out Unallocated File Visitor");
|
||||
try {
|
||||
return c.getChildren().get(0).accept(uv); //Launching it on the root directory
|
||||
} catch (TskCoreException tce) {
|
||||
logger.log(Level.WARNING, "Couldn't get a list of Unallocated Files, failed at sending out the visitor ", tce);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Private class for dispatching the file IO in a background thread.
|
||||
*/
|
||||
private class ExtractUnallocWorker extends SwingWorker<Integer, Integer> {
|
||||
|
||||
File path;
|
||||
private ProgressHandle progress;
|
||||
private boolean canceled = false;
|
||||
|
||||
ExtractUnallocWorker(File path) {
|
||||
this.path = path;
|
||||
running = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Integer doInBackground() {
|
||||
try {
|
||||
progress = ProgressHandleFactory.createHandle("Extracting " + path.getName(), new Cancellable() {
|
||||
@Override
|
||||
public boolean cancel() {
|
||||
logger.log(Level.INFO, "Canceling extraction of Unalloc file " + path.getName());
|
||||
canceled = true;
|
||||
if (progress != null) {
|
||||
progress.setDisplayName(path.getName() + " (Cancelling...)");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
FileOutputStream fos = new FileOutputStream(path);
|
||||
int MAX_BYTES = 8192;
|
||||
byte[] buf = new byte[MAX_BYTES]; //read 8k at a time
|
||||
logger.log(Level.INFO, "Writing Unalloc file to " + path.getPath());
|
||||
|
||||
progress.start(llf.size());
|
||||
int count = 0;
|
||||
for (LayoutFile f : llf) {
|
||||
long offset = 0L;
|
||||
while (offset != f.getSize() && !canceled) {
|
||||
offset += f.read(buf, offset, MAX_BYTES); //Offset + Bytes read
|
||||
fos.write(buf);
|
||||
}
|
||||
progress.progress(count++);
|
||||
}
|
||||
progress.finish();
|
||||
fos.flush();
|
||||
fos.close();
|
||||
|
||||
if(canceled){
|
||||
path.delete();
|
||||
logger.log(Level.INFO, "Canceled extraction of " + path.getName() + " and deleted file");
|
||||
}
|
||||
else{
|
||||
logger.log(Level.INFO, "Finished writing unalloc file");
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
logger.log(Level.WARNING, "Could not create Unalloc File; error writing file", ioe);
|
||||
return -1;
|
||||
} catch (TskCoreException tce) {
|
||||
logger.log(Level.WARNING, "Could not create Unalloc File; error getting image info", tce);
|
||||
return -1;
|
||||
}finally{
|
||||
running = false;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
private static class UnallocVisitor extends ContentVisitor.Default<List<LayoutFile>> {
|
||||
|
||||
/**
|
||||
* If the volume has no FileSystem, then it will call this method to return the single instance of unallocated space.
|
||||
* @param lf the LayoutFile the visitor encountered
|
||||
* @return A list<LayoutFile> of size 1, returns null if it fails
|
||||
*/
|
||||
@Override
|
||||
public List<LayoutFile> visit(final org.sleuthkit.datamodel.LayoutFile lf) {
|
||||
return new ArrayList<LayoutFile>() {
|
||||
{
|
||||
add(lf);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* If the visitor finds a FileSystem, it will filter the results for directories and return on the Root Dir.
|
||||
* @param fs the FileSystem the visitor encountered
|
||||
* @return A list<LayoutFile> containing the layout files from subsequent Visits(), returns null if it fails
|
||||
*/
|
||||
@Override
|
||||
public List<LayoutFile> visit(FileSystem fs) {
|
||||
try {
|
||||
for (Content c : fs.getChildren()){
|
||||
if(((AbstractFile)c).isRoot()){
|
||||
return c.accept(this);
|
||||
}
|
||||
}
|
||||
} catch (TskCoreException tce) {
|
||||
logger.log(Level.WARNING, "Couldn't get a list of Unallocated Files, failed at visiting FileSystem " + fs.getId(), tce);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* LayoutDirectory has all the Layout(Unallocated) files
|
||||
* @param ld LayoutDirectory the visitor encountered
|
||||
* @return A list<LayoutFile> containing all the LayoutFile in ld, returns null if it fails
|
||||
*/
|
||||
@Override
|
||||
public List<LayoutFile> visit(LayoutDirectory ld){
|
||||
try{
|
||||
List<LayoutFile> lflst = new ArrayList<LayoutFile>();
|
||||
for(Content layout : ld.getChildren()){
|
||||
lflst.add((LayoutFile)layout);
|
||||
}
|
||||
return lflst;
|
||||
} catch(TskCoreException tce){
|
||||
logger.log(Level.WARNING, "Could not get list of Layout Files, failed at visiting Layout Directory", tce);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The only time this visitor should ever encounter a directory is when parsing over Root
|
||||
* @param dir the directory this visitor encountered
|
||||
* @return A list<LayoutFile> containing LayoutFiles encountered during subsequent Visits(), returns null if it fails
|
||||
*/
|
||||
@Override
|
||||
public List<LayoutFile> visit(Directory dir) {
|
||||
try {
|
||||
for (Content c : dir.getChildren()) {
|
||||
if(c instanceof LayoutDirectory){
|
||||
return c.accept(this);
|
||||
}
|
||||
}
|
||||
}catch (TskCoreException tce) {
|
||||
logger.log(Level.WARNING, "Couldn't get a list of Unallocated Files, failed at visiting Directory " + dir.getId(), tce);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<LayoutFile> defaultVisit(Content cntnt) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private class SortObjId implements Comparator<LayoutFile>{
|
||||
|
||||
@Override
|
||||
public int compare(LayoutFile o1, LayoutFile o2) {
|
||||
if(o1.getId() == o2.getId()){
|
||||
return 0;
|
||||
}
|
||||
if(o1.getId() > o2.getId()){
|
||||
return -1;
|
||||
}
|
||||
else{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -44,11 +44,7 @@ import org.sleuthkit.datamodel.FileSystem;
|
||||
import org.sleuthkit.datamodel.Image;
|
||||
import org.sleuthkit.datamodel.Volume;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author jantonius
|
||||
*/
|
||||
|
||||
class ShowDetailActionVisitor extends ContentVisitor.Default<List<? extends Action>> {
|
||||
|
||||
private static ShowDetailActionVisitor instance = new ShowDetailActionVisitor();
|
||||
@ -231,11 +227,32 @@ class ShowDetailActionVisitor extends ContentVisitor.Default<List<? extends Acti
|
||||
|
||||
@Override
|
||||
public List<? extends Action> visit(final Volume vol) {
|
||||
final String title = "Volume Details";
|
||||
List<AbstractAction> lst = new ArrayList<AbstractAction>();
|
||||
lst.add(new VolumeDetailsAction("Volume Details", vol));
|
||||
lst.add(new ExtractUnallocAction("Extract Unallocated Space to Single File", vol));
|
||||
return lst;
|
||||
}
|
||||
|
||||
|
||||
return Collections.singletonList(new AbstractAction(title) {
|
||||
@Override
|
||||
protected List<? extends Action> defaultVisit(Content di) {
|
||||
return new ArrayList<Action>();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
class VolumeDetailsAction extends AbstractAction{
|
||||
|
||||
String title;
|
||||
Volume vol;
|
||||
|
||||
VolumeDetailsAction(String title, Volume vol){
|
||||
super(title);
|
||||
this.title = title;
|
||||
this.vol = vol;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
Logger.noteAction(ShowDetailActionVisitor.class);
|
||||
|
||||
@ -289,11 +306,4 @@ class ShowDetailActionVisitor extends ContentVisitor.Default<List<? extends Acti
|
||||
popUpWindow.setVisible(true);
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<? extends Action> defaultVisit(Content di) {
|
||||
return new ArrayList<Action>();
|
||||
}
|
||||
}
|
||||
}
|
@ -371,7 +371,7 @@ public class IngestManager {
|
||||
try {
|
||||
s.stop();
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.WARNING, "Exception while stopping module: " + s.getName(), e);
|
||||
logger.log(Level.WARNING, "Unexpected exception while stopping module: " + s.getName(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -379,10 +379,11 @@ public class IngestManager {
|
||||
//stop fs ingester thread
|
||||
boolean cancelled = abstractFileIngester.cancel(true);
|
||||
if (!cancelled) {
|
||||
logger.log(Level.WARNING, "Unable to cancel file ingest worker");
|
||||
} else {
|
||||
abstractFileIngester = null;
|
||||
logger.log(Level.INFO, "Unable to cancel file ingest worker, likely already stopped");
|
||||
}
|
||||
|
||||
abstractFileIngester = null;
|
||||
|
||||
}
|
||||
|
||||
List<IngestImageThread> toStop = new ArrayList<IngestImageThread>();
|
||||
|
@ -69,6 +69,8 @@ public class HashDbIngestModule implements IngestModuleAbstractFile {
|
||||
static long lookuptime = 0;
|
||||
private Map<Integer, HashDb> knownBadSets = new HashMap<Integer, HashDb>();
|
||||
private HashDbManagementPanel panel;
|
||||
|
||||
private final Hash hasher = new Hash();
|
||||
|
||||
private HashDbIngestModule() {
|
||||
count = 0;
|
||||
@ -323,8 +325,7 @@ public class HashDbIngestModule implements IngestModuleAbstractFile {
|
||||
|
||||
ProcessResult ret = ProcessResult.OK;
|
||||
boolean processFile = true;
|
||||
if (fsContent.getSize() == 0
|
||||
|| fsContent.getKnown().equals(TskData.FileKnown.BAD)) {
|
||||
if (fsContent.getKnown().equals(TskData.FileKnown.BAD)) {
|
||||
processFile = false;
|
||||
}
|
||||
if (processFile && (nsrlIsSet || knownBadIsSet)) {
|
||||
@ -333,7 +334,7 @@ public class HashDbIngestModule implements IngestModuleAbstractFile {
|
||||
String md5Hash = fsContent.getMd5Hash();
|
||||
if (md5Hash == null || md5Hash.isEmpty()) {
|
||||
long calcstart = System.currentTimeMillis();
|
||||
md5Hash = Hash.calculateMd5(fsContent);
|
||||
md5Hash = hasher.calculateMd5(fsContent);
|
||||
calctime += (System.currentTimeMillis() - calcstart);
|
||||
}
|
||||
TskData.FileKnown status = TskData.FileKnown.UKNOWN;
|
||||
@ -375,7 +376,7 @@ public class HashDbIngestModule implements IngestModuleAbstractFile {
|
||||
String md5Hash = fsContent.getMd5Hash();
|
||||
if (md5Hash == null || md5Hash.isEmpty()) {
|
||||
long calcstart = System.currentTimeMillis();
|
||||
Hash.calculateMd5(fsContent);
|
||||
hasher.calculateMd5(fsContent);
|
||||
calctime += (System.currentTimeMillis() - calcstart);
|
||||
}
|
||||
ret = ProcessResult.OK;
|
||||
|
@ -32,21 +32,21 @@ import org.sleuthkit.datamodel.FsContent;
|
||||
/**
|
||||
* Searches for FsContent Files with the same MD5 hash as the given Node's
|
||||
* FsContent's MD5 hash. This action should only be available from Nodes with
|
||||
* specific Content attached; it is manually programmed into a Node's available actions.
|
||||
* specific Content attached; it is manually programmed into a Node's available
|
||||
* actions.
|
||||
*/
|
||||
public class HashDbSearchAction extends CallableSystemAction implements HashSearchProvider {
|
||||
|
||||
private static final InitializeContentVisitor initializeCV = new InitializeContentVisitor();
|
||||
private FsContent fsContent;
|
||||
|
||||
private static HashDbSearchAction instance = null;
|
||||
|
||||
HashDbSearchAction() {
|
||||
super();
|
||||
}
|
||||
|
||||
|
||||
public static HashDbSearchAction getDefault() {
|
||||
if(instance == null){
|
||||
if (instance == null) {
|
||||
instance = new HashDbSearchAction();
|
||||
}
|
||||
return instance;
|
||||
@ -60,7 +60,7 @@ public class HashDbSearchAction extends CallableSystemAction implements HashSear
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the FsContent if it is supported, otherwise null. It should
|
||||
* Returns the FsContent if it is supported, otherwise null. It should
|
||||
* realistically never return null or a Directory, only a File.
|
||||
*/
|
||||
private static class InitializeContentVisitor extends ContentVisitor.Default<FsContent> {
|
||||
@ -82,28 +82,21 @@ public class HashDbSearchAction extends CallableSystemAction implements HashSear
|
||||
}
|
||||
|
||||
/**
|
||||
* Find all files with the same MD5 hash as this' fsContent. fsContent should
|
||||
* be previously set by calling the search function, which in turn calls performAction.
|
||||
* Find all files with the same MD5 hash as this' fsContent. fsContent
|
||||
* should be previously set by calling the search function, which in turn
|
||||
* calls performAction.
|
||||
*/
|
||||
@Override
|
||||
public void performAction() {
|
||||
// Make sure all files have an md5 hash
|
||||
if(HashDbSearcher.allFilesMd5Hashed()) {
|
||||
// Make sure at least 1 file has an md5 hash
|
||||
if (HashDbSearcher.countFilesMd5Hashed() > 0) {
|
||||
doSearch();
|
||||
// and if not, warn the user
|
||||
} else if(HashDbSearcher.countFilesMd5Hashed() > 0) {
|
||||
Object selected = JOptionPane.showConfirmDialog(null, "Not all files have MD5 hashes. "
|
||||
+ "Search results will be incomplete.\n"
|
||||
+ "Would you like to search anyway?", "File Search by MD5 Hash", JOptionPane.YES_NO_OPTION);
|
||||
if(selected.equals(JOptionPane.YES_OPTION)) {
|
||||
doSearch();
|
||||
}
|
||||
} else {
|
||||
JOptionPane.showMessageDialog(null, "No files currently have an MD5 hash.",
|
||||
"File Search by MD5 Hash", JOptionPane.ERROR_MESSAGE);
|
||||
JOptionPane.showMessageDialog(null, "No files currently have an MD5 hash calculated, run HashDB ingest first.",
|
||||
"File Search by MD5 Hash", JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void doSearch() {
|
||||
HashDbSearchThread hashThread = new HashDbSearchThread(fsContent);
|
||||
hashThread.execute();
|
||||
|
@ -292,20 +292,9 @@ public class HashDbSearchPanel extends javax.swing.JPanel implements ActionListe
|
||||
boolean search() {
|
||||
// Check if any hashed have been entered
|
||||
if(hashTable.getRowCount()!=0) {
|
||||
// Make sure all files have an md5 hash
|
||||
if(HashDbSearcher.allFilesMd5Hashed()) {
|
||||
return doSearch();
|
||||
// and if not, warn the user
|
||||
} else if(HashDbSearcher.countFilesMd5Hashed() > 0) {
|
||||
errorField.setVisible(false);
|
||||
Object selected = JOptionPane.showConfirmDialog(null, "Not all files have MD5 hashes. "
|
||||
+ "Search results will be incomplete.\n"
|
||||
+ "Would you like to search anyway?", "File Search by MD5 Hash", JOptionPane.YES_NO_OPTION);
|
||||
if(selected.equals(JOptionPane.YES_OPTION)) {
|
||||
return doSearch();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
// Make sure at least 1 file has an md5 hash
|
||||
if(HashDbSearcher.countFilesMd5Hashed() > 0) {
|
||||
return doSearch();
|
||||
} else {
|
||||
JOptionPane.showMessageDialog(null, "No files currently have an MD5 hash.",
|
||||
"File Search by MD5 Hash", JOptionPane.ERROR_MESSAGE);
|
||||
|
@ -25,6 +25,7 @@ import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.SwingWorker;
|
||||
@ -39,6 +40,7 @@ import javax.swing.text.html.HTMLEditorKit;
|
||||
import javax.swing.text.html.HTMLEditorKit.HTMLFactory;
|
||||
import org.netbeans.api.progress.ProgressHandle;
|
||||
import org.netbeans.api.progress.ProgressHandleFactory;
|
||||
import org.sleuthkit.autopsy.coreutils.EscapeUtil;
|
||||
import org.sleuthkit.autopsy.coreutils.TextUtil;
|
||||
|
||||
/**
|
||||
@ -320,7 +322,7 @@ class ExtractedContentPanel extends javax.swing.JPanel {
|
||||
*/
|
||||
void setSources(List<MarkupSource> sources) {
|
||||
sourceComboBox.removeAllItems();
|
||||
setPanelText(null);
|
||||
setPanelText(null, false);
|
||||
|
||||
for (MarkupSource ms : sources) {
|
||||
sourceComboBox.addItem(ms);
|
||||
@ -351,14 +353,29 @@ class ExtractedContentPanel extends javax.swing.JPanel {
|
||||
return (MarkupSource) sourceComboBox.getSelectedItem();
|
||||
}
|
||||
|
||||
private void setPanelText(String text) {
|
||||
if (text == null ) {
|
||||
private void setPanelText(String text, boolean detectDirection) {
|
||||
if (text == null) {
|
||||
text = "";
|
||||
}
|
||||
|
||||
//detect text direction and set it
|
||||
extractedTextPane.applyComponentOrientation(TextUtil.getTextDirection(text));
|
||||
|
||||
|
||||
if (detectDirection) {
|
||||
//detect text direction using first 1024 chars and set it
|
||||
//get first up to 1024 chars, strip <pre> tag and unescape html to get the string on which to detect
|
||||
final int len = text.length();
|
||||
final int prefixLen = "<pre>".length();
|
||||
if (len > prefixLen) {
|
||||
final int maxOrientChars = Math.min(len, 1024);
|
||||
final String orientDetectText = EscapeUtil.unEscapeHtml(text.substring(prefixLen, maxOrientChars));
|
||||
ComponentOrientation direction = TextUtil.getTextDirection(orientDetectText);
|
||||
//logger.log(Level.INFO, "ORIENTATION LEFT TO RIGHT: " + direction.isLeftToRight());
|
||||
extractedTextPane.applyComponentOrientation(direction);
|
||||
} else {
|
||||
extractedTextPane.applyComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
|
||||
}
|
||||
} else {
|
||||
extractedTextPane.applyComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
|
||||
}
|
||||
|
||||
extractedTextPane.setText(text);
|
||||
extractedTextPane.setCaretPosition(0);
|
||||
}
|
||||
@ -570,16 +587,15 @@ class ExtractedContentPanel extends javax.swing.JPanel {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets and sets new markup. Updates GUI in GUI thread and gets markup in background thread.
|
||||
* To be invoked from GUI thread only.
|
||||
* Gets and sets new markup. Updates GUI in GUI thread and gets markup in
|
||||
* background thread. To be invoked from GUI thread only.
|
||||
*/
|
||||
private void setMarkup(MarkupSource source) {
|
||||
setPanelText("<span style='font-style:italic'>Loading text... Please wait</span>");
|
||||
setPanelText("<span style='font-style:italic'>Loading text... Please wait</span>", false);
|
||||
new SetMarkup(source).execute();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Swingworker to get makrup source content String from Solr in background
|
||||
* thread and then set the panel text in the EDT Helps not to block the UI
|
||||
@ -601,7 +617,7 @@ class ExtractedContentPanel extends javax.swing.JPanel {
|
||||
progress.setDisplayName("Loading text");
|
||||
progress.start();
|
||||
progress.switchToIndeterminate();
|
||||
|
||||
|
||||
markup = source.getMarkup();
|
||||
return null;
|
||||
}
|
||||
@ -611,9 +627,9 @@ class ExtractedContentPanel extends javax.swing.JPanel {
|
||||
//super.done();
|
||||
progress.finish();
|
||||
if (markup != null) {
|
||||
setPanelText(markup);
|
||||
setPanelText(markup, true);
|
||||
} else {
|
||||
setPanelText("");
|
||||
setPanelText("", false);
|
||||
}
|
||||
updateControls(source);
|
||||
|
||||
|
@ -282,8 +282,8 @@ public class Firefox extends Extract implements IngestModuleImage {
|
||||
//TODO Revisit usage of deprecated constructor as per TSK-583
|
||||
//bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_LAST_ACCESSED.getTypeID(), "RecentActivity", "Last Visited", (Long.valueOf(result.get("startTime").toString()))));
|
||||
bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED.getTypeID(), "RecentActivity", (Long.valueOf(result.get("startTime").toString()))));
|
||||
bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH_ID.getTypeID(), "RecentActivity", Util.findID(urldecodedtarget)));
|
||||
bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH.getTypeID(), "RecentActivity", urldecodedtarget));
|
||||
bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH_ID.getTypeID(), "RecentActivity", Util.findID(urldecodedtarget)));
|
||||
bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH.getTypeID(), "RecentActivity", ((result.get("target").toString() != null) ? result.get("target").toString() : "")));
|
||||
bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID(), "RecentActivity", "FireFox"));
|
||||
bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN.getTypeID(), "RecentActivity", (Util.extractDomain((result.get("source").toString() != null) ? result.get("source").toString() : ""))));
|
||||
this.addArtifact(ARTIFACT_TYPE.TSK_WEB_DOWNLOAD, FFSqlitedb.get(j), bbattributes);
|
||||
|
Loading…
x
Reference in New Issue
Block a user