mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-14 17:06:16 +00:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
2bcb924deb
Binary file not shown.
Before Width: | Height: | Size: 8.9 KiB After Width: | Height: | Size: 20 KiB |
@ -825,7 +825,10 @@ public class IngestManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* File ingest pipeline processor. Worker runs until AbstractFile queue is
|
* File ingest pipeline processor. Worker thread that queries
|
||||||
|
* the scheduler for new files.
|
||||||
|
* Modules are assumed to already be initialized.
|
||||||
|
* runs until AbstractFile queue is
|
||||||
* consumed New instance is created and started when data arrives and
|
* consumed New instance is created and started when data arrives and
|
||||||
* previous pipeline completed.
|
* previous pipeline completed.
|
||||||
*/
|
*/
|
||||||
|
@ -23,7 +23,9 @@ package org.sleuthkit.autopsy.ingest;
|
|||||||
/**
|
/**
|
||||||
* Base interface for ingest modules
|
* Base interface for ingest modules
|
||||||
*/
|
*/
|
||||||
public interface IngestModuleAbstract {
|
public abstract class IngestModuleAbstract {
|
||||||
|
|
||||||
|
private String args;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Possible module types for the implementing classes
|
* Possible module types for the implementing classes
|
||||||
@ -41,68 +43,78 @@ public interface IngestModuleAbstract {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notification from manager that brand new ingest should be initiated..
|
* Invoked every time an ingest session is started by the framework.
|
||||||
* Module loads its configuration and performs initialization.
|
* A module should support multiple invocations of init() throughout the application life-cycle.
|
||||||
* Invoked once per new worker thread, per ingest.
|
* In this method, the module should reinitialize its internal objects and resources and get them ready
|
||||||
* In this method initialize always IngestServices handle
|
* for a brand new ingest processing.
|
||||||
* using IngestServices.getDefault() lazy-loading approach.
|
*
|
||||||
|
* Here are some things you may do in this method if you'll need them later.
|
||||||
|
* - Get a handle to the ingest services using org.sleuthkit.autopsy.ingest.IngestServices.getDefault().
|
||||||
|
* - Get the current case using org.sleuthkit.autopsy.ingest.IngestServices.getCurrentSleuthkitCaseDb().
|
||||||
|
*
|
||||||
* NEVER initialize IngestServices handle in the member declaration, because it might result
|
* NEVER initialize IngestServices handle in the member declaration, because it might result
|
||||||
* in multiple instances of the singleton -- different class loaders are used in different modules.
|
* in multiple instances of the singleton -- different class loaders are used in different modules.
|
||||||
* @param initContext context used to initialize some modules
|
* @param initContext context used to initialize some modules
|
||||||
*/
|
*/
|
||||||
public void init(IngestModuleInit initContext);
|
abstract public void init(IngestModuleInit initContext);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notification from manager that there is no more content to process and all work is done.
|
* Invoked when an ingest session completes.
|
||||||
* Module performs any clean-up of internal resources, and finalizes processing to produce complete result
|
* The module should perform any resource (files, handles, caches)
|
||||||
* Module also posts ingest message indicating it is done, and posts ingest stats and errors in the details of the message.
|
* cleanup in this method and submit final results and post a final ingest inbox message.
|
||||||
*/
|
*/
|
||||||
public void complete();
|
abstract public void complete();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notification from manager to stop processing due to some interruption (user, error, exception)
|
* Invoked on a module when an ingest session is interrupted by the user or system.
|
||||||
* Module performs any clean-up of internal resources
|
* The method implementation should be similar to complete() in that the
|
||||||
* It may also discard any pending results, but it should ensure it is in a defined state so that ingest can be rerun later.
|
* module should perform any cleanup work.
|
||||||
|
* If there is pending data to be processed or pending results to be reported by the module
|
||||||
|
* then the results should be rejected and ignored and the method should return as early as possible.
|
||||||
|
* It should ensure it is in a defined state so that ingest can be rerun later.
|
||||||
*/
|
*/
|
||||||
public void stop();
|
abstract public void stop();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets specific name of the module
|
* Returns unique name of the module. Should not have collisions.
|
||||||
* The name should be unique across modules
|
|
||||||
* @return unique module name
|
* @return unique module name
|
||||||
*/
|
*/
|
||||||
public String getName();
|
abstract public String getName();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the module version
|
* Gets the module version
|
||||||
* @return module version string
|
* @return module version string
|
||||||
*/
|
*/
|
||||||
public String getVersion();
|
abstract public String getVersion();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets user-friendly description of the module
|
* Gets user-friendly description of the module
|
||||||
* @return module description
|
* @return module description
|
||||||
*/
|
*/
|
||||||
public String getDescription();
|
abstract public String getDescription();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns type of the module
|
* Returns type of the module (Image-level or file-level)
|
||||||
* @return module type
|
* @return module type
|
||||||
*/
|
*/
|
||||||
public ModuleType getType();
|
abstract public ModuleType getType();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the arguments as set in XML
|
* Gets the arguments as set in XML
|
||||||
* @return arguments string
|
* @return arguments string
|
||||||
*/
|
*/
|
||||||
public String getArguments();
|
public String getArguments() {
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the arguments from XML
|
* Sets the arguments from XML
|
||||||
* @param args arguments string in XML
|
* @param args arguments string in XML
|
||||||
*/
|
*/
|
||||||
public void setArguments(String args);
|
public void setArguments(String a_args) {
|
||||||
|
args = a_args;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A module can manage and use additional threads to perform some work in the background.
|
* A module can manage and use additional threads to perform some work in the background.
|
||||||
@ -112,7 +124,7 @@ public interface IngestModuleAbstract {
|
|||||||
* @return true if any background threads/workers managed by this module are still running or are pending to be run,
|
* @return true if any background threads/workers managed by this module are still running or are pending to be run,
|
||||||
* false if all work has been done, or if background threads are not used/managed by this module
|
* false if all work has been done, or if background threads are not used/managed by this module
|
||||||
*/
|
*/
|
||||||
public boolean hasBackgroundJobsRunning();
|
abstract public boolean hasBackgroundJobsRunning();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -121,7 +133,9 @@ public interface IngestModuleAbstract {
|
|||||||
*
|
*
|
||||||
* @return true if this module has a simple (run-time) configuration
|
* @return true if this module has a simple (run-time) configuration
|
||||||
*/
|
*/
|
||||||
public boolean hasSimpleConfiguration();
|
public boolean hasSimpleConfiguration() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to determine if a module has implemented an advanced (general)
|
* Used to determine if a module has implemented an advanced (general)
|
||||||
@ -129,21 +143,23 @@ public interface IngestModuleAbstract {
|
|||||||
*
|
*
|
||||||
* @return true if this module has an advanced configuration
|
* @return true if this module has an advanced configuration
|
||||||
*/
|
*/
|
||||||
public boolean hasAdvancedConfiguration();
|
public boolean hasAdvancedConfiguration() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called by the ingest manager if the simple (run-time) configuration
|
* Called by the ingest manager if the simple (run-time) configuration
|
||||||
* panel should save its current state so that the settings can be used
|
* panel should save its current state so that the settings can be used
|
||||||
* during the ingest.
|
* during the ingest.
|
||||||
*/
|
*/
|
||||||
public void saveSimpleConfiguration();
|
public void saveSimpleConfiguration() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If module implements advanced configuration panel
|
* If module implements advanced configuration panel
|
||||||
* it should read its current state and make it persistent / save it in this method
|
* it should read its current state and make it persistent / save it in this method
|
||||||
* so that the new configuration will be in effect during the ingest.
|
* so that the new configuration will be in effect during the ingest.
|
||||||
*/
|
*/
|
||||||
public void saveAdvancedConfiguration();
|
public void saveAdvancedConfiguration() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a panel that displays the simple (run-time) configuration.
|
* Returns a panel that displays the simple (run-time) configuration.
|
||||||
@ -155,14 +171,18 @@ public interface IngestModuleAbstract {
|
|||||||
*
|
*
|
||||||
* @return JPanel containing basic configuration widgets or null if simple configuration is not available
|
* @return JPanel containing basic configuration widgets or null if simple configuration is not available
|
||||||
*/
|
*/
|
||||||
public javax.swing.JPanel getSimpleConfiguration();
|
public javax.swing.JPanel getSimpleConfiguration() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements advanced module configuration exposed to the user before ingest starts
|
* Implements advanced module conf iguration exposed to the user before ingest starts
|
||||||
* The module is responsible for preserving / saving its configuration state
|
* The module is responsible for preserving / saving its configuration state
|
||||||
* In addition, saveAdvancedConfiguration() can be used
|
* In addition, saveAdvancedConfiguration() can be used
|
||||||
*
|
*
|
||||||
* @return JPanel containing advanced configuration widgets or null if advanced configuration is not available
|
* @return JPanel containing advanced configuration widgets or null if advanced configuration is not available
|
||||||
*/
|
*/
|
||||||
public javax.swing.JPanel getAdvancedConfiguration();
|
public javax.swing.JPanel getAdvancedConfiguration() {
|
||||||
|
return null;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ import org.sleuthkit.datamodel.AbstractFile;
|
|||||||
/**
|
/**
|
||||||
* Ingest module interface that will be called for every file in the image
|
* Ingest module interface that will be called for every file in the image
|
||||||
*/
|
*/
|
||||||
public interface IngestModuleAbstractFile extends IngestModuleAbstract {
|
public abstract class IngestModuleAbstractFile extends IngestModuleAbstract {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return value resulting from processing AbstractFile
|
* Return value resulting from processing AbstractFile
|
||||||
@ -36,6 +36,11 @@ public interface IngestModuleAbstractFile extends IngestModuleAbstract {
|
|||||||
UNKNOWN ///< Indicates that a return value for the module is not known. This should not be returned directly by modules, but is used to indicate the module has not set its return value (e.g. it never ran)
|
UNKNOWN ///< Indicates that a return value for the module is not known. This should not be returned directly by modules, but is used to indicate the module has not set its return value (e.g. it never ran)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ModuleType getType() {
|
||||||
|
return ModuleType.AbstractFile;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Entry point to process file / directory by the module. See \ref ingestmodule_making for details
|
* Entry point to process file / directory by the module. See \ref ingestmodule_making for details
|
||||||
* on what modules are responsible for doing.
|
* on what modules are responsible for doing.
|
||||||
@ -44,5 +49,5 @@ public interface IngestModuleAbstractFile extends IngestModuleAbstract {
|
|||||||
* @param abstractFile file to process
|
* @param abstractFile file to process
|
||||||
* @return ProcessResult result of the processing that can be used in the pipeline as a hint whether to further process this file
|
* @return ProcessResult result of the processing that can be used in the pipeline as a hint whether to further process this file
|
||||||
*/
|
*/
|
||||||
public ProcessResult process(PipelineContext<IngestModuleAbstractFile>pipelineContext, AbstractFile abstractFile);
|
abstract public ProcessResult process(PipelineContext<IngestModuleAbstractFile>pipelineContext, AbstractFile abstractFile);
|
||||||
}
|
}
|
||||||
|
@ -26,26 +26,27 @@ import org.sleuthkit.datamodel.Image;
|
|||||||
* Image ingest modules run each in its own background thread
|
* Image ingest modules run each in its own background thread
|
||||||
* in parallel to the file processing ingest pipeline and other image ingest modules
|
* in parallel to the file processing ingest pipeline and other image ingest modules
|
||||||
*/
|
*/
|
||||||
public interface IngestModuleImage extends IngestModuleAbstract {
|
public abstract class IngestModuleImage extends IngestModuleAbstract {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ModuleType getType() {
|
||||||
|
return ModuleType.Image;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Entry point to process the image by the module.
|
* Called with the image to analyze.
|
||||||
*
|
*
|
||||||
* Module does all the processing work in this method.
|
* Modules typically use FileManager to get specific files to analyze.
|
||||||
* It is responsible for extracting content of interest from the image (i.e. using DataModel API) and processing it.
|
|
||||||
* Results of processing, such as extracted data or analysis results, should be posted to the blackboard.
|
|
||||||
*
|
*
|
||||||
* The module notifies the ingest inbox of interesting events (data, errors, warnings, infos)
|
* Results should be posted to the blackboard.
|
||||||
* by posting ingest messages
|
* The module should also send messages to the ingest inbox of interesting events (data, errors, warnings, infos).
|
||||||
* The module notifies data viewers by firing events using IngestManagerProxy.fireModuleDataEvent
|
* The module notifies data viewers by firing events using IngestManagerProxy.fireModuleDataEvent
|
||||||
*
|
*
|
||||||
* The module is responsible for posting progress to controller
|
* The module will have its own progress bar while it is running and it should update it with the Controller object.
|
||||||
* And to periodically check controller if it should break out of the processing loop because task has been canceled
|
|
||||||
*
|
*
|
||||||
* @param pipelineContext the context in which the ingest runs (with its own settings, modules, etc)
|
* @param pipelineContext Context in which the ingest pipeline is running (Settings, modules, etc)
|
||||||
* @param image to process
|
* @param image Image to process
|
||||||
* @param controller to post progress to and to use for checking if cancellation has occurred
|
* @param controller Used to update progress bar and to check if the task has been canceled.
|
||||||
*/
|
*/
|
||||||
public void process(PipelineContext<IngestModuleImage>pipelineContext, Image image, IngestImageWorkerController controller);
|
abstract public void process(PipelineContext<IngestModuleImage>pipelineContext, Image image, IngestImageWorkerController controller);
|
||||||
}
|
}
|
||||||
|
@ -222,27 +222,18 @@ public final class IngestModuleLoader {
|
|||||||
//netbeans uses custom class loader, otherwise can't load classes from other modules
|
//netbeans uses custom class loader, otherwise can't load classes from other modules
|
||||||
|
|
||||||
final Class<?> moduleClass = Class.forName(location, false, classLoader);
|
final Class<?> moduleClass = Class.forName(location, false, classLoader);
|
||||||
|
final Type intf = moduleClass.getGenericSuperclass();
|
||||||
final Type[] intfs = moduleClass.getGenericInterfaces();
|
|
||||||
|
|
||||||
if (intfs.length != 0 && pType != null) {
|
if (pType != null) {
|
||||||
//check if one of the module interfaces matches the pipeline type
|
|
||||||
boolean interfaceFound = false;
|
|
||||||
Class<?> moduleMeta = ((IngestModuleMapping) pType).getIngestModuleInterface();
|
Class<?> moduleMeta = ((IngestModuleMapping) pType).getIngestModuleInterface();
|
||||||
String moduleIntNameCan = moduleMeta.getCanonicalName();
|
String moduleIntNameCan = moduleMeta.getCanonicalName();
|
||||||
String[] moduleIntNameTok = moduleIntNameCan.split(" ");
|
String[] moduleIntNameTok = moduleIntNameCan.split(" ");
|
||||||
String moduleIntName = moduleIntNameTok[moduleIntNameTok.length - 1];
|
String moduleIntName = moduleIntNameTok[moduleIntNameTok.length - 1];
|
||||||
for (Type intf : intfs) {
|
|
||||||
String intNameCan = intf.toString();
|
String intNameCan = intf.toString();
|
||||||
String[] intNameCanTok = intNameCan.split(" ");
|
String[] intNameCanTok = intNameCan.split(" ");
|
||||||
String intName = intNameCanTok[intNameCanTok.length - 1];
|
String intName = intNameCanTok[intNameCanTok.length - 1];
|
||||||
if (intName.equals(moduleIntName)) {
|
if (!intName.equals(moduleIntName)) {
|
||||||
interfaceFound = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (interfaceFound == false) {
|
|
||||||
moduleErrors = true;
|
moduleErrors = true;
|
||||||
logger.log(Level.WARNING, "Module class: " + location
|
logger.log(Level.WARNING, "Module class: " + location
|
||||||
+ " does not implement correct interface: " + moduleMeta.getName()
|
+ " does not implement correct interface: " + moduleMeta.getName()
|
||||||
|
@ -20,11 +20,9 @@ package org.sleuthkit.autopsy.exifparser;
|
|||||||
|
|
||||||
import com.drew.imaging.ImageMetadataReader;
|
import com.drew.imaging.ImageMetadataReader;
|
||||||
import com.drew.imaging.ImageProcessingException;
|
import com.drew.imaging.ImageProcessingException;
|
||||||
import com.drew.imaging.jpeg.JpegProcessingException;
|
|
||||||
import com.drew.lang.GeoLocation;
|
import com.drew.lang.GeoLocation;
|
||||||
import com.drew.lang.Rational;
|
import com.drew.lang.Rational;
|
||||||
import com.drew.metadata.Metadata;
|
import com.drew.metadata.Metadata;
|
||||||
import com.drew.metadata.MetadataException;
|
|
||||||
import com.drew.metadata.exif.ExifIFD0Directory;
|
import com.drew.metadata.exif.ExifIFD0Directory;
|
||||||
import com.drew.metadata.exif.ExifSubIFDDirectory;
|
import com.drew.metadata.exif.ExifSubIFDDirectory;
|
||||||
import com.drew.metadata.exif.GpsDirectory;
|
import com.drew.metadata.exif.GpsDirectory;
|
||||||
@ -33,26 +31,19 @@ import java.io.IOException;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Calendar;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.ingest.PipelineContext;
|
import org.sleuthkit.autopsy.ingest.PipelineContext;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestServices;
|
import org.sleuthkit.autopsy.ingest.IngestServices;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestMessage;
|
|
||||||
import org.sleuthkit.autopsy.ingest.IngestMessage.MessageType;
|
|
||||||
import org.sleuthkit.autopsy.ingest.IngestModuleAbstract;
|
|
||||||
import org.sleuthkit.autopsy.ingest.IngestModuleAbstractFile;
|
import org.sleuthkit.autopsy.ingest.IngestModuleAbstractFile;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestModuleImage;
|
|
||||||
import org.sleuthkit.autopsy.ingest.IngestModuleInit;
|
import org.sleuthkit.autopsy.ingest.IngestModuleInit;
|
||||||
import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
|
import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
|
||||||
import org.sleuthkit.datamodel.AbstractFile;
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||||
import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
|
import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
|
||||||
import org.sleuthkit.datamodel.FsContent;
|
|
||||||
import org.sleuthkit.datamodel.ReadContentInputStream;
|
import org.sleuthkit.datamodel.ReadContentInputStream;
|
||||||
import org.sleuthkit.datamodel.TskCoreException;
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
import org.sleuthkit.datamodel.TskData.TSK_DB_FILES_TYPE_ENUM;
|
import org.sleuthkit.datamodel.TskData.TSK_DB_FILES_TYPE_ENUM;
|
||||||
@ -62,15 +53,13 @@ import org.sleuthkit.datamodel.TskData.TSK_DB_FILES_TYPE_ENUM;
|
|||||||
* Ingests an image file and, if available, adds it's date, latitude, longitude,
|
* Ingests an image file and, if available, adds it's date, latitude, longitude,
|
||||||
* altitude, device model, and device make to a blackboard artifact.
|
* altitude, device model, and device make to a blackboard artifact.
|
||||||
*/
|
*/
|
||||||
public final class ExifParserFileIngestModule implements IngestModuleAbstractFile {
|
public final class ExifParserFileIngestModule extends IngestModuleAbstractFile {
|
||||||
|
|
||||||
private IngestServices services;
|
private IngestServices services;
|
||||||
|
|
||||||
final public static String MODULE_NAME = "Exif Parser";
|
final public static String MODULE_NAME = "Exif Parser";
|
||||||
final public static String MODULE_VERSION = "1.0";
|
final public static String MODULE_VERSION = "1.0";
|
||||||
|
|
||||||
private String args;
|
|
||||||
|
|
||||||
private static final int readHeaderSize = 2;
|
private static final int readHeaderSize = 2;
|
||||||
private final byte[] fileHeaderBuffer = new byte[readHeaderSize];
|
private final byte[] fileHeaderBuffer = new byte[readHeaderSize];
|
||||||
private static final char JPEG_SIGNATURE_BE = 0xFFD8;
|
private static final char JPEG_SIGNATURE_BE = 0xFFD8;
|
||||||
@ -260,17 +249,6 @@ public final class ExifParserFileIngestModule implements IngestModuleAbstractFil
|
|||||||
return MODULE_VERSION;
|
return MODULE_VERSION;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getArguments() {
|
|
||||||
return args;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setArguments(String args) {
|
|
||||||
this.args = args;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
@ -297,41 +275,8 @@ public final class ExifParserFileIngestModule implements IngestModuleAbstractFil
|
|||||||
//module specific cleanup due to interruption here
|
//module specific cleanup due to interruption here
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public IngestModuleAbstract.ModuleType getType() {
|
|
||||||
return IngestModuleAbstract.ModuleType.AbstractFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasSimpleConfiguration() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasAdvancedConfiguration() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public javax.swing.JPanel getSimpleConfiguration() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public javax.swing.JPanel getAdvancedConfiguration() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasBackgroundJobsRunning() {
|
public boolean hasBackgroundJobsRunning() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void saveAdvancedConfiguration() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void saveSimpleConfiguration() {
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -47,13 +47,12 @@ import org.sleuthkit.datamodel.TskCoreException;
|
|||||||
import org.sleuthkit.datamodel.TskData;
|
import org.sleuthkit.datamodel.TskData;
|
||||||
import org.sleuthkit.datamodel.TskException;
|
import org.sleuthkit.datamodel.TskException;
|
||||||
|
|
||||||
public class HashDbIngestModule implements IngestModuleAbstractFile {
|
public class HashDbIngestModule extends IngestModuleAbstractFile {
|
||||||
|
|
||||||
private static HashDbIngestModule instance = null;
|
private static HashDbIngestModule instance = null;
|
||||||
public final static String MODULE_NAME = "Hash Lookup";
|
public final static String MODULE_NAME = "Hash Lookup";
|
||||||
public final static String MODULE_DESCRIPTION = "Identifies known and notables files using supplied hash databases, such as a standard NSRL database.";
|
public final static String MODULE_DESCRIPTION = "Identifies known and notables files using supplied hash databases, such as a standard NSRL database.";
|
||||||
final public static String MODULE_VERSION = "1.0";
|
final public static String MODULE_VERSION = "1.0";
|
||||||
private String args;
|
|
||||||
private static final Logger logger = Logger.getLogger(HashDbIngestModule.class.getName());
|
private static final Logger logger = Logger.getLogger(HashDbIngestModule.class.getName());
|
||||||
private IngestServices services;
|
private IngestServices services;
|
||||||
private SleuthkitCase skCase;
|
private SleuthkitCase skCase;
|
||||||
@ -195,16 +194,6 @@ public class HashDbIngestModule implements IngestModuleAbstractFile {
|
|||||||
return MODULE_VERSION;
|
return MODULE_VERSION;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getArguments() {
|
|
||||||
return args;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setArguments(String args) {
|
|
||||||
this.args = args;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ProcessResult process(PipelineContext<IngestModuleAbstractFile>pipelineContext, AbstractFile file) {
|
public ProcessResult process(PipelineContext<IngestModuleAbstractFile>pipelineContext, AbstractFile file) {
|
||||||
@ -216,10 +205,6 @@ public class HashDbIngestModule implements IngestModuleAbstractFile {
|
|||||||
return processFile(file);
|
return processFile(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ModuleType getType() {
|
|
||||||
return ModuleType.AbstractFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasBackgroundJobsRunning() {
|
public boolean hasBackgroundJobsRunning() {
|
||||||
|
@ -74,7 +74,7 @@
|
|||||||
<Component id="pagePreviousButton" min="-2" max="-2" attributes="0"/>
|
<Component id="pagePreviousButton" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
|
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
|
||||||
<Component id="pageNextButton" min="-2" max="-2" attributes="0"/>
|
<Component id="pageNextButton" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace pref="71" max="32767" attributes="0"/>
|
<EmptySpace max="32767" attributes="0"/>
|
||||||
<Component id="sourceComboBox" min="-2" max="-2" attributes="0"/>
|
<Component id="sourceComboBox" min="-2" max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
<Component id="jScrollPane1" pref="0" max="32767" attributes="0"/>
|
<Component id="jScrollPane1" pref="0" max="32767" attributes="0"/>
|
||||||
@ -105,7 +105,7 @@
|
|||||||
<Component id="pagePreviousButton" min="-2" pref="23" max="-2" attributes="0"/>
|
<Component id="pagePreviousButton" min="-2" pref="23" max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
|
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
|
||||||
<Component id="jScrollPane1" pref="293" max="32767" attributes="0"/>
|
<Component id="jScrollPane1" pref="377" max="32767" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
</DimensionLayout>
|
</DimensionLayout>
|
||||||
|
@ -77,7 +77,7 @@ import org.sleuthkit.datamodel.TskData.FileKnown;
|
|||||||
*
|
*
|
||||||
* Registered as a module in layer.xml
|
* Registered as a module in layer.xml
|
||||||
*/
|
*/
|
||||||
public final class KeywordSearchIngestModule implements IngestModuleAbstractFile {
|
public final class KeywordSearchIngestModule extends IngestModuleAbstractFile {
|
||||||
|
|
||||||
enum UpdateFrequency {
|
enum UpdateFrequency {
|
||||||
|
|
||||||
@ -98,7 +98,6 @@ public final class KeywordSearchIngestModule implements IngestModuleAbstractFile
|
|||||||
public static final String MODULE_NAME = "Keyword Search";
|
public static final String MODULE_NAME = "Keyword Search";
|
||||||
public static final String MODULE_DESCRIPTION = "Performs file indexing and periodic search using keywords and regular expressions in lists.";
|
public static final String MODULE_DESCRIPTION = "Performs file indexing and periodic search using keywords and regular expressions in lists.";
|
||||||
final public static String MODULE_VERSION = "1.0";
|
final public static String MODULE_VERSION = "1.0";
|
||||||
private String args;
|
|
||||||
private static KeywordSearchIngestModule instance = null;
|
private static KeywordSearchIngestModule instance = null;
|
||||||
private IngestServices services;
|
private IngestServices services;
|
||||||
private Ingester ingester = null;
|
private Ingester ingester = null;
|
||||||
@ -326,16 +325,6 @@ public final class KeywordSearchIngestModule implements IngestModuleAbstractFile
|
|||||||
return MODULE_VERSION;
|
return MODULE_VERSION;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getArguments() {
|
|
||||||
return args;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setArguments(String args) {
|
|
||||||
this.args = args;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the module for new ingest run Sets up threads, timers,
|
* Initializes the module for new ingest run Sets up threads, timers,
|
||||||
* retrieves settings, keyword lists to run on
|
* retrieves settings, keyword lists to run on
|
||||||
@ -427,11 +416,6 @@ public final class KeywordSearchIngestModule implements IngestModuleAbstractFile
|
|||||||
searchTimer.start();
|
searchTimer.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ModuleType getType() {
|
|
||||||
return ModuleType.AbstractFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasSimpleConfiguration() {
|
public boolean hasSimpleConfiguration() {
|
||||||
return true;
|
return true;
|
||||||
|
@ -359,7 +359,7 @@ public class Server {
|
|||||||
} else {
|
} else {
|
||||||
loggingPropertiesFilePath += "logging-release.properties";
|
loggingPropertiesFilePath += "logging-release.properties";
|
||||||
}
|
}
|
||||||
loggingPropertiesFilePath = PlatformUtil.getOSFilePath(loggingPropertiesFilePath);
|
//loggingPropertiesFilePath = PlatformUtil.getOSFilePath(loggingPropertiesFilePath);
|
||||||
final String loggingProperties = loggingPropertiesOpt + loggingPropertiesFilePath;
|
final String loggingProperties = loggingPropertiesOpt + loggingPropertiesFilePath;
|
||||||
|
|
||||||
final String [] SOLR_START_CMD = {
|
final String [] SOLR_START_CMD = {
|
||||||
|
@ -56,7 +56,7 @@ import org.sleuthkit.datamodel.TskData;
|
|||||||
/**
|
/**
|
||||||
* Chrome recent activity extraction
|
* Chrome recent activity extraction
|
||||||
*/
|
*/
|
||||||
public class Chrome extends Extract implements IngestModuleImage {
|
public class Chrome extends Extract {
|
||||||
|
|
||||||
private static final String chquery = "SELECT urls.url, urls.title, urls.visit_count, urls.typed_count, "
|
private static final String chquery = "SELECT urls.url, urls.title, urls.visit_count, urls.typed_count, "
|
||||||
+ "last_visit_time, urls.hidden, visits.visit_time, (SELECT urls.url FROM urls WHERE urls.id=visits.url) as from_visit, visits.transition FROM urls, visits WHERE urls.id = visits.url";
|
+ "last_visit_time, urls.hidden, visits.visit_time, (SELECT urls.url FROM urls WHERE urls.id=visits.url) as from_visit, visits.transition FROM urls, visits WHERE urls.id = visits.url";
|
||||||
@ -67,7 +67,6 @@ public class Chrome extends Extract implements IngestModuleImage {
|
|||||||
private final Logger logger = Logger.getLogger(this.getClass().getName());
|
private final Logger logger = Logger.getLogger(this.getClass().getName());
|
||||||
public int ChromeCount = 0;
|
public int ChromeCount = 0;
|
||||||
final public static String MODULE_VERSION = "1.0";
|
final public static String MODULE_VERSION = "1.0";
|
||||||
private String args;
|
|
||||||
private IngestServices services;
|
private IngestServices services;
|
||||||
|
|
||||||
//hide public constructor to prevent from instantiation by ingest module loader
|
//hide public constructor to prevent from instantiation by ingest module loader
|
||||||
@ -80,15 +79,6 @@ public class Chrome extends Extract implements IngestModuleImage {
|
|||||||
return MODULE_VERSION;
|
return MODULE_VERSION;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getArguments() {
|
|
||||||
return args;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setArguments(String args) {
|
|
||||||
this.args = args;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void process(PipelineContext<IngestModuleImage>pipelineContext, Image image, IngestImageWorkerController controller) {
|
public void process(PipelineContext<IngestModuleImage>pipelineContext, Image image, IngestImageWorkerController controller) {
|
||||||
@ -468,38 +458,6 @@ public class Chrome extends Extract implements IngestModuleImage {
|
|||||||
return "Extracts activity from the Google Chrome browser.";
|
return "Extracts activity from the Google Chrome browser.";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ModuleType getType() {
|
|
||||||
return ModuleType.Image;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasSimpleConfiguration() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasAdvancedConfiguration() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public javax.swing.JPanel getSimpleConfiguration() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public javax.swing.JPanel getAdvancedConfiguration() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void saveAdvancedConfiguration() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void saveSimpleConfiguration() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasBackgroundJobsRunning() {
|
public boolean hasBackgroundJobsRunning() {
|
||||||
|
@ -34,7 +34,7 @@ import org.sleuthkit.autopsy.ingest.IngestModuleImage;
|
|||||||
import org.sleuthkit.autopsy.report.SQLiteDBConnect;
|
import org.sleuthkit.autopsy.report.SQLiteDBConnect;
|
||||||
import org.sleuthkit.datamodel.*;
|
import org.sleuthkit.datamodel.*;
|
||||||
|
|
||||||
abstract public class Extract implements IngestModuleImage{
|
abstract public class Extract extends IngestModuleImage{
|
||||||
|
|
||||||
protected Case currentCase = Case.getCurrentCase(); // get the most updated case
|
protected Case currentCase = Case.getCurrentCase(); // get the most updated case
|
||||||
protected SleuthkitCase tskCase = currentCase.getSleuthkitCase();
|
protected SleuthkitCase tskCase = currentCase.getSleuthkitCase();
|
||||||
|
@ -70,7 +70,7 @@ import org.sleuthkit.autopsy.ingest.IngestModuleImage;
|
|||||||
import org.sleuthkit.autopsy.ingest.IngestModuleInit;
|
import org.sleuthkit.autopsy.ingest.IngestModuleInit;
|
||||||
import org.sleuthkit.datamodel.*;
|
import org.sleuthkit.datamodel.*;
|
||||||
|
|
||||||
public class ExtractIE extends Extract implements IngestModuleImage {
|
public class ExtractIE extends Extract {
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(ExtractIE.class.getName());
|
private static final Logger logger = Logger.getLogger(ExtractIE.class.getName());
|
||||||
private IngestServices services;
|
private IngestServices services;
|
||||||
@ -91,7 +91,6 @@ public class ExtractIE extends Extract implements IngestModuleImage {
|
|||||||
public LinkedHashMap<String, Object> IE_OBJ;
|
public LinkedHashMap<String, Object> IE_OBJ;
|
||||||
boolean pascoFound = false;
|
boolean pascoFound = false;
|
||||||
final public static String MODULE_VERSION = "1.0";
|
final public static String MODULE_VERSION = "1.0";
|
||||||
private String args;
|
|
||||||
private static final SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
|
private static final SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
|
||||||
|
|
||||||
private ExecUtil execPasco;
|
private ExecUtil execPasco;
|
||||||
@ -106,15 +105,6 @@ public class ExtractIE extends Extract implements IngestModuleImage {
|
|||||||
return MODULE_VERSION;
|
return MODULE_VERSION;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getArguments() {
|
|
||||||
return args;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setArguments(String args) {
|
|
||||||
this.args = args;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void process(PipelineContext<IngestModuleImage>pipelineContext, Image image, IngestImageWorkerController controller) {
|
public void process(PipelineContext<IngestModuleImage>pipelineContext, Image image, IngestImageWorkerController controller) {
|
||||||
@ -593,39 +583,6 @@ public class ExtractIE extends Extract implements IngestModuleImage {
|
|||||||
return "Extracts activity from Internet Explorer browser, as well as recent documents in windows.";
|
return "Extracts activity from Internet Explorer browser, as well as recent documents in windows.";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ModuleType getType() {
|
|
||||||
return ModuleType.Image;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasSimpleConfiguration() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasAdvancedConfiguration() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public javax.swing.JPanel getSimpleConfiguration() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public javax.swing.JPanel getAdvancedConfiguration() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void saveAdvancedConfiguration() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void saveSimpleConfiguration() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasBackgroundJobsRunning() {
|
public boolean hasBackgroundJobsRunning() {
|
||||||
return false;
|
return false;
|
||||||
|
@ -22,11 +22,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.recentactivity;
|
package org.sleuthkit.autopsy.recentactivity;
|
||||||
|
|
||||||
import org.sleuthkit.autopsy.coreutils.ExecUtil;
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@ -36,18 +33,18 @@ import javax.xml.parsers.DocumentBuilderFactory;
|
|||||||
import javax.xml.parsers.ParserConfigurationException;
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
import org.openide.modules.InstalledFileLocator;
|
import org.openide.modules.InstalledFileLocator;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.ExecUtil;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
|
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
|
||||||
import org.sleuthkit.autopsy.datamodel.ContentUtils;
|
import org.sleuthkit.autopsy.datamodel.ContentUtils;
|
||||||
import org.sleuthkit.autopsy.ingest.PipelineContext;
|
|
||||||
import org.sleuthkit.autopsy.ingest.IngestImageWorkerController;
|
import org.sleuthkit.autopsy.ingest.IngestImageWorkerController;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestModuleImage;
|
import org.sleuthkit.autopsy.ingest.IngestModuleImage;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestModuleInit;
|
import org.sleuthkit.autopsy.ingest.IngestModuleInit;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestServices;
|
import org.sleuthkit.autopsy.ingest.IngestServices;
|
||||||
|
import org.sleuthkit.autopsy.ingest.PipelineContext;
|
||||||
import org.sleuthkit.datamodel.*;
|
import org.sleuthkit.datamodel.*;
|
||||||
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
|
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
|
||||||
import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
|
import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
|
||||||
import org.sleuthkit.datamodel.FileSystem;
|
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
import org.w3c.dom.Node;
|
import org.w3c.dom.Node;
|
||||||
@ -58,7 +55,7 @@ import org.xml.sax.SAXException;
|
|||||||
/**
|
/**
|
||||||
* Extracting windows registry data using regripper
|
* Extracting windows registry data using regripper
|
||||||
*/
|
*/
|
||||||
public class ExtractRegistry extends Extract implements IngestModuleImage {
|
public class ExtractRegistry extends Extract {
|
||||||
|
|
||||||
public Logger logger = Logger.getLogger(this.getClass().getName());
|
public Logger logger = Logger.getLogger(this.getClass().getName());
|
||||||
private String RR_PATH;
|
private String RR_PATH;
|
||||||
@ -66,7 +63,7 @@ public class ExtractRegistry extends Extract implements IngestModuleImage {
|
|||||||
private int sysid;
|
private int sysid;
|
||||||
private IngestServices services;
|
private IngestServices services;
|
||||||
final public static String MODULE_VERSION = "1.0";
|
final public static String MODULE_VERSION = "1.0";
|
||||||
private String args;
|
|
||||||
private ExecUtil execRR;
|
private ExecUtil execRR;
|
||||||
|
|
||||||
//hide public constructor to prevent from instantiation by ingest module loader
|
//hide public constructor to prevent from instantiation by ingest module loader
|
||||||
@ -105,15 +102,6 @@ public class ExtractRegistry extends Extract implements IngestModuleImage {
|
|||||||
return MODULE_VERSION;
|
return MODULE_VERSION;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getArguments() {
|
|
||||||
return args;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setArguments(String args) {
|
|
||||||
this.args = args;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void getRegistryFiles(Image image, IngestImageWorkerController controller) {
|
private void getRegistryFiles(Image image, IngestImageWorkerController controller) {
|
||||||
|
|
||||||
@ -441,38 +429,6 @@ public class ExtractRegistry extends Extract implements IngestModuleImage {
|
|||||||
return "Extracts activity from the Windows registry utilizing RegRipper.";
|
return "Extracts activity from the Windows registry utilizing RegRipper.";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ModuleType getType() {
|
|
||||||
return ModuleType.Image;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasSimpleConfiguration() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasAdvancedConfiguration() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public javax.swing.JPanel getSimpleConfiguration() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public javax.swing.JPanel getAdvancedConfiguration() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void saveAdvancedConfiguration() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void saveSimpleConfiguration() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasBackgroundJobsRunning() {
|
public boolean hasBackgroundJobsRunning() {
|
||||||
|
@ -51,7 +51,7 @@ import org.sleuthkit.datamodel.TskCoreException;
|
|||||||
/**
|
/**
|
||||||
* Firefox recent activity extraction
|
* Firefox recent activity extraction
|
||||||
*/
|
*/
|
||||||
public class Firefox extends Extract implements IngestModuleImage {
|
public class Firefox extends Extract {
|
||||||
|
|
||||||
private static final String ffquery = "SELECT moz_historyvisits.id,url,title,visit_count,(visit_date/1000000) as visit_date,from_visit,(SELECT url FROM moz_places WHERE id=moz_historyvisits.from_visit) as ref FROM moz_places, moz_historyvisits WHERE moz_places.id = moz_historyvisits.place_id AND hidden = 0";
|
private static final String ffquery = "SELECT moz_historyvisits.id,url,title,visit_count,(visit_date/1000000) as visit_date,from_visit,(SELECT url FROM moz_places WHERE id=moz_historyvisits.from_visit) as ref FROM moz_places, moz_historyvisits WHERE moz_places.id = moz_historyvisits.place_id AND hidden = 0";
|
||||||
private static final String ffcookiequery = "SELECT name,value,host,expiry,(lastAccessed/1000000) as lastAccessed,(creationTime/1000000) as creationTime FROM moz_cookies";
|
private static final String ffcookiequery = "SELECT name,value,host,expiry,(lastAccessed/1000000) as lastAccessed,(creationTime/1000000) as creationTime FROM moz_cookies";
|
||||||
@ -60,7 +60,6 @@ public class Firefox extends Extract implements IngestModuleImage {
|
|||||||
private static final String ffdownloadquery = "select target, source,(startTime/1000000) as startTime, maxBytes from moz_downloads";
|
private static final String ffdownloadquery = "select target, source,(startTime/1000000) as startTime, maxBytes from moz_downloads";
|
||||||
public int FireFoxCount = 0;
|
public int FireFoxCount = 0;
|
||||||
final public static String MODULE_VERSION = "1.0";
|
final public static String MODULE_VERSION = "1.0";
|
||||||
private String args;
|
|
||||||
private IngestServices services;
|
private IngestServices services;
|
||||||
|
|
||||||
//hide public constructor to prevent from instantiation by ingest module loader
|
//hide public constructor to prevent from instantiation by ingest module loader
|
||||||
@ -73,16 +72,6 @@ public class Firefox extends Extract implements IngestModuleImage {
|
|||||||
return MODULE_VERSION;
|
return MODULE_VERSION;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getArguments() {
|
|
||||||
return args;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setArguments(String args) {
|
|
||||||
this.args = args;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void process(PipelineContext<IngestModuleImage>pipelineContext, Image image, IngestImageWorkerController controller) {
|
public void process(PipelineContext<IngestModuleImage>pipelineContext, Image image, IngestImageWorkerController controller) {
|
||||||
this.getHistory(image, controller);
|
this.getHistory(image, controller);
|
||||||
@ -364,39 +353,6 @@ public class Firefox extends Extract implements IngestModuleImage {
|
|||||||
return "Extracts activity from the Mozilla FireFox browser.";
|
return "Extracts activity from the Mozilla FireFox browser.";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ModuleType getType() {
|
|
||||||
return ModuleType.Image;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasSimpleConfiguration() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasAdvancedConfiguration() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public javax.swing.JPanel getSimpleConfiguration() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public javax.swing.JPanel getAdvancedConfiguration() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void saveAdvancedConfiguration() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void saveSimpleConfiguration() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasBackgroundJobsRunning() {
|
public boolean hasBackgroundJobsRunning() {
|
||||||
return false;
|
return false;
|
||||||
|
@ -23,7 +23,6 @@
|
|||||||
package org.sleuthkit.autopsy.recentactivity;
|
package org.sleuthkit.autopsy.recentactivity;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.ingest.PipelineContext;
|
import org.sleuthkit.autopsy.ingest.PipelineContext;
|
||||||
@ -31,7 +30,6 @@ import org.sleuthkit.autopsy.ingest.IngestImageWorkerController;
|
|||||||
import org.sleuthkit.autopsy.ingest.IngestServices;
|
import org.sleuthkit.autopsy.ingest.IngestServices;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestMessage;
|
import org.sleuthkit.autopsy.ingest.IngestMessage;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestMessage.MessageType;
|
import org.sleuthkit.autopsy.ingest.IngestMessage.MessageType;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestModuleAbstractFile;
|
|
||||||
import org.sleuthkit.autopsy.ingest.IngestModuleImage;
|
import org.sleuthkit.autopsy.ingest.IngestModuleImage;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestModuleInit;
|
import org.sleuthkit.autopsy.ingest.IngestModuleInit;
|
||||||
import org.sleuthkit.datamodel.Image;
|
import org.sleuthkit.datamodel.Image;
|
||||||
@ -40,7 +38,7 @@ import org.sleuthkit.datamodel.Image;
|
|||||||
* Recent activity image ingest module
|
* Recent activity image ingest module
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public final class RAImageIngestModule implements IngestModuleImage {
|
public final class RAImageIngestModule extends IngestModuleImage {
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(RAImageIngestModule.class.getName());
|
private static final Logger logger = Logger.getLogger(RAImageIngestModule.class.getName());
|
||||||
private static RAImageIngestModule defaultInstance = null;
|
private static RAImageIngestModule defaultInstance = null;
|
||||||
@ -49,7 +47,6 @@ public final class RAImageIngestModule implements IngestModuleImage {
|
|||||||
private StringBuilder subCompleted = new StringBuilder();
|
private StringBuilder subCompleted = new StringBuilder();
|
||||||
private ArrayList<Extract> modules;
|
private ArrayList<Extract> modules;
|
||||||
final public static String MODULE_VERSION = "1.0";
|
final public static String MODULE_VERSION = "1.0";
|
||||||
private String args;
|
|
||||||
|
|
||||||
//public constructor is required
|
//public constructor is required
|
||||||
//as multiple instances are created for processing multiple images simultenously
|
//as multiple instances are created for processing multiple images simultenously
|
||||||
@ -179,54 +176,12 @@ public final class RAImageIngestModule implements IngestModuleImage {
|
|||||||
logger.log(Level.INFO, "Recent Activity processes has been shutdown.");
|
logger.log(Level.INFO, "Recent Activity processes has been shutdown.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ModuleType getType() {
|
|
||||||
return ModuleType.Image;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getVersion() {
|
public String getVersion() {
|
||||||
return MODULE_VERSION;
|
return MODULE_VERSION;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getArguments() {
|
|
||||||
return args;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setArguments(String args) {
|
|
||||||
this.args = args;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasSimpleConfiguration() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasAdvancedConfiguration() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public javax.swing.JPanel getSimpleConfiguration() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public javax.swing.JPanel getAdvancedConfiguration() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void saveAdvancedConfiguration() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void saveSimpleConfiguration() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasBackgroundJobsRunning() {
|
public boolean hasBackgroundJobsRunning() {
|
||||||
return false;
|
return false;
|
||||||
|
@ -48,7 +48,6 @@ import org.sleuthkit.datamodel.BlackboardArtifact;
|
|||||||
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
|
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
|
||||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||||
import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
|
import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
|
||||||
import org.sleuthkit.datamodel.Content;
|
|
||||||
import org.sleuthkit.datamodel.FsContent;
|
import org.sleuthkit.datamodel.FsContent;
|
||||||
import org.sleuthkit.datamodel.Image;
|
import org.sleuthkit.datamodel.Image;
|
||||||
import org.sleuthkit.datamodel.TskException;
|
import org.sleuthkit.datamodel.TskException;
|
||||||
@ -66,13 +65,12 @@ import org.xml.sax.SAXException;
|
|||||||
* To add search engines, edit SearchEngines.xml under RecentActivity
|
* To add search engines, edit SearchEngines.xml under RecentActivity
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class SearchEngineURLQueryAnalyzer extends Extract implements IngestModuleImage {
|
public class SearchEngineURLQueryAnalyzer extends Extract {
|
||||||
|
|
||||||
private IngestServices services;
|
private IngestServices services;
|
||||||
|
|
||||||
public static final String MODULE_NAME = "Search Engine URL Query Analyzer";
|
public static final String MODULE_NAME = "Search Engine URL Query Analyzer";
|
||||||
public final static String MODULE_VERSION = "1.0";
|
public final static String MODULE_VERSION = "1.0";
|
||||||
private String args;
|
|
||||||
|
|
||||||
public static final String XMLFILE = "SEUQAMappings.xml";
|
public static final String XMLFILE = "SEUQAMappings.xml";
|
||||||
private static final String XSDFILE = "SearchEngineSchema.xsd";
|
private static final String XSDFILE = "SearchEngineSchema.xsd";
|
||||||
@ -401,51 +399,9 @@ public class SearchEngineURLQueryAnalyzer extends Extract implements IngestModul
|
|||||||
return MODULE_VERSION;
|
return MODULE_VERSION;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getArguments() {
|
|
||||||
return args;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setArguments(String args) {
|
|
||||||
this.args = args;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IngestModuleAbstract.ModuleType getType() {
|
|
||||||
return IngestModuleAbstract.ModuleType.Image;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasBackgroundJobsRunning() {
|
public boolean hasBackgroundJobsRunning() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasSimpleConfiguration() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasAdvancedConfiguration() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void saveSimpleConfiguration() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void saveAdvancedConfiguration() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JPanel getSimpleConfiguration() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JPanel getAdvancedConfiguration() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -64,13 +64,12 @@ import org.sleuthkit.datamodel.TskCoreException;
|
|||||||
*
|
*
|
||||||
* Updates datamodel / directory tree with new files.
|
* Updates datamodel / directory tree with new files.
|
||||||
*/
|
*/
|
||||||
public final class SevenZipIngestModule implements IngestModuleAbstractFile {
|
public final class SevenZipIngestModule extends IngestModuleAbstractFile {
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(SevenZipIngestModule.class.getName());
|
private static final Logger logger = Logger.getLogger(SevenZipIngestModule.class.getName());
|
||||||
public static final String MODULE_NAME = "Archive Extractor";
|
public static final String MODULE_NAME = "Archive Extractor";
|
||||||
public static final String MODULE_DESCRIPTION = "Extracts archive files (zip, rar, arj, 7z, gzip, bzip2, tar), reschedules them to current ingest and populates directory tree with new files.";
|
public static final String MODULE_DESCRIPTION = "Extracts archive files (zip, rar, arj, 7z, gzip, bzip2, tar), reschedules them to current ingest and populates directory tree with new files.";
|
||||||
final public static String MODULE_VERSION = "1.0";
|
final public static String MODULE_VERSION = "1.0";
|
||||||
private String args;
|
|
||||||
private IngestServices services;
|
private IngestServices services;
|
||||||
private volatile int messageID = 0;
|
private volatile int messageID = 0;
|
||||||
private int processedFiles = 0;
|
private int processedFiles = 0;
|
||||||
@ -600,53 +599,12 @@ public final class SevenZipIngestModule implements IngestModuleAbstractFile {
|
|||||||
return MODULE_VERSION;
|
return MODULE_VERSION;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getArguments() {
|
|
||||||
return args;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setArguments(String args) {
|
|
||||||
this.args = args;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ModuleType getType() {
|
|
||||||
return ModuleType.AbstractFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasBackgroundJobsRunning() {
|
public boolean hasBackgroundJobsRunning() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasSimpleConfiguration() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasAdvancedConfiguration() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void saveSimpleConfiguration() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void saveAdvancedConfiguration() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JPanel getSimpleConfiguration() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JPanel getAdvancedConfiguration() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSupported(AbstractFile file) {
|
public boolean isSupported(AbstractFile file) {
|
||||||
String fileNameLower = file.getName().toLowerCase();
|
String fileNameLower = file.getName().toLowerCase();
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#Updated by build script
|
#Updated by build script
|
||||||
|
#Thu, 23 May 2013 00:04:58 -0400
|
||||||
LBL_splash_window_title=Starting Autopsy
|
LBL_splash_window_title=Starting Autopsy
|
||||||
SPLASH_HEIGHT=288
|
SPLASH_HEIGHT=288
|
||||||
SPLASH_WIDTH=538
|
SPLASH_WIDTH=538
|
||||||
@ -6,3 +7,5 @@ SplashProgressBarBounds=3,236,533,6
|
|||||||
SplashRunningTextBounds=5,212,530,17
|
SplashRunningTextBounds=5,212,530,17
|
||||||
SplashRunningTextColor=0x0
|
SplashRunningTextColor=0x0
|
||||||
SplashRunningTextFontSize=18
|
SplashRunningTextFontSize=18
|
||||||
|
|
||||||
|
currentVersion=Autopsy 20130523
|
||||||
|
@ -1 +1,5 @@
|
|||||||
#Updated by build script
|
#Updated by build script
|
||||||
|
#Thu, 23 May 2013 00:04:58 -0400
|
||||||
|
|
||||||
|
CTL_MainWindow_Title=Autopsy 20130523
|
||||||
|
CTL_MainWindow_Title_No_Project=Autopsy 20130523
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 8.9 KiB After Width: | Height: | Size: 20 KiB |
BIN
branding_autopsy/welcome_logo_old.png
Normal file
BIN
branding_autopsy/welcome_logo_old.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.9 KiB |
@ -1,18 +1,21 @@
|
|||||||
/*! \mainpage Autopsy Forensic Browser Developer's Guide and API Reference
|
/*! \mainpage Autopsy Forensic Browser Developer's Guide and API Reference
|
||||||
|
|
||||||
<h3>Overview</h3>
|
<h3>Overview</h3>
|
||||||
Autopsy has been designed as a platform for open source tools besides just The Sleuth Kit. This document is for developers who want to add functionality into Autopsy. This could be in the form of enhancing the existing functionality or by making a module that plugs into it and you may distribute from your own site or push it back into the base distribution.
|
Autopsy has been designed as a platform for open source tools besides just The Sleuth Kit. This document is for developers who want to add functionality into Autopsy. This could be in the form of enhancing the existing functionality or by making a module that plugs into it and you may distribute from your own site or push it back into the base distribution.
|
||||||
|
|
||||||
- \subpage workflow_page
|
If you want to write modules, then these pages are for you:
|
||||||
- \subpage platform_page
|
- \subpage platform_page
|
||||||
- \subpage mod_dev_page
|
- \subpage mod_dev_page
|
||||||
- \subpage mod_ingest_page
|
- \subpage mod_ingest_page
|
||||||
- \subpage mod_report_page
|
- \subpage mod_report_page
|
||||||
- \subpage mod_content_page
|
- \subpage mod_content_page
|
||||||
- \subpage mod_result_page
|
- \subpage mod_result_page
|
||||||
- \subpage regression_test_page
|
|
||||||
|
These pages are more detailed if you want to modify Autopsy code instead of writing add-on modules.
|
||||||
<!-- Note that Case still has lots of content in package.dox -->
|
- \subpage workflow_page
|
||||||
*/
|
- \subpage regression_test_page
|
||||||
|
|
||||||
|
<!-- Note that Case still has lots of content in package.dox -->
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,205 +1,196 @@
|
|||||||
/*! \page mod_dev_page Development Basics
|
/*! \page mod_dev_page Development Basics
|
||||||
|
|
||||||
<!-- NOTE: This doc contains the concepts that apply when developing
|
<!-- NOTE: This doc contains the concepts that apply when developing
|
||||||
any type of module. Information about specific types of modules should
|
any type of module. Information about specific types of modules should
|
||||||
go into the page for that module type. -->
|
go into the page for that module type. -->
|
||||||
|
|
||||||
<!-- @@@ Update -->
|
<!-- @@@ Update -->
|
||||||
|
|
||||||
This page describes the basic concepts and setup that are needed regardless of the module type that you are building.
|
This page describes the basic concepts and setup that are needed regardless of the module type that you are building.
|
||||||
|
|
||||||
\section mod_dev_setup Basic Setup
|
\section mod_dev_setup Basic Setup
|
||||||
|
|
||||||
\subsection mod_dev_setup_java The Java Environment
|
\subsection mod_dev_setup_nb NetBeans
|
||||||
|
|
||||||
Currently, to develop modules for Autopsy, you must be using Java 1.6.
|
Autopsy is built on top of the NetBeans Rich Client Platform, which makes it easy to make plug-in infrastructures. To do any development, you really need to download NetBeans first. You can in theory develop modules by command line only, but this document assumes that you are using the IDE. Download and install the latest version of the IDE from X.
|
||||||
|
|
||||||
You can verify the module project is built for Java 1.6 by right clicking the project, choosing Properties, and checking that under Libraries the Java Platform is JDK 1.6 and under Sources the Source Level is 1.6.
|
\subsection mod_dev_setup_java Java
|
||||||
|
|
||||||
|
Autopsy currently requires Java 1.7. Ensure that it is installed.
|
||||||
\subsection mod_dev_setup_autopsy Setting up Development Environment
|
|
||||||
|
\subsection mod_dev_setup_platform Autopsy Platform
|
||||||
|
|
||||||
To setup a module development environment for Autopsy, you must have either:
|
Before we can make a module, we must configure NetBeans to know about Autopsy as a platform. This will allow you to access all of the classes and services that Autopsy provides. Therea are two ways of configuring the NetBeans IDE to know about Autopsy:
|
||||||
\li Autopsy installed on your machine
|
|
||||||
\li The Autopsy source code, downloaded from GitHub
|
- Download an official release of Autopsy and build against it.
|
||||||
|
- Download Autopsy source code, build it, and make a platform to build against.
|
||||||
in order to for your project to import the Autopsy framework API.
|
|
||||||
|
\subsubsection mod_dev_setup_platform_rel Released Platform
|
||||||
If you used Autopsy installer that comes with an official release of Autopsy, you will get the more stable version of the framework, but possibly not the latest.
|
|
||||||
If you import Autopsy libraries pulled from GitHub,
|
The easiest approach is install Autopsy on your computer. It will have everything that you need. If you installed it in "C:\Program Files\Autopsy", then the platform is in "C:\Program Files\Autopsy\platform".
|
||||||
you may get the latest version of the framework, but not the most stable and official one,
|
|
||||||
and still likely to be changed before the next official release.
|
\subsubsection mod_dev_setup_platform_src Source Code-based Platform
|
||||||
|
|
||||||
If you have Autopsy installed on your machine and would like to use that as your development environment,
|
If you want to build against the bleeding edge code and updates that have occured since the last release, then you must download the latest source code and build it. This involves getting a full development environment setup.
|
||||||
proceed to \ref mod_dev_module.
|
|
||||||
Note that older versions of Autopsy may not have the latest features available for module development.
|
// @@@ ADD LINK IN HERE TO DEV SETUP ON WIKI
|
||||||
|
|
||||||
To use the latest Autopsy source code as your development environment, first follow BUILDING.TXT to properly build and setup Autopsy in NetBeans. Make sure you are using Java 1.6.
|
To use the latest Autopsy source code as your development environment, first follow BUILDING.TXT in the root source repository to properly build and setup Autopsy in NetBeans.
|
||||||
|
|
||||||
Once Autopsy has been successfully built, right click on the Autopsy project in NetBeans and select Package as > ZIP Distribution.
|
Once Autopsy has been successfully built, right click on the Autopsy project in NetBeans and select Package as > ZIP Distribution. Once the ZIP file is created, extract its contents to a directory. This directory is the platform that you will build against. Note that you will building the module against this built platform. If you need to make changes to Autopsy infrastructure for your module, then you will need to then make a new ZIP file and configure your module to use it each time.
|
||||||
Then extract the ZIP file to any directory of your choosing.
|
|
||||||
|
|
||||||
|
\section mod_dev_module Creating a Basic NetBeans Module
|
||||||
\section mod_dev_module How to Create a Module
|
|
||||||
|
The Autopsy modules are encapsulated inside of NetBeans modules. A NetBeans module will be packaged as a single ".nbm" file. A single NetBeans module can contain many Autopsy modules. The NetBeans module is what the user will install and provides things like auto-update.
|
||||||
In NetBeans go to File > New Project.
|
|
||||||
|
\subsection mod_dev_mod_nb Creating a NetBeans Module
|
||||||
From the categories, choose NetBeans Modules, and then Module under Projects.
|
|
||||||
|
If this is your first module, then you will need to make a NetBeans module. If you have already made an Autopsy module and are now working on a second one, you can consider adding it to your pevious NetBeans module.
|
||||||
Click Next, name the module, and set the project location.
|
|
||||||
|
To make a NetBeans module, open the NetBeans IDE and go to File -> New Project.
|
||||||
Select Standalone Module, and click the Manage button. Click on Add Platform and either browse to the directory Autopsy is installed or to the directory the ZIP distribution was extracted. Press Finish and then Close.
|
|
||||||
|
From the list of categories, choose "NetBeans Modules" and then "Module" from the list of "Projects". Click Next.
|
||||||
Autopsy has now been added as a "NetBeans Platform", meaning the development environment for NetBeans has been set to use the code from within Autopsy. This grants access to Autopsy Framework API (exported packages and classes) to external developers, without having to program inside the Autopsy project itself.
|
|
||||||
|
In the next panel of the wizard, give the module a name and directory. Select Standalone Module (the default is typically "Add to Suite") so that you build the module as an external module against Autopsy. You will need to tell NetBeans about the Autopsy platform, so choose the "Manage" button. Choose the "Add Platform" button and browse to the location of the platform discussed in the previous sections (as a reminder this will either be the location that you installed Autopsy into or where you opened up the ZIP file you created from source). Click Next.
|
||||||
Click Next, and fill out the rest of the module-creation wizard.
|
|
||||||
Make sure to fill out the Module Name, Module Category (use "Ingest Module" for an Autopsy ingest module), Short and Long Descriptions.
|
Finally, enter the code base name. Press Finish.
|
||||||
Also fill out the Module Major Build version and Specification version in API Versioning section.
|
|
||||||
|
You now have a NetBeans module that is using Autopsy as its build platform. That means you will have access to all of the services and utilities that Autopsy provides.
|
||||||
Autopsy requires that all modules restart Autopsy after they are installed -- otherwise the module might not be fully loaded and functional.
|
|
||||||
To setup your module in this fashion, right click on the module and choose Properties.
|
|
||||||
Under Build > Packaging, check the box that says Needs Restart on Install.
|
\subsection mod_dev_mod_config Configuring the NetBeans Module
|
||||||
|
|
||||||
Press Finish when complete, and the module will be added as a standalone project in NetBeans.
|
After the module is created, you will need to do some further configuration. Right click on the newly created module and choose "Properties".
|
||||||
|
|
||||||
After the module is created, it is important to verify the new project is using Java 1.6.
|
\subsubsection mod_dev_mod_config_library Dependencies
|
||||||
To check the version of Java, right click on the module in the Projects window and go to Properties.
|
|
||||||
Make sure that under the Libraries category the Java Platform is JDK 1.6, and under Sources the Source Level is 1.6.
|
You will need to configure the module to be dependent on modules from within the Autopsy platform. Go to the "Libraries" area and choose "Add" in the "Module Dependencies" section. Choose the "Autopsy-core" library. You now have access to the Autopsy services.
|
||||||
|
|
||||||
See \ref mod_ingest_page for instructions on programming ingest modules for Autopsy.
|
If you later determine that you need to pull in external JAR files, then you will use the "Wrapped Jar" section to add them in.
|
||||||
Or read <a href="http://bits.netbeans.org/dev/javadoc/org-openide-modules/org/openide/modules/doc-files/api.html">this guide from NetBeans.org</a> for general module development tips.
|
|
||||||
|
Note, you will also need to come back to this section if you update the platform. You may need to add a new dependency for the version of the Autopsy-core that comes with the updated platform.
|
||||||
|
|
||||||
\subsection mod_dev_services_dependency Adding a Dependency
|
\subsubsection mod_dev_mod_config_restart Restarting
|
||||||
|
|
||||||
You need to first add dependencies to your module to import the relevant APIs needed for development of your module.
|
Autopsy requires that all modules restart Autopsy after they are installed -- otherwise the module might not be fully loaded and functional.
|
||||||
Adding the dependency will also help to resolve the dependencies of your module at runtime
|
Configure your module this way
|
||||||
and let the framework properly load your module.
|
under Build -> Packaging. Check the box that says Needs Restart on Install.
|
||||||
|
|
||||||
To add a dependency on a module, in NetBeans IDE, right click the module and go to Properties.
|
|
||||||
In the Libraries category, you can see the current dependencies your module has.
|
\subsubsection mod_dev_mod_config_other Optional Settings
|
||||||
Click the Add button and either scroll through the list of available modules
|
There are several optional things in the Properties section. You can add a description and specify the version. You can do all of this later though and it does not need to be done before you start development.
|
||||||
or filter the modules by class, package name, path, or display name.
|
|
||||||
When the desired module is found, press OK and it will appear in the list of current dependencies.
|
TODO: @@@ Add link here about NetBeans versioning scheme.
|
||||||
|
TODO: @@@ Add mention somwhere in the docs about Autopsy's versioning scheme
|
||||||
Currently you only need to specify Autopsy-Core as one of your module dependencies
|
|
||||||
- this will give you access to the Autopsy Framework Core API (such as interfaces and services)
|
|
||||||
and allow for plugging-in your custom Ingest Modules, Content Viewers and Reports.
|
|
||||||
|
\subsection mod_dev_mod_other Other Links
|
||||||
Ensure that you select which Build and Specification version of the Autopsy-Core module your module depends on.
|
|
||||||
This will later help the plugin manager detect if dependencies are met for your module when the module is being loaded,
|
For general NetBeans module information, refer to <a href="http://bits.netbeans.org/dev/javadoc/org-openide-modules/org/openide/modules/doc-files/api.html">this guide from NetBeans.org</a>.
|
||||||
into a potentially different version of the framework.
|
|
||||||
|
|
||||||
When a module is added as a dependency, its APIs become available to the dependant module.
|
\section mod_dev_aut Creating Autopsy Modules
|
||||||
|
|
||||||
The relevant APIs for module development are the interfaces for different module types (for example, Ingest Modules),
|
You can now add Autopsy modules into the NetBeans container module. There are other pages that focus on that and are listed on the main page. The rest of this document contains info that you will eventually want to come back to though.
|
||||||
defining which methods the module should be implementing. Also, there are services APIs, which are tools that framework provides for modules,
|
As you will read in the later sections about the different module types, each Autopsy Module is a java class that extends an interface (the interface depends on the type of module).
|
||||||
such as data storage, configuration, logging, etc.
|
|
||||||
|
|
||||||
TODO we should outline the process of adding a JAR file dependency for an external library.
|
\subsection mod_dev_aut_run1 Running Your Module During Development
|
||||||
E.g. adding jar directly to the module project, or (preferred) wrapping set of jars in another module
|
|
||||||
e.g. NewModuleName-Libs and adding a dependency on the libs module. Add info how to bundle OS-specific dlls in the jar (work in progress).
|
When you are developing your Autopsy module, you can simply choose "Run" on the module and it will launch the Autopsy platform with the module enabled in it. This is also how you can debug the module.
|
||||||
|
|
||||||
\section mod_dev_services Services
|
\subsection mod_dev_aut_deploy Deploying Your Module
|
||||||
|
|
||||||
A Services class is provided to give developers access to the services provided by the Autopsy framework. Currently, the following
|
When you are ready to share your module, create an NBM file by right clicking on the module and selecting "Create NBM".
|
||||||
services are provided:
|
|
||||||
|
\subsection mod_dev_aut_install Installing Your Module
|
||||||
- FileManager: the org.sleuthkit.autopsy.casemodule.services.FileManager service provides an API for easy access to files and directories for a given image.
|
|
||||||
You can access the org.sleuthkit.autopsy.casemodule.services.FileManager service by calling the getFileManager() method of the
|
To install the module on a non-development environment, launch Autopsy and choose Plugins under the Tools menu. Open the Downloaded tab and click Add Plugins. Navigate to the NBM file and open it. Next, click Install and follow the wizard.
|
||||||
org.sleuthkit.autopsy.casemodule.services.Services class.
|
|
||||||
|
|
||||||
\section mod_dev_utilities Utilities
|
\section mod_dev_other Other Useful Information
|
||||||
|
|
||||||
Autopsy-Core module contains the core Autopsy application and also the framework the application is built upon that other modules can use.
|
This section contains other information that will be useful when developing any type of Autopsy module.
|
||||||
Among the Core APIs there are general utilities available to the Autopsy modules. The relevant packages include:
|
|
||||||
|
\subsection mod_dev_other_services Autopsy Services
|
||||||
- org.sleuthkit.autopsy.casemodule.Case class - for the module to access Case data (TSK database) and subscribe to Case change events
|
|
||||||
- org.sleuthkit.autopsy.coreutils package has classes providing utilities for getting access to Autopsy loggers, configuration persistance API,
|
Autopsy provides basic services to its modules. These were created to make it easier to write modules. Currently, the following
|
||||||
getting information about the Platform (such as locations of files and folders, info about the runtime environment),
|
services are provided:
|
||||||
extracting default settings files from the jar file to a user settings folder, etc.
|
|
||||||
Relevant service classes are org.sleuthkit.autopsy.coreutils.Version,
|
- FileManager: the org.sleuthkit.autopsy.casemodule.services.FileManager service provides an API to access any file in the case. You can access FileManager by calling org.sleuthkit.autopsy.casemodule.services.Services.getFileManager().
|
||||||
org.sleuthkit.autopsy.coreutils.PlatformUtil, org.sleuthkit.autopsy.coreutils.ModuleSettings,
|
|
||||||
org.sleuthkit.autopsy.coreutils.Logger and org.sleuthkit.autopsy.coreutils.FileUtil.
|
\subsection mod_dev_other_utilities Autopsy Utilities
|
||||||
|
|
||||||
TODO: Add additional info about utility classes (log, Case, database, etc.) Similar to the C++ section about services (http://sleuthkit.org/sleuthkit/docs/framework-docs/mod_devpage.html)
|
|
||||||
|
Autopsy-Core module contains the core Autopsy application and also the framework the application is built upon that other modules can use.
|
||||||
TODO: Move the log content from the wiki (http://wiki.sleuthkit.org/index.php?title=Autopsy_3_Logging_and_Error_Checking) to here.
|
Among the Core APIs there are general utilities available to the Autopsy modules. The relevant packages include:
|
||||||
|
|
||||||
Note: org.sleuthkit.autopsy.ingest.IngestServices provides services specifically for the ingest modules.
|
- org.sleuthkit.autopsy.casemodule.Case class - for the module to access Case data (TSK database) and subscribe to Case change events
|
||||||
|
- org.sleuthkit.autopsy.coreutils package has classes providing utilities for getting access to Autopsy loggers, configuration persistance API,
|
||||||
|
getting information about the Platform (such as locations of files and folders, info about the runtime environment),
|
||||||
\section mod_dev_configuration Making a Configuration Panel
|
extracting default settings files from the jar file to a user settings folder, etc.
|
||||||
|
Relevant service classes are org.sleuthkit.autopsy.coreutils.Version,
|
||||||
Some modules may have configuration settings for the users to set or review using GUI components, such as JPanels.
|
org.sleuthkit.autopsy.coreutils.PlatformUtil, org.sleuthkit.autopsy.coreutils.ModuleSettings,
|
||||||
Autopsy provides two centralized locations for users to accesss these settings via panels registered by the module: the \ref mod_dev_configuration_ingest,
|
org.sleuthkit.autopsy.coreutils.Logger and org.sleuthkit.autopsy.coreutils.FileUtil.
|
||||||
and the \ref mod_dev_configuration_options.
|
|
||||||
|
TODO: Add additional info about utility classes (log, Case, database, etc.) Similar to the C++ section about services (http://sleuthkit.org/sleuthkit/docs/framework-docs/mod_devpage.html)
|
||||||
\subsection mod_dev_configuration_ingest Ingest Dialog Panel
|
|
||||||
|
TODO: Move the log content from the wiki (http://wiki.sleuthkit.org/index.php?title=Autopsy_3_Logging_and_Error_Checking) to here.
|
||||||
The ingest configuration dialog panel is displayed anytime ingest is to be started/restarted.
|
|
||||||
It provides framework for two-levels of settings: "simple panel" as well as an "advanced panel".
|
Note: org.sleuthkit.autopsy.ingest.IngestServices provides services specifically for the ingest modules.
|
||||||
The simple panel is shown directly in the ingest configuration panel on the right-hand side when a specific module is selected.
|
|
||||||
The advanced panel is opened in a new window if the user presses the Advanced button in the ingest configuration dialog.
|
|
||||||
|
\section mod_dev_adv Advanced Concepts
|
||||||
Both of these panels can be created as a standard \c JPanel, and returned by your ingest module using
|
|
||||||
of the the ingest module methods implemented, that are declared in the ingest module interface.
|
These aren't really advanced, but you don't need to know them in detail when you start your first module. You'll want to refer back to them after you get started and wonder, "how do I do X".
|
||||||
|
|
||||||
It is recommended when making an ingest module to have the advanced panel also be accessible also via the main Options panel,
|
|
||||||
allowing the user access to the settings from Tools > Options and not only via the ingest module configuration.
|
\section mod_dev_adv_bb Black Board
|
||||||
|
|
||||||
See \ref ingestmodule_making_configuration how to implement hooks for having your ingest module configurations registered.
|
@@@ TODO
|
||||||
|
|
||||||
\subsection mod_dev_configuration_options Options Panel
|
\section mod_dev_adv_inbox Ingest Inbox Messages
|
||||||
|
|
||||||
To add panel to the options menu, right click the module and choose New > Other. Under the Module Development category, select Options Panel and press Next.
|
@@@ TODO: Sending messages, etc.
|
||||||
|
|
||||||
Select Create Primary Panel, name the panel (preferably with the module's name), select an icon, and add keywords, then click Next and Finish. Note that NetBeans will automatically copy the selected icon to the module's directory if not already there.
|
\section mod_dev_adv_options Option Panels
|
||||||
|
|
||||||
NetBeans will generate two Java files for you, the panel and the controller. For now, we only need to focus on the panel.
|
|
||||||
|
|
||||||
First, use NetBeans' GUI builder to design the panel. Be sure to include all options, settings, preferences, etc for the module, as this is what the user will see. The recommended size of an options panel is about 675 x 500.
|
Some modules may have configuration settings that uses can change. We recommend that you use the infrastructure provided by Autopsy and NetBeans to do this so that all module condiguration is done in a single place.
|
||||||
|
|
||||||
Second, in the source code of the panel, there are two important methods: \c load() and \c store(). When the options panel is opened via Tools > Options in Autopsy, the \c load() method will be called. Conversely, when the user presses OK after editing the options, the \c store() method will be called.
|
To add a panel to the options menu, right click the module and choose New > Other. Under the Module Development category, select Options Panel and press Next.
|
||||||
|
|
||||||
If one wishes to make any additional panels within the original options panel, or panels which the original opens, Autopsy provides the org.sleuthkit.autopsy.corecomponents.OptionsPanel interface to help. This interface requires the \c store() and \c load() functions also be provided in the separate panels, allowing for easier child storing and loading.
|
Select Create Primary Panel, name the panel (preferably with the module's name), select an icon, and add keywords, then click Next and Finish. Note that NetBeans will automatically copy the selected icon to the module's directory if not already there.
|
||||||
|
|
||||||
Any storing or loading of settings or properties should be done in the \c store() and \c load() methods. Continue to \ref mod_dev_properties for more details.
|
NetBeans will generate two Java files for you, the panel and the controller. For now, we only need to focus on the panel.
|
||||||
|
|
||||||
|
First, use NetBeans' GUI builder to design the panel. Be sure to include all options, settings, preferences, etc for the module, as this is what the user will see. The recommended size of an options panel is about 675 x 500.
|
||||||
|
|
||||||
\section mod_dev_properties Saving Settings and Properties
|
Second, in the source code of the panel, there are two important methods: \c load() and \c store(). When the options panel is opened via Tools > Options in Autopsy, the \c load() method will be called. Conversely, when the user presses OK after editing the options, the \c store() method will be called.
|
||||||
|
|
||||||
It is recommended to have the module settings persistent, so that when a change is made and Autopsy is re-opened
|
If one wishes to make any additional panels within the original options panel, or panels which the original opens, Autopsy provides the org.sleuthkit.autopsy.corecomponents.OptionsPanel interface to help. This interface requires the \c store() and \c load() functions also be provided in the separate panels, allowing for easier child storing and loading.
|
||||||
the user made changes remain effective and not reset back to defaults.
|
|
||||||
Use org.sleuthkit.autopsy.coreutils.ModuleSettings class for saving and reading back settings for your module.
|
Any storing or loading of settings or properties should be done in the \c store() and \c load() methods. Continue to \ref mod_dev_properties for more details.
|
||||||
|
|
||||||
|
|
||||||
\section mod_dev_events Registering for events
|
|
||||||
|
|
||||||
Modules may want to register for case change events using org.sleuthkit.autopsy.casemodule.Case.addPropertyChangeListener() method.
|
\subsection mod_dev_adv_properties Saving Settings and Properties
|
||||||
Modules may want to reinitialize and update their data views as case is changed.
|
|
||||||
|
It is recommended to have the module settings persistent, so that when a change is made and Autopsy is re-opened
|
||||||
If a module is a viewer interested in knowing when new data is available from ingest, it can register for listening of the ingest result updates using:
|
the user made changes remain effective and not reset back to defaults.
|
||||||
org.sleuthkit.autopsy.ingest.IngestManager.addPropertyChangeListener()
|
Use org.sleuthkit.autopsy.coreutils.ModuleSettings class for saving and reading back settings for your module.
|
||||||
|
|
||||||
When developing Ingest modules specifically - their life cycle is managed by ingest manager
|
|
||||||
and an ingest module does not need to listen for case change events
|
\subsection mod_dev_adv_events Registering for Events
|
||||||
or other general system-wide events.
|
|
||||||
However, it should make sure that it gets a new handle to the current Case every time the module's init() is invoked.
|
Autopsy will generate events as the application runs and modules may want to listen for those events so that they can change their state. There is not an exhaustive list of events, but here are some common ones to listen for:
|
||||||
|
|
||||||
|
- Case change events occur when a case is opened, closed, or changed. The org.sleuthkit.autopsy.casemodule.Case.addPropertyChangeListener() method can be used for this.
|
||||||
\section mod_dev_plugin Adding a Module to Autopsy
|
- IngestManager events occur when new results are available. The org.sleuthkit.autopsy.ingest.IngestManager.addPropertyChangeListener() method can be used for this.
|
||||||
|
|
||||||
When the module is created and ready for use, it can be added to Autopsy via the plugins menu.
|
|
||||||
|
*/
|
||||||
The plugins menu can be used to add modules (i.e. plugins) to Autopsy in a number of different ways, the simplest of which is through an NBM file.
|
|
||||||
|
|
||||||
To generate an NBM file, right click on the module and select Create NBM.
|
|
||||||
|
|
||||||
Then, launch Autopsy and choose Plugins under the Tools menu. Open the Downloaded tab and click Add Plugins. Navigate to the NBM file and open it. Next, click Install and follow the wizard. Autopsy will require a restart after installing the module, but afterwards the plugin will be integrated into Autopsy.
|
|
||||||
|
|
||||||
The options to uninstall or temporarily disable a plugin are also available under the plugins menu.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
@ -1,413 +1,412 @@
|
|||||||
/*! \page mod_ingest_page Developing Ingest Modules
|
/*! \page mod_ingest_page Developing Ingest Modules
|
||||||
|
|
||||||
|
|
||||||
\section ingestmodule_modules Ingest Module Basics
|
\section ingestmodule_modules Ingest Module Basics
|
||||||
|
|
||||||
Ingest modules analyze data from a disk image.
|
This section tells you how to make an Ingest Module.
|
||||||
They typically focus on a specific type of data analysis.
|
Ingest modules analyze data from a disk image.
|
||||||
The modules are loaded each time that Autopsy starts.
|
They typically focus on a specific type of data analysis.
|
||||||
The user can choose to enable each module when they add an image to the case.
|
The modules are loaded each time that Autopsy starts.
|
||||||
|
The user can choose to enable each module when they add an image to the case. It assumes you have already setup your development environment as described in \ref mod_dev_page.
|
||||||
There are two types of ingest modules.
|
|
||||||
- Image-level modules are passed in a reference to an image and perform general analysis on it.
|
First, you need to choose the type of Ingest Module.
|
||||||
These modules may query the database for a small set of specific files, thus are generally quicker to execute.
|
|
||||||
|
- Image-level modules are passed in a reference to an image and perform general analysis on it.
|
||||||
- File-level modules are passed in a reference to each file.
|
These modules may query the database for a small set of specific files. For example, a Windows registry module that runs on the hive files. It is interested in only a small subset of the hard drive files.
|
||||||
The Ingest Manager chooses which files to pass and when.
|
|
||||||
These modules are intended to analyze most of the files on the system
|
- File-level modules are passed in a reference to each file.
|
||||||
or that want to examine the file content of all files
|
The Ingest Manager chooses which files to pass and when.
|
||||||
(i.e. to detect file type based on signature instead of file extension).
|
These modules are intended to analyze most of the files on the system
|
||||||
|
For example, a hash calculation module that reads in the content of every file.
|
||||||
An example of Image-level module is a registry module, that extracts only the registry files.
|
|
||||||
An example of File-level module is a search module, that indexes and searches content of every file.
|
|
||||||
|
|
||||||
Modules post their results to the \ref platform_blackboard
|
Refer to org.sleuthkit.autopsy.ingest.example for sample source code of dummy modules.
|
||||||
(@@@ NEED REFERENCE FOR THIS -- org.sleuthkit.datamodel)
|
|
||||||
and can query the blackboard to get the results of previous modules.
|
\section ingest_common Commonalities
|
||||||
For example, the hash database lookup module may want to query for a previously calculated hash value.
|
|
||||||
|
There are several things about these module types that are common and we'll outline those here. For both modules, you will extend an interface and implement some methods.
|
||||||
|
|
||||||
|
Refer to the documentation for each method for its use.
|
||||||
\section ingestmodule_relevant_api Relevant APIs
|
- org.sleuthkit.autopsy.ingest.IngestModuleAbstract.init() is invoked when an ingest session starts.
|
||||||
|
- org.sleuthkit.autopsy.ingest.IngestModuleAbstract.complete() is invoked when an ingest session completes.
|
||||||
Relevant APIs to a ingest module writer are:
|
- org.sleuthkit.autopsy.ingest.IngestModuleAbstract.stop() is invoked on a module when an ingest session is interrupted by the user or system.
|
||||||
|
- org.sleuthkit.autopsy.ingest.IngestModuleAbstract.getName() returns the name of the module.
|
||||||
- The org.sleuthkit.autopsy.ingest.IngestServices class, which contains methods to post ingest results and
|
- org.sleuthkit.autopsy.ingest.IngestModuleAbstract.getDescription() returns a short description of the module.
|
||||||
to get access to services in the framework (Case and blackboard, logging, configuration , and others).
|
- org.sleuthkit.autopsy.ingest.IngestModuleAbstract.getVersion() returns the version of the module.
|
||||||
- Interfaces org.sleuthkit.autopsy.ingest.IngestModuleAbstractFile and org.sleuthkit.autopsy.ingest.IngestModuleImage, one of which needs to be implemented by the module.
|
|
||||||
There is also a parent interface, org.sleuthkit.autopsy.ingest.IngestModuleAbstract, common to all ingest modules.
|
|
||||||
- Additional utilities in the Autopsy \ref org.sleuthkit.autopsy.coreutils module for getting information about the platform,
|
The process() method is invoked to analyze the data. This is where the analysis is done. The specific method depends on the module type; it is passed
|
||||||
versions and for file operations.
|
either an Image or a File to process. We'll cover this in later sections. This method will post results to the blackboard
|
||||||
|
and with inbox messages to the user.
|
||||||
|
|
||||||
\section ingestmodule_making Making Ingest Modules
|
|
||||||
|
\section ingest_image Image-level Modules
|
||||||
First, you will need to setup your environment and
|
|
||||||
make a new Autopsy module using Netbeans IDE. Refer to \ref mod_dev_page for general instructions.
|
To make an Image-level module, make a new Java class either manually or using the NetBeans wizards. Edit the class to extend "org.sleuthkit.autopsy.ingest.IngestModuleImage". NetBeans will likely complain that you have not implemented the necessary methods and you can use its "hints" to automatically generate stubs for them. Use the links above to fill in the details.
|
||||||
|
|
||||||
Refer to org.sleuthkit.autopsy.ingest.example for sample source code of dummy modules.
|
The org.sleuthkit.autopsy.ingest.IngestModuleImage.process() method gets several objects passed in.
|
||||||
|
get a reference to org.sleuthkit.autopsy.ingest.IngestImageWorkerController object.
|
||||||
\subsection ingestmodule_making_api Module Interface
|
|
||||||
|
They should use this object to:
|
||||||
The next step is to choose the correct module type and implement the correct interface.
|
- report progress (number of work units processed),
|
||||||
|
- add thread cancellation support.
|
||||||
Image-level modules will implement the org.sleuthkit.autopsy.ingest.IngestModuleImage interface
|
|
||||||
and file-level modules will implement the org.sleuthkit.autopsy.ingest.IngestModuleAbstractFile interface.
|
New instances of image-level modules will be created when the second image is added.
|
||||||
|
Therefore, image-level modules can assume that the process() method will be called at most once after init() is called.
|
||||||
|
|
||||||
The interfaces have several standard methods that need to be implemented:
|
|
||||||
|
Example snippet of an ingest-level module process() method:
|
||||||
- org.sleuthkit.autopsy.ingest.IngestModuleAbstract.init() is invoked every time an ingest session starts by the framework.
|
|
||||||
A module should support multiple invocations of init() throughout the application life-cycle.
|
|
||||||
|
\code
|
||||||
In this method, module should reinitialize its internal objects and resources and get them ready
|
@Override
|
||||||
for a brand new ingest processing.
|
public void process(Image image, IngestImageWorkerController controller) {
|
||||||
|
|
||||||
At minimum, the module should get a handle to the ingest services using
|
//we have some number workunits / sub-tasks to execute
|
||||||
org.sleuthkit.autopsy.ingest.IngestServices.getDefault().
|
//in this case, we know the number of total tasks in advance
|
||||||
If the module posts results, then it needs the blackboard API; the module should get
|
final int totalTasks = 12;
|
||||||
an updated handle to the current Case database (and the blackboard API)
|
|
||||||
using org.sleuthkit.autopsy.ingest.IngestServices.getCurrentSleuthkitCaseDb().
|
//initialize the overall image ingest progress
|
||||||
This gives access to the underlying datamodel for the current Case.
|
controller.switchToDeterminate();
|
||||||
Make sure not to store stale handles to Case objects across ingests,
|
controller.progress(totalTasks);
|
||||||
because Case can likely be changed for the next ingest.
|
|
||||||
|
for(int subTask = 0; subTask < totalTasks; ++subTask) {
|
||||||
|
//add cancellation support
|
||||||
- org.sleuthkit.autopsy.ingest.IngestModuleAbstract.complete() is invoked when an ingest session completes.
|
if (controller.isCancelled() ) {
|
||||||
The module should perform any resource (files, handles, caches) cleanup in this method
|
break; // break out early to let the thread terminate
|
||||||
and submit final results and post a final ingest inbox message, using org.sleuthkit.autopsy.ingest.IngestServices.
|
}
|
||||||
|
|
||||||
- org.sleuthkit.autopsy.ingest.IngestModuleAbstract.stop() is invoked on a module when an ingest session is interrupted by the user or by the system.
|
//do the work
|
||||||
The method implementation should be similar to complete() in that the module should perform any cleanup work.
|
try {
|
||||||
If there is pending data to be processed or pending results to be reported by the module
|
//sub-task may add blackboard artifacts and create an inbox message
|
||||||
then the results should be rejected and ignored if stop()
|
performSubTask(i);
|
||||||
is invoked and the method should return as early as possible.
|
} catch (Exception ex) {
|
||||||
|
logger.log(Level.WARNING, "Exception occurred in subtask " + subTask, ex);
|
||||||
The main difference between complete() and stop() is that stop() does not need to worry about
|
}
|
||||||
finalizing and reporting final results, it can simply reject them.
|
|
||||||
The quicker it acts, the easier it will for the application to transition to the next state.
|
//update progress
|
||||||
|
controller.progress(i+1);
|
||||||
- process() method is invoked to analyze the data. The specific method depends on the module type; it is passed
|
}
|
||||||
either an Image or a File to process.
|
}
|
||||||
|
\endcode
|
||||||
\subsubsection ingestmodule_making_process Process Method
|
|
||||||
The process method is where the work is done in each type of module, on the Image of File passed as an argument.
|
|
||||||
|
\section ingest_file File-level Modules
|
||||||
Once a result is found, in this method the module should post result to the blackboard
|
|
||||||
and it could post an inbox message to the user.
|
To make a File-level module, make a new Java class either manually or using the NetBeans wizards. Edit the class to extend "org.sleuthkit.autopsy.ingest.IngestModuleAbstractFile". NetBeans will likely complain that you have not implemented the necessary methods and you can use its "hints" to automatically generate stubs for them. Use the links above to fill in the details.
|
||||||
|
|
||||||
Some notes:
|
File-level modules are singletons. Only a single instance is created for all files.
|
||||||
- File-level modules will be called on each file in an order determined by the org.sleuthkit.autopsy.ingest.IngestManager.
|
The same file-level module instance can be invoked again by the org.sleuthkit.autopsy.ingest.IngestManager when more work is enqueued or
|
||||||
Each module is free to quickly ignore a file based on name, signature, etc.
|
when ingest is restarted. The same file-level ingest module instance can also be invoked for different Cases or files from different images in the Case.
|
||||||
|
|
||||||
- If a module wants to know the return value from a previously run module on this file,
|
Every file-level module should support multiple init() -> process() -> complete(), and init() -> process() -> stop() invocations. It shoudl also support init() -> complete() sequences.
|
||||||
it should use the org.sleuthkit.autopsy.ingest.IngestServices.getAbstractFileModuleResult() method.
|
|
||||||
|
|
||||||
- Image-level modules are expected not passed in specific files and are expected to query the database
|
------
|
||||||
to find the files that they are interested in. They can use the org.sleuthkit.datamodel.SleuthkitCase object handle (initialized in the init() method) to query the database.
|
|
||||||
|
|
||||||
- File-level module could be passed in files from different images in consecutive calls to process().
|
|
||||||
|
|
||||||
|
|
||||||
\subsubsection ingestmodule_making_process_controller Image Ingest Controller (Image-level modules only)
|
\subsection ingestmodule_additional_method Additional Methods to Implement
|
||||||
|
MOVE THIS TO COMMON
|
||||||
Image-level modules receive in org.sleuthkit.autopsy.ingest.IngestModuleImage.process() method
|
|
||||||
get a reference to org.sleuthkit.autopsy.ingest.IngestImageWorkerController object.
|
Besides methods defined in the interfaces, you will need to implement
|
||||||
|
a public static getDefault() method (both for an image or a file module), which needs
|
||||||
They should use this object to:
|
to return a static instance of the module. This is required for proper module registration.
|
||||||
|
|
||||||
- report progress (number of work units processed),
|
Presence of that method is validated when the module is loaded, and the module will fail validation
|
||||||
- add thread cancellation support.
|
and will not be loaded if the method is not implemented.
|
||||||
|
|
||||||
Example snippet of an ingest-level module process() method:
|
The implementation of this method is very standard, example:
|
||||||
|
|
||||||
|
\code
|
||||||
\code
|
public static synchronized MyIngestModule getDefault() {
|
||||||
@Override
|
|
||||||
public void process(Image image, IngestImageWorkerController controller) {
|
//defaultInstance is a private static class variable
|
||||||
|
if (defaultInstance == null) {
|
||||||
//we have some number workunits / sub-tasks to execute
|
defaultInstance = new MyIngestModule();
|
||||||
//in this case, we know the number of total tasks in advance
|
}
|
||||||
final int totalTasks = 12;
|
return defaultInstance;
|
||||||
|
}
|
||||||
//initialize the overall image ingest progress
|
\endcode
|
||||||
controller.switchToDeterminate();
|
|
||||||
controller.progress(totalTasks);
|
|
||||||
|
File-level modules need to be singleton. To ensure this, make the constructor private.
|
||||||
for(int subTask = 0; subTask < totalTasks; ++subTask) {
|
|
||||||
//add cancellation support
|
Image-level modules require a public constructor.
|
||||||
if (controller.isCancelled() ) {
|
|
||||||
break; // break out early to let the thread terminate
|
|
||||||
}
|
\subsection ingestmodule_making_registration Module Registration
|
||||||
|
|
||||||
//do the work
|
Modules are automatically discovered and registered when \ref mod_dev_plugin "added as a plugin to Autopsy".
|
||||||
try {
|
Currently, a restart of Autopsy is required for the newly discovered ingest module to be fully registered and functional.
|
||||||
//sub-task may add blackboard artifacts and create an inbox message
|
All you need to worry about is to implement the ingest module interface and the required methods and the module will be
|
||||||
performSubTask(i);
|
automatically discovered by the framework.
|
||||||
} catch (Exception ex) {
|
|
||||||
logger.log(Level.WARNING, "Exception occurred in subtask " + subTask, ex);
|
\subsubsection ingestmodule_making_registration_pipeline_config Pipeline Configuration
|
||||||
}
|
|
||||||
|
Autopsy maintains an ordered list of autodiscovered modules. The order of a module in the pipeline determines
|
||||||
//update progress
|
when it will be run relative to other modules. The order can be important for some modules and it can be adjusted.
|
||||||
controller.progress(i+1);
|
|
||||||
}
|
When a module is installed using the plugin installer, it is automatically discovered and validated.
|
||||||
}
|
The validation process ensures that the module meets the inter-module dependencies, implements the right interfaces and methods
|
||||||
\endcode
|
and meets constrains enforced by the schema. If the module is valid, it is registered and added to the right pipeline
|
||||||
|
based on the interfaces it implements, and the pipeline configuration is updated with the new module.
|
||||||
|
If the module is not already known to the pipeline configuration, it gets the default order assigned --
|
||||||
\subsection ingestmodule_module_lifecycle Module Lifecycle
|
it is added to the end of the pipeline.
|
||||||
|
|
||||||
File-level modules are singletons and are long-lived and image-level modules are short lived.
|
If the module is invalid, it will still be added to the pipeline configuration, but it will not be instantiated.
|
||||||
The same file-level module instance can be invoked again by the org.sleuthkit.autopsy.ingest.IngestManager when more work is enqueued or
|
It will be re-validated again next time the module discovery runs. The validation process logs its results to the main
|
||||||
when ingest is restarted. The same file-level ingest module instance can also be invoked for different Cases or files from different images in the Case.
|
Autopsy log files.
|
||||||
|
|
||||||
Every file-level module should support multiple init() - process() - complete(), and init() - process() - stop() invocations.
|
The pipeline configuration is an XML file with currently discovered modules
|
||||||
|
and the modules that were discovered in the past but are not currently loaded.
|
||||||
New instances of image-level modules will be created when the second image is added.
|
Autopsy maintains that file in the Autopsy user configuration directory.
|
||||||
Therefore, image-level modules can assume that the process() method will be called at most once after init() is called.
|
The XML file defines the module location, its place in the ingest pipeline, along with optional configuration arguments.
|
||||||
|
The example of the pipeline configuration is given below:
|
||||||
Every module (file or image) should also support multiple init() - complete() and init() - stop() invocations,
|
|
||||||
which can occur if ingest pipeline is started but no work is enqueued for the particular module.
|
\code
|
||||||
|
<PIPELINE_CONFIG>
|
||||||
\subsection ingestmodule_additional_method Additional Methods to Implement
|
<PIPELINE type="FileAnalysis">
|
||||||
|
<MODULE order="1" type="plugin" location="org.sleuthkit.autopsy.hashdatabase.HashDbIngestModule" arguments="" />
|
||||||
Besides methods defined in the interfaces, you will need to implement
|
<MODULE order="2" type="plugin" location="org.sleuthkit.autopsy.exifparser.ExifParserFileIngestModule"/>
|
||||||
a public static getDefault() method (both for an image or a file module), which needs
|
</PIPELINE>
|
||||||
to return a static instance of the module. This is required for proper module registration.
|
|
||||||
|
<PIPELINE type="ImageAnalysis">
|
||||||
Presence of that method is validated when the module is loaded, and the module will fail validation
|
<MODULE order="1" type="plugin" location="org.sleuthkit.autopsy.recentactivity.RAImageIngestModule" arguments=""/>
|
||||||
and will not be loaded if the method is not implemented.
|
</PIPELINE>
|
||||||
|
</PIPELINE_CONFIG>
|
||||||
The implementation of this method is very standard, example:
|
\endcode
|
||||||
|
|
||||||
\code
|
Refer to http://sleuthkit.org/sleuthkit/docs/framework-docs/pipeline_config_page.html which is an official documentation
|
||||||
public static synchronized MyIngestModule getDefault() {
|
for the pipeline configuration schema.
|
||||||
|
|
||||||
//defaultInstance is a private static class variable
|
The pipeline configuration file should not be directly edited by a regular user,
|
||||||
if (defaultInstance == null) {
|
but it can be edited by a developer to test their module.
|
||||||
defaultInstance = new MyIngestModule();
|
|
||||||
}
|
Autopsy will provide tools for reconfiguring the ingest pipeline in the near future,
|
||||||
return defaultInstance;
|
and user/developer will be able to reload current view of discovered modules,
|
||||||
}
|
reorder modules in the pipeline and set their arguments using GUI.
|
||||||
\endcode
|
|
||||||
|
|
||||||
|
\subsection ingestmodule_using_services Using Ingest Services
|
||||||
File-level modules need to be singleton. To ensure this, make the constructor private.
|
|
||||||
|
Class org.sleuthkit.autopsy.ingest.IngestModuleServices provides services specifically for the ingest modules
|
||||||
Image-level modules require a public constructor.
|
and a module developer should use these utilities.
|
||||||
|
|
||||||
|
The class has methods for ingest modules to:
|
||||||
\subsection ingestmodule_making_registration Module Registration
|
- send ingest messages to the inbox,
|
||||||
|
- send new data events to registered listeners (such as viewers),
|
||||||
Modules are automatically discovered and registered when \ref mod_dev_plugin "added as a plugin to Autopsy".
|
- check for errors in the file-level pipeline,
|
||||||
Currently, a restart of Autopsy is required for the newly discovered ingest module to be fully registered and functional.
|
- getting access to org.sleuthkit.datamodel.SleuthkitCase database and the blackboard,
|
||||||
All you need to worry about is to implement the ingest module interface and the required methods and the module will be
|
- getting loggers,
|
||||||
automatically discovered by the framework.
|
- getting and setting module settings.
|
||||||
|
|
||||||
\subsubsection ingestmodule_making_registration_pipeline_config Pipeline Configuration
|
To use it, a handle to org.sleuthkit.autopsy.ingest.IngestServices singleton object should be initialized
|
||||||
|
in the module's \c init() method. For example:
|
||||||
Autopsy maintains an ordered list of autodiscovered modules. The order of a module in the pipeline determines
|
|
||||||
when it will be run relative to other modules. The order can be important for some modules and it can be adjusted.
|
\code
|
||||||
|
services = IngestServices.getDefault()
|
||||||
When a module is installed using the plugin installer, it is automatically discovered and validated.
|
\endcode
|
||||||
The validation process ensures that the module meets the inter-module dependencies, implements the right interfaces and methods
|
|
||||||
and meets constrains enforced by the schema. If the module is valid, it is registered and added to the right pipeline
|
It is safe to store handle to services in your module private member variable.
|
||||||
based on the interfaces it implements, and the pipeline configuration is updated with the new module.
|
|
||||||
If the module is not already known to the pipeline configuration, it gets the default order assigned --
|
However, DO NOT initialize the services handle statically in the member variable declaration.
|
||||||
it is added to the end of the pipeline.
|
Use the init() method to do that to ensure proper order of initialization of objects in the platform.
|
||||||
|
|
||||||
If the module is invalid, it will still be added to the pipeline configuration, but it will not be instantiated.
|
Module developers are encouraged to use Autopsy's org.sleuthkit.autopsy.coreutils.Logger
|
||||||
It will be re-validated again next time the module discovery runs. The validation process logs its results to the main
|
infrastructure to log errors to the Autopsy log.
|
||||||
Autopsy log files.
|
The logger can also be accessed using the org.sleuthkit.autopsy.ingest.IngestServices class.
|
||||||
|
|
||||||
The pipeline configuration is an XML file with currently discovered modules
|
Certain modules may need need a persistant store (other than for storing results) for storing and reading
|
||||||
and the modules that were discovered in the past but are not currently loaded.
|
module configurations or state.
|
||||||
Autopsy maintains that file in the Autopsy user configuration directory.
|
The ModuleSettings API can be used also via org.sleuthkit.autopsy.ingest.IngestServices class.
|
||||||
The XML file defines the module location, its place in the ingest pipeline, along with optional configuration arguments.
|
|
||||||
The example of the pipeline configuration is given below:
|
|
||||||
|
\subsection ingestmodule_making_results Posting Results
|
||||||
\code
|
|
||||||
<PIPELINE_CONFIG>
|
<!-- @@@ -->
|
||||||
<PIPELINE type="FileAnalysis">
|
NOTE: This needs to be made more in sync with the \ref platform_blackboard. This section (or one near this) needs to be the sole source of ingest inbox API information.
|
||||||
<MODULE order="1" type="plugin" location="org.sleuthkit.autopsy.hashdatabase.HashDbIngestModule" arguments="" />
|
|
||||||
<MODULE order="2" type="plugin" location="org.sleuthkit.autopsy.exifparser.ExifParserFileIngestModule"/>
|
Users will see the results from ingest modules in one of two ways:
|
||||||
</PIPELINE>
|
- Results are posted to the blackboard and will be displayed in the navigation tree
|
||||||
|
- For selected results, messages are sent to the Ingest Inbox to notify a user of what has recently been found.
|
||||||
<PIPELINE type="ImageAnalysis">
|
|
||||||
<MODULE order="1" type="plugin" location="org.sleuthkit.autopsy.recentactivity.RAImageIngestModule" arguments=""/>
|
\subsubsection ingestmodule_making_results_bb Posting Results to Blackboard
|
||||||
</PIPELINE>
|
|
||||||
</PIPELINE_CONFIG>
|
See the Blackboard (REFERENCE) documentation for posting results to it.
|
||||||
\endcode
|
|
||||||
|
Modules are free to immediately post results when they find them
|
||||||
Refer to http://sleuthkit.org/sleuthkit/docs/framework-docs/pipeline_config_page.html which is an official documentation
|
or they can wait until they are ready to post the results or until ingest is done.
|
||||||
for the pipeline configuration schema.
|
|
||||||
|
An example of waiting to post results is the keyword search module.
|
||||||
The pipeline configuration file should not be directly edited by a regular user,
|
It is resource intensive to commit the keyword index and do a keyword search.
|
||||||
but it can be edited by a developer to test their module.
|
Therefore, when its process() method is invoked,
|
||||||
|
it checks if it is internal timer and result posting frequency setting
|
||||||
Autopsy will provide tools for reconfiguring the ingest pipeline in the near future,
|
to check if it is close to it since the last time it did a keyword search.
|
||||||
and user/developer will be able to reload current view of discovered modules,
|
If it is, then it commits the index and performs the search.
|
||||||
reorder modules in the pipeline and set their arguments using GUI.
|
|
||||||
|
When modules add data to the blackboard,
|
||||||
|
modules should notify listeners of the new data by
|
||||||
\subsection ingestmodule_using_services Using Ingest Services
|
invoking IngestServices.fireModuleDataEvent() method.
|
||||||
|
Do so as soon as you have added an artifact to the blackboard.
|
||||||
Class org.sleuthkit.autopsy.ingest.IngestModuleServices provides services specifically for the ingest modules
|
This allows other modules (and the main UI) to know when to query the blackboard for the latest data.
|
||||||
and a module developer should use these utilities.
|
However, if you are writing a larger number of blackboard artifacts in a loop, it is better to invoke
|
||||||
|
IngestServices.fireModuleDataEvent() only once after the bulk write, not to flood the system with events.
|
||||||
The class has methods for ingest modules to:
|
|
||||||
- send ingest messages to the inbox,
|
\subsubsection ingestmodule_making_results_inbox Posting Results to Message Inbox
|
||||||
- send new data events to registered listeners (such as viewers),
|
|
||||||
- check for errors in the file-level pipeline,
|
Modules should post messages to the inbox when interesting data is found and has been posted to the blackboard.
|
||||||
- getting access to org.sleuthkit.datamodel.SleuthkitCase database and the blackboard,
|
|
||||||
- getting loggers,
|
A single message includes the module name, message subject, message details,
|
||||||
- getting and setting module settings.
|
a unique message id (in the context of the originating module), and a uniqueness attribute.
|
||||||
|
The uniqueness attribute is used to group similar messages together
|
||||||
To use it, a handle to org.sleuthkit.autopsy.ingest.IngestServices singleton object should be initialized
|
and to determine the overall importance priority of the message
|
||||||
in the module's \c init() method. For example:
|
(if the same message is seen repeatedly, it is considered lower priority).
|
||||||
|
|
||||||
\code
|
For example, for a keyword search module, the uniqueness attribute would the keyword that was hit.
|
||||||
services = IngestServices.getDefault()
|
|
||||||
\endcode
|
It is important though to not fill up the inbox with messages. Do not post an inbox message for every
|
||||||
|
result artifact written to the blackboard.
|
||||||
It is safe to store handle to services in your module private member variable.
|
|
||||||
|
These messages should only be sent if the result has a low false positive rate and will likely be relevant.
|
||||||
However, DO NOT initialize the services handle statically in the member variable declaration.
|
For example, the hash lookup module will send messages if known bad (notable) files are found,
|
||||||
Use the init() method to do that to ensure proper order of initialization of objects in the platform.
|
but not if known good (NSRL) files are found.
|
||||||
|
The keyword search module will send messages if a specific keyword matches,
|
||||||
Module developers are encouraged to use Autopsy's org.sleuthkit.autopsy.coreutils.Logger
|
but will not send messages (by default) if a regular expression match for a URL has matches
|
||||||
infrastructure to log errors to the Autopsy log.
|
(because a lot of the URL hits will be false positives and can generate thousands of messages on a typical system).
|
||||||
The logger can also be accessed using the org.sleuthkit.autopsy.ingest.IngestServices class.
|
|
||||||
|
|
||||||
Certain modules may need need a persistant store (other than for storing results) for storing and reading
|
Ingest messages have different types:
|
||||||
module configurations or state.
|
there are info messages, warning messages, error messages and data messages.
|
||||||
The ModuleSettings API can be used also via org.sleuthkit.autopsy.ingest.IngestServices class.
|
|
||||||
|
Modules will mostly post data messages about the most relevant results.
|
||||||
|
The data messages contain encapsulated blackboard artifacts and attributes.
|
||||||
\subsection ingestmodule_making_results Posting Results
|
The passed in data is used by the ingest inbox GUI widget to navigate
|
||||||
|
to the artifact view in the directory tree, if requested by the user.
|
||||||
<!-- @@@ -->
|
|
||||||
NOTE: This needs to be made more in sync with the \ref platform_blackboard. This section (or one near this) needs to be the sole source of ingest inbox API information.
|
Ingest message API is defined in IngestMessage class.
|
||||||
|
The class also contains factory methods to create new messages.
|
||||||
Users will see the results from ingest modules in one of two ways:
|
Messages are posted using IngestServices.postMessage() method,
|
||||||
- Results are posted to the blackboard and will be displayed in the navigation tree
|
which accepts a message object created using one of the factory methods.
|
||||||
- For selected results, messages are sent to the Ingest Inbox to notify a user of what has recently been found.
|
|
||||||
|
Modules should post info messages (with no data) to the inbox
|
||||||
\subsubsection ingestmodule_making_results_bb Posting Results to Blackboard
|
at minimum when stop() or complete() is invoked (refer to the examples).
|
||||||
|
It is recommended to populate the description field of the complete inbox message to provide feedback to the user
|
||||||
See the Blackboard (REFERENCE) documentation for posting results to it.
|
summarizing the module ingest run and if any errors were encountered.
|
||||||
|
|
||||||
Modules are free to immediately post results when they find them
|
Modules should also post high-level error messages (e.g. without flooding the inbox
|
||||||
or they can wait until they are ready to post the results or until ingest is done.
|
when the same error encountered for a large number of files).
|
||||||
|
|
||||||
An example of waiting to post results is the keyword search module.
|
|
||||||
It is resource intensive to commit the keyword index and do a keyword search.
|
\subsection ingestmodule_making_configuration Module Configuration
|
||||||
Therefore, when its process() method is invoked,
|
|
||||||
it checks if it is internal timer and result posting frequency setting
|
<!-- @@@ -->
|
||||||
to check if it is close to it since the last time it did a keyword search.
|
NOTE: Make sure we update this to reflect \ref mod_dev_properties and reduce duplicate comments.
|
||||||
If it is, then it commits the index and performs the search.
|
|
||||||
|
Ingest modules may require user configuration. The framework
|
||||||
When modules add data to the blackboard,
|
supports two levels of configuration: run-time and general. Run-time configuration
|
||||||
modules should notify listeners of the new data by
|
occurs when the user selects which ingest modules to run when an image is added. This level
|
||||||
invoking IngestServices.fireModuleDataEvent() method.
|
of configuration should allow the user to enable or disable settings. General configuration is more in-depth and
|
||||||
Do so as soon as you have added an artifact to the blackboard.
|
may require an interface that is more powerful than simple check boxes.
|
||||||
This allows other modules (and the main UI) to know when to query the blackboard for the latest data.
|
|
||||||
However, if you are writing a larger number of blackboard artifacts in a loop, it is better to invoke
|
As an example, the keyword search module uses both configuration methods. The run-time configuration allows the user
|
||||||
IngestServices.fireModuleDataEvent() only once after the bulk write, not to flood the system with events.
|
to choose which lists of keywords to search for. However, if the user wants to edit the lists or create lists, they
|
||||||
|
need to do go the general configuration window.
|
||||||
\subsubsection ingestmodule_making_results_inbox Posting Results to Message Inbox
|
|
||||||
|
Module configuration is module-specific: every module maintains its own configuration state and is responsible for implementing the graphical interface. However, Autopsy does provide \ref mod_dev_configuration "a centralized location to display your settings to the user".
|
||||||
Modules should post messages to the inbox when interesting data is found and has been posted to the blackboard.
|
|
||||||
|
The run-time configuration (also called simple configuration), is achieved by each
|
||||||
A single message includes the module name, message subject, message details,
|
ingest module providing a JPanel. The IngestModuleAbstract.hasSimpleConfiguration(),
|
||||||
a unique message id (in the context of the originating module), and a uniqueness attribute.
|
IngestModuleAbstract.getSimpleConfiguration(), and IngestModuleAbstract.saveSimpleConfiguration()
|
||||||
The uniqueness attribute is used to group similar messages together
|
methods should be used for run-time configuration.
|
||||||
and to determine the overall importance priority of the message
|
|
||||||
(if the same message is seen repeatedly, it is considered lower priority).
|
The general configuration is also achieved by the module returning a JPanel. A link will be provided to the general configuration from the ingest manager if it exists.
|
||||||
|
The IngestModuleAbstract.hasAdvancedConfiguration(),
|
||||||
For example, for a keyword search module, the uniqueness attribute would the keyword that was hit.
|
IngestModuleAbstract.getAdvancedConfiguration(), and IngestModuleAbstract.saveAdvancedConfiguration()
|
||||||
|
methods should be used for general configuration.
|
||||||
It is important though to not fill up the inbox with messages. Do not post an inbox message for every
|
|
||||||
result artifact written to the blackboard.
|
|
||||||
|
|
||||||
These messages should only be sent if the result has a low false positive rate and will likely be relevant.
|
\section ingestmodule_events Getting Ingest Status and Events
|
||||||
For example, the hash lookup module will send messages if known bad (notable) files are found,
|
|
||||||
but not if known good (NSRL) files are found.
|
<!-- @@@ -->
|
||||||
The keyword search module will send messages if a specific keyword matches,
|
NOTE: Sync this up with \ref mod_dev_events.
|
||||||
but will not send messages (by default) if a regular expression match for a URL has matches
|
|
||||||
(because a lot of the URL hits will be false positives and can generate thousands of messages on a typical system).
|
Other modules and core Autopsy classes may want to get the overall ingest status from the ingest manager.
|
||||||
|
The IngestManager handle is obtained using org.sleuthkit.autopsy.ingest.IngestManager.getDefault().
|
||||||
|
The manager provides access to ingest status with the
|
||||||
Ingest messages have different types:
|
org.sleuthkit.autopsy.ingest.IngestManager.isIngestRunning() method and related methods
|
||||||
there are info messages, warning messages, error messages and data messages.
|
that allow to query ingest status per specific module.
|
||||||
|
|
||||||
Modules will mostly post data messages about the most relevant results.
|
External modules (such as data viewers) can also register themselves as ingest module event listeners
|
||||||
The data messages contain encapsulated blackboard artifacts and attributes.
|
and receive event notifications (when a module is started, stopped, completed or has new data).
|
||||||
The passed in data is used by the ingest inbox GUI widget to navigate
|
Use the IngestManager.addPropertyChangeListener() method to register a module event listener.
|
||||||
to the artifact view in the directory tree, if requested by the user.
|
Events types received are defined in IngestManager.IngestModuleEvent enum.
|
||||||
|
|
||||||
Ingest message API is defined in IngestMessage class.
|
At the end of the ingest, IngestManager itself will notify all listeners of IngestModuleEvent.COMPLETED event.
|
||||||
The class also contains factory methods to create new messages.
|
The event is an indication for listeners to perform the final data refresh by quering the blackboard.
|
||||||
Messages are posted using IngestServices.postMessage() method,
|
Module developers are encouraged to generate periodic IngestModuleEvent.DATA
|
||||||
which accepts a message object created using one of the factory methods.
|
ModuleDataEvent events when they post data to the blackboard,
|
||||||
|
but the IngestManager will make a final event to handle scenarios where the module did not notify listeners while it was running.
|
||||||
Modules should post info messages (with no data) to the inbox
|
|
||||||
at minimum when stop() or complete() is invoked (refer to the examples).
|
|
||||||
It is recommended to populate the description field of the complete inbox message to provide feedback to the user
|
|
||||||
summarizing the module ingest run and if any errors were encountered.
|
|
||||||
|
---- MERGE THIS IN -----
|
||||||
Modules should also post high-level error messages (e.g. without flooding the inbox
|
\subsection mod_dev_configuration_ingest Ingest Dialog Panel
|
||||||
when the same error encountered for a large number of files).
|
|
||||||
|
Each ingest module has a small configuration panel when the user
|
||||||
|
|
||||||
\subsection ingestmodule_making_configuration Module Configuration
|
The ingest configuration dialog panel is displayed anytime ingest is to be started/restarted.
|
||||||
|
It provides framework for two-levels of settings: "simple panel" as well as an "advanced panel".
|
||||||
<!-- @@@ -->
|
The simple panel is shown directly in the ingest configuration panel on the right-hand side when a specific module is selected.
|
||||||
NOTE: Make sure we update this to reflect \ref mod_dev_properties and reduce duplicate comments.
|
The advanced panel is opened in a new window if the user presses the Advanced button in the ingest configuration dialog.
|
||||||
|
|
||||||
Ingest modules may require user configuration. The framework
|
Both of these panels can be created as a standard \c JPanel, and returned by your ingest module using
|
||||||
supports two levels of configuration: run-time and general. Run-time configuration
|
of the the ingest module methods implemented, that are declared in the ingest module interface.
|
||||||
occurs when the user selects which ingest modules to run when an image is added. This level
|
|
||||||
of configuration should allow the user to enable or disable settings. General configuration is more in-depth and
|
It is recommended when making an ingest module to have the advanced panel also be accessible also via the main Options panel,
|
||||||
may require an interface that is more powerful than simple check boxes.
|
allowing the user access to the settings from Tools > Options and not only via the ingest module configuration.
|
||||||
|
|
||||||
As an example, the keyword search module uses both configuration methods. The run-time configuration allows the user
|
See \ref ingestmodule_making_configuration how to implement hooks for having your ingest module configurations registered.
|
||||||
to choose which lists of keywords to search for. However, if the user wants to edit the lists or create lists, they
|
|
||||||
need to do go the general configuration window.
|
|
||||||
|
----- MERGE THIS IN ----
|
||||||
Module configuration is module-specific: every module maintains its own configuration state and is responsible for implementing the graphical interface. However, Autopsy does provide \ref mod_dev_configuration "a centralized location to display your settings to the user".
|
When developing Ingest modules specifically - their life cycle is managed by ingest manager
|
||||||
|
and an ingest module does not need to listen for case change events
|
||||||
The run-time configuration (also called simple configuration), is achieved by each
|
or other general system-wide events.
|
||||||
ingest module providing a JPanel. The IngestModuleAbstract.hasSimpleConfiguration(),
|
However, it should make sure that it gets a new handle to the current Case every time the module's init() is invoked.
|
||||||
IngestModuleAbstract.getSimpleConfiguration(), and IngestModuleAbstract.saveSimpleConfiguration()
|
|
||||||
methods should be used for run-time configuration.
|
|
||||||
|
---- MERGE
|
||||||
The general configuration is also achieved by the module returning a JPanel. A link will be provided to the general configuration from the ingest manager if it exists.
|
\section ingestmodule_relevant_api Relevant APIs
|
||||||
The IngestModuleAbstract.hasAdvancedConfiguration(),
|
|
||||||
IngestModuleAbstract.getAdvancedConfiguration(), and IngestModuleAbstract.saveAdvancedConfiguration()
|
Relevant APIs to a ingest module writer are:
|
||||||
methods should be used for general configuration.
|
|
||||||
|
- The org.sleuthkit.autopsy.ingest.IngestServices class, which contains methods to post ingest results and
|
||||||
|
to get access to services in the framework (Case and blackboard, logging, configuration , and others).
|
||||||
|
- Interfaces org.sleuthkit.autopsy.ingest.IngestModuleAbstractFile and org.sleuthkit.autopsy.ingest.IngestModuleImage, one of which needs to be implemented by the module.
|
||||||
\section ingestmodule_events Getting Ingest Status and Events
|
There is also a parent interface, org.sleuthkit.autopsy.ingest.IngestModuleAbstract, common to all ingest modules.
|
||||||
|
- Additional utilities in the Autopsy \ref org.sleuthkit.autopsy.coreutils module for getting information about the platform,
|
||||||
<!-- @@@ -->
|
versions and for file operations.
|
||||||
NOTE: Sync this up with \ref mod_dev_events.
|
|
||||||
|
|
||||||
Other modules and core Autopsy classes may want to get the overall ingest status from the ingest manager.
|
|
||||||
The IngestManager handle is obtained using org.sleuthkit.autopsy.ingest.IngestManager.getDefault().
|
-------
|
||||||
The manager provides access to ingest status with the
|
Some notes:
|
||||||
org.sleuthkit.autopsy.ingest.IngestManager.isIngestRunning() method and related methods
|
- File-level modules will be called on each file in an order determined by the org.sleuthkit.autopsy.ingest.IngestManager.
|
||||||
that allow to query ingest status per specific module.
|
Each module is free to quickly ignore a file based on name, signature, etc.
|
||||||
|
|
||||||
External modules (such as data viewers) can also register themselves as ingest module event listeners
|
- If a module wants to know the return value from a previously run module on this file,
|
||||||
and receive event notifications (when a module is started, stopped, completed or has new data).
|
it should use the org.sleuthkit.autopsy.ingest.IngestServices.getAbstractFileModuleResult() method.
|
||||||
Use the IngestManager.addPropertyChangeListener() method to register a module event listener.
|
|
||||||
Events types received are defined in IngestManager.IngestModuleEvent enum.
|
- Image-level modules are not passed in specific files and are expected to query the database
|
||||||
|
to find the files that they are interested in. They can use the org.sleuthkit.datamodel.SleuthkitCase object handle (initialized in the init() method) to query the database.
|
||||||
At the end of the ingest, IngestManager itself will notify all listeners of IngestModuleEvent.COMPLETED event.
|
|
||||||
The event is an indication for listeners to perform the final data refresh by quering the blackboard.
|
- File-level module could be passed in files from different images in consecutive calls to process().
|
||||||
Module developers are encouraged to generate periodic IngestModuleEvent.DATA
|
|
||||||
ModuleDataEvent events when they post data to the blackboard,
|
|
||||||
but the IngestManager will make a final event to handle scenarios where the module did not notify listeners while it was running.
|
*/
|
||||||
*/
|
|
||||||
|
34
docs/doxygen/needs_a_home.dox
Executable file
34
docs/doxygen/needs_a_home.dox
Executable file
@ -0,0 +1,34 @@
|
|||||||
|
|
||||||
|
<!-- @@@ MOVE THIS SOMEWHERE ELSE -- the directory tree package maybe?? -->
|
||||||
|
|
||||||
|
The component is by default registered with the ingest manager as an ingest event listener.
|
||||||
|
The viewer first loads all the viewer-supported data currently in the blackboard when Autopsy starts.
|
||||||
|
During the ingest process the viewer receives events from ingest modules
|
||||||
|
(relayed by ingest manager) and it selectively refreshes parts of the tree providing real-time updates to the user.
|
||||||
|
When ingest is completed, the viewer responds to the final ingest data event generated by the ingest manager,
|
||||||
|
and performs a final refresh of all viewer-supported data in the blackboard.
|
||||||
|
|
||||||
|
|
||||||
|
Node content support capabilities are registered in the node's Lookup.
|
||||||
|
|
||||||
|
|
||||||
|
<!-- @@@ This is too detailed for here, but maybe should be broken up and put into the sections on making a result viewer and such…
|
||||||
|
-->
|
||||||
|
|
||||||
|
\section design_data_flow Data Flow
|
||||||
|
|
||||||
|
\subsection design_data_flow_create Creating Nodes in DataExplorer
|
||||||
|
|
||||||
|
Data flows between the UI zones using a NetBeans node. The DataExplorer modules create the NetBeans nodes. They query the SQLite database or do whatever they want to identify the set of files that are of interest. They create the NetBeans nodes based on Sleuthkit data model objects. See the org.sleuthkit.autopsy.datamodel package for more details on this.
|
||||||
|
|
||||||
|
\subsection design_data_flow_toResult Getting Nodes to DataResult
|
||||||
|
|
||||||
|
Each DataExplorer TopComponent is responsible for creating its own DataResult TopComponent to display its results. It can choose to re-use the same TopComponent for multiple searches (as DirectoryTree does) or it can choose to make a new one each time (as FileSearch does). The setNode() method on the DataResult object is used to set the root node to display. A dummy root node must be created as the parent if a parent does not already exist.
|
||||||
|
|
||||||
|
The DataExplorer is responsible for setting the double-click and right-click actions associated with the node. The default single click action is to pass data to DataContent. To override this, you must create a new DataResultViewer instance that overrides the propertyChange() method. The DataExplorer adds actions to wrapping the node in a FilterNode variant. The FilterNode then defines the actions for the node by overriding the getPreferredAction() and getActions() methods. As an example, org.sleuthkit.autopsy.directorytree.DataResultFilterNode and org.sleuthkit.autopsy.directorytree.DataResultFilterChildren wraps the nodes that are passed over by the DirectoryTree DataExplorer.
|
||||||
|
|
||||||
|
DataResult can send data back to its DataExplorer by making a custom action that looks up it's instance (DataExplorer.getInstance()).
|
||||||
|
|
||||||
|
\subsection design_data_flow_toContent Getting Nodes to DataContent
|
||||||
|
|
||||||
|
A default DataContent viewer is created when a case is opened. To display the contents of a node, it must be passed to a DataContent instance. The default single-click behavior of the DataResultViewers is to lookup the default DataContent TopComponent and pass the selected node to it. See org.sleuthkit.autopsy.corecomponents.AbstractDataResultViewer.propertyChange(PropertyChangeEvent) for details.
|
@ -1,40 +1,42 @@
|
|||||||
/*! \page platform_page Platform Concepts
|
/*! \page platform_page Platform Concepts
|
||||||
|
|
||||||
\section platform_basics Basic Concepts
|
\section platform_basics Basic Concepts
|
||||||
|
|
||||||
- <b>Central Database</b>: All data except for the disk image is stored in a SQLite database. This includes information about what files exist in the disk image and the output from modules. Access to this database can be found from the SleuthKitCase class. <!-- @@@ IS THAT CORRECT -->
|
These are the basic concepts that you should be aware of before writing a module:
|
||||||
- <b>Utilities</b>: There are core utilities that the platform provides to modules. See the \ref mod_dev_utilities section for more details.
|
|
||||||
- <b>Services</b>: There are services provided by the platform. See the \ref mod_dev_services section for more details.
|
- <b>Phases:</b> The platform has been design to support different phases in the investigation process:
|
||||||
- <b>Pipelines and Plug-in Modules:</b> The platform has several places where plug-in modules can be incorporated. This modular approach allows other developers to extend the functionality of the system. See the \ref platform_frameworks section for more details.
|
- Case Creation: Use wizards to create a new case.
|
||||||
- <b>Blackboard:</b> The platform uses the blackboard to enable modules to communicate with each other and to display data in the GUI. See the \ref platform_blackboard section for more details.
|
- File Extraction: Where files are identified and the basic metadata are added to the central database. This happens in the Add Image Wizard.
|
||||||
- <b>Single tree:</b> Results from the various modules can generally be found in a single tree. This makes it easy for users to find their results.
|
- Ingest Modules: A variety of analysis modules then run on the extracted files to perform specific tasks.
|
||||||
- <b>Phases:</b> The platform has been design to support different phases in the investigation process:
|
- Browsing and searching: User can manually browse and search the data using the user interface.
|
||||||
- Case Creation: Use wizards to create a new case.
|
- Report: A final report is generated at the end of the case.
|
||||||
- File Extraction: Where files are identified and the basic metadata are added to the central database. This happens in the Add Image Wizard.
|
- <b>Central Database</b>: All data except for the disk image is stored in a SQLite database. This includes information about what files exist in the disk image and the output from modules. Access to this database can be found from the SleuthKitCase class, but you'll probably never need to directly interact with it. <!-- @@@ IS THAT CORRECT -->
|
||||||
- Ingest Modules: A variety of analysis modules then run on the extracted files to perform specific tasks.
|
- <b>Utilities</b>: There are core utilities that the platform provides to modules. See the \ref mod_dev_utilities section for more details.
|
||||||
- Browsing and searching: User can manually browse and search the data using the user interface.
|
- <b>Services</b>: There are services provided by the platform. See the \ref mod_dev_services section for more details.
|
||||||
- Report: A final report is generated at the end of the case.
|
- <b>Blackboard:</b> The platform uses the blackboard to enable modules to communicate with each other and to display data in the GUI. See the \ref platform_blackboard section for more details.
|
||||||
|
- <b>Single tree:</b> Results from the various modules can generally be found in a single tree. This makes it easy for users to find their results.
|
||||||
\section platform_frameworks Frameworks in the Platform
|
|
||||||
There are several places in the platform where plug-in modules can be applied.
|
|
||||||
- <b>Ingest Modules:</b> These modules are run when a new image is added to a case (and can be re-run afterwards too). See \ref mod_ingest_page for details on building these modules. These modules come in two forms:
|
\section platform_frameworks Frameworks in the Platform
|
||||||
- File Ingest Modules are called for every file in the image. Use this type of module if you want to examine the contents of all or most of the files. Examples include hash calculation, hash lookup, file type identification, and entropy calculation.
|
There are several places in the platform where plug-in modules can be applied.
|
||||||
- Image Ingest Modules are called once for every image. These modules can use the database to query for one or more files and perform analysis on them. Examples include web artifact analysis and searches that can rely only file names and extensions.
|
- <b>Ingest Modules:</b> These modules are run when a new image is added to a case (and can be re-run afterwards too). See \ref mod_ingest_page for details on building these modules. These modules come in two forms:
|
||||||
- <b>Content Viewers:</b> These modules show information about a specific file. These are the modules in the lower right of the interface. The platform comes with viewers to view the file in hexadecimal, extract the strings from the file, and view images and movies. See \ref mod_content_page for details on creating these modules.
|
- File Ingest Modules are called for every file in the image. Use this type of module if you want to examine the contents of all or most of the files. Examples include hash calculation, hash lookup, file type identification, and entropy calculation.
|
||||||
- <b>Result Viewers:</b> These modules show information about a set of files. These modules are in the upper right of the interface. The platform comes with viewers to view the set of files in a table and thumbnails. See \ref mod_result_page for details on creating these modules.
|
- Image Ingest Modules are called once for every image. These modules can use the database to query for one or more files and perform analysis on them. Examples include web artifact analysis and searches that can rely only file names and extensions.
|
||||||
|
- <b>Content Viewers:</b> These modules show information about a specific file. These are the modules in the lower right of the interface. The platform comes with viewers to view the file in hexadecimal, extract the strings from the file, and view images and movies. See \ref mod_content_page for details on creating these modules.
|
||||||
\section platform_blackboard The Blackboard
|
- <b>Result Viewers:</b> These modules show information about a set of files. These modules are in the upper right of the interface. The platform comes with viewers to view the set of files in a table and thumbnails. See \ref mod_result_page for details on creating these modules.
|
||||||
|
|
||||||
The blackboard allows modules to communicate. It has three main uses in Autopsy:
|
\section platform_blackboard The Blackboard
|
||||||
- Ingest modules can communicate with each other. For example, one module can calculate a MD5 hash of a file and post it to the blackboard. Then another module can retrieve the hash value from the blackboard and not need to calculate it again.
|
|
||||||
- The tree in the right-hand side of the UI uses the blackboard to populate its Results section. The bookmarks, hashset hits, etc. are all populated from Ingest modules that created blackboard entries.
|
The blackboard allows modules to communicate. It has three main uses in Autopsy:
|
||||||
- The report modules query the blackboard to identify what they should report on.
|
- Ingest modules can communicate with each other. For example, one module can calculate a MD5 hash of a file and post it to the blackboard. Then another module can retrieve the hash value from the blackboard and not need to calculate it again.
|
||||||
|
- The tree in the right-hand side of the UI uses the blackboard to populate its Results section. The bookmarks, hashset hits, etc. are all populated from Ingest modules that created blackboard entries.
|
||||||
For more details on the blackboard, refer to the TSK Framework documentation at http://sleuthkit.org/sleuthkit/docs/framework-docs/mod_bbpage.html. These documents are about the C++ implementation of the blackboard, but it is the same concepts.
|
- The report modules query the blackboard to identify what they should report on.
|
||||||
|
|
||||||
For details on the Java API, refer to the JNI docs:
|
For more details on the blackboard, refer to the TSK Framework documentation at http://sleuthkit.org/sleuthkit/docs/framework-docs/mod_bbpage.html. These documents are about the C++ implementation of the blackboard, but it is the same concepts.
|
||||||
http://sleuthkit.org/sleuthkit/docs/jni-docs/
|
|
||||||
|
For details on the Java API, refer to the JNI docs:
|
||||||
|
http://sleuthkit.org/sleuthkit/docs/jni-docs/
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
*/
|
||||||
|
@ -1,98 +1,87 @@
|
|||||||
/*! \page workflow_page General Workflow and Design
|
/*! \page workflow_page General Workflow and Design
|
||||||
|
|
||||||
\section design_overview Overview
|
\section design_overview Overview
|
||||||
This section outlines Autopsy design from the typical analysis work flow perspective.
|
This section outlines the internal Autopsy design from the typical analysis work flow perspective.
|
||||||
This page is organized based on these phases:
|
This page is organized based on these phases:
|
||||||
- A Case is created.
|
- A Case is created.
|
||||||
- Images are added to the case and ingest modules are run.
|
- Images are added to the case and ingest modules are run.
|
||||||
- Results are manually reviewed and searched.
|
- Results are manually reviewed and searched.
|
||||||
- Reports are generated.
|
- Reports are generated.
|
||||||
|
|
||||||
\section design_case Creating a Case
|
\section design_case Creating a Case
|
||||||
|
The first step in Autopsy work flow is creating a case. This is done in the org.sleuthkit.autopsy.casemodule package (see \ref casemodule_overview for details). This module contains the wizards needed and deals with how to store the information. You should not need to do much modifications in this package. But, you will want to use the org.sleuthkit.autopsy.casemodule.Case object to access all data related to this case.
|
||||||
The first step in Autopsy work flow is creating a case. This is done in the org.sleuthkit.autopsy.casemodule package (see \ref casemodule_overview for details). This module contains the wizards needed and deals with how to store the information. You should not need to do much modifications in this package. But, you will want to use the org.sleuthkit.autopsy.casemodule.Case object to access all data related to this case.
|
|
||||||
|
|
||||||
|
\section design_image Adding an Image and Running Ingest Modules
|
||||||
|
|
||||||
\section design_image Adding an Image and Running Ingest Modules
|
After case is created, one or more disk images can be added to the case. There is a wizard to guide that process and it is located in the org.sleuthkit.autopsy.casemodule package. Refer to the package section \ref casemodule_add_image for more details on the wizard. Most developers will not need to touch this code though. An important concept though is that adding an image to a case means that Autopsy uses The Sleuth Kit to enumerate all of the files in the file system and make a database entry for them in the embedded SQLite database that was created for the case. The database will be used for all further analysis.
|
||||||
|
|
||||||
After case is created, one or more disk images can be added to the case. There is a wizard to guide that process and it is located in the org.sleuthkit.autopsy.casemodule package. Refer to the package section \ref casemodule_add_image for more details on the wizard. Most developers will not need to touch this code though.
|
After image has been added to the case, the user can select one or more ingest modules to be executed on the image. Ingest modules focus on a specific type of analysis task and run in the background. They either analyze the entire disk image or individual files. The user will see the results from the modules in the result tree and in the ingest inbox.
|
||||||
|
|
||||||
After image has been added to the case, the user can select one or more ingest modules to be executed on the image. Ingest modules focus on a specific type of analysis task and run in the background. The results from the ingest module can be found in the results tree and in the ingest inbox.
|
The org.sleuthkit.autopsy.ingest package provides the basic infrastructure for the ingest module management.
|
||||||
|
|
||||||
The org.sleuthkit.autopsy.ingest package provides the basic infrastructure for the ingest module management.
|
If you want to develop a module that analyzes drive data, then this is probably the type of module that you want to build. See \ref mod_ingest_page for more details on making an ingest module.
|
||||||
|
|
||||||
A list of standard ingest modules that come with Autopsy can be found in:
|
|
||||||
- org.sleuthkit.autopsy.keywordsearch
|
\section design_view Viewing Results
|
||||||
- org.sleuthkit.autopsy.recentactivity
|
|
||||||
- org.sleuthkit.autopsy.hashdatabase
|
The UI has three main areas. The tree on the left-hand side, the result viewers in the upper right, and the content viewers in the lower right. Data passes between these areas by encapsulating them in Netbeans Node objects (see org.openide.nodes.Node). These allow Autopsy to generically handle all types of data. The org.sleuthkit.autopsy.datamodel package wraps the generic org.sleuthkit.datamodel Sleuth Kit objects as Netbeans Nodes.
|
||||||
- org.sleuthkit.autopsy.thunderbirdparser
|
|
||||||
|
Nodes are modeled in a parent-child hierarchy with other nodes. All data within a Case is represented in a hierarchy with the disk images being one level below the case and volumes and such below the image.
|
||||||
See \ref mod_ingest_page for more details on making an ingest module.
|
|
||||||
|
The tree on the left hand-side shows the analysis results.
|
||||||
|
Its contents are populated from the central database.
|
||||||
\section design_view Viewing Results
|
This is where you can browse the file system contents and see the results from the blackboard.
|
||||||
|
<!-- @@@(see \ref blackboard_page). -->
|
||||||
The UI has three main areas. The tree on the left-hand side, the result viewers in the upper right, and the content viewers in the lower right. Data passes between these areas by encapsulating them in Netbeans Node objects (see org.openide.nodes.Node). These allow Autopsy to generically handle all types of data. The org.sleuthkit.autopsy.datamodel package details with wrapping the org.sleuthkit.datamodel objects as Netbeans Nodes.
|
The tree is implemented in the org.sleuthkit.autopsy.directorytree package.
|
||||||
|
|
||||||
|
The area in the upper right is the result viewer area. When a node is selected from the tree, the node and its children are sent to this area. This area is used to view a set of nodes. The viewer is itself a framework with modules that display the data in different layouts. For example, the standard version comes with a table viewer and a thumbnail viewer. Refer to \ref mod_result_page for details on building a data result module.
|
||||||
Nodes are modeled in a parent-child hierarchy with other nodes. All data within a Case is represented in a hierarchy with the disk images being one level below the case and volumes and such below the image.
|
|
||||||
|
When an item is selected from the result viewer area, it is passed to the bottom right content viewers. It too is a framework with many modules that know how to show information about a specific file in different ways. For example, there are viewers that show the data in a hex dump format, extract the strings, and display pictures and movies.
|
||||||
The tree on the left hand-side shows the analysis results.
|
See \ref mod_content_page for details on building new content viewers.
|
||||||
Its contents are populated from the central database.
|
|
||||||
This is where you can browse the file system contents and see the results from the blackboard.
|
\section design_report Report generation
|
||||||
<!-- @@@(see \ref blackboard_page). -->
|
|
||||||
The tree is implemented in the org.sleuthkit.autopsy.directorytree package.
|
When ingest is complete, the user can generate reports.
|
||||||
|
There is a reporting framework to enable many different formats. Autopsy currently comes with generic html, xml and Excel reports. See the org.sleuthkit.autopsy.report package for details on the framework and
|
||||||
The area in the upper right is the result viewer area. When a node is selected from the tree, the node and its children are sent to this area. This area is used to view a set of nodes. The viewer is itself a framework with modules that display the data in different layouts. For example, the standard version comes with a table viewer and a thumbnail viewer. Refer to \ref mod_result_page for details on building a module.
|
\ref mod_report_page for details on building a new report module.
|
||||||
|
|
||||||
When an item is selected from the result viewer area, it is passed to the bottom right content viewers. It too is a framework with many modules that know how to show information about a specific file in different ways. For example, there are viewers that show the data in a hex dump format, extract the strings, and display pictures and movies.
|
|
||||||
See \ref mod_content_page for details on building new content viewers.
|
|
||||||
|
<!-- @@@ MOVE THIS SOMEWHERE ELSE -- the directory tree package maybe?? -->
|
||||||
|
|
||||||
|
The component is by default registered with the ingest manager as an ingest event listener.
|
||||||
\section design_report Report generation
|
The viewer first loads all the viewer-supported data currently in the blackboard when Autopsy starts.
|
||||||
|
During the ingest process the viewer receives events from ingest modules
|
||||||
When ingest is complete, the user can generate reports.
|
(relayed by ingest manager) and it selectively refreshes parts of the tree providing real-time updates to the user.
|
||||||
There is a reporting framework to enable many different formats. Autopsy currently comes with generic html, xml and Excel reports. See the org.sleuthkit.autopsy.report package for details on the framework and
|
When ingest is completed, the viewer responds to the final ingest data event generated by the ingest manager,
|
||||||
\ref mod_report_page for details on building a new report module.
|
and performs a final refresh of all viewer-supported data in the blackboard.
|
||||||
|
|
||||||
|
|
||||||
|
Node content support capabilities are registered in the node's Lookup.
|
||||||
<!-- @@@ MOVE THIS SOMEWHERE ELSE -- the directory tree package maybe?? -->
|
|
||||||
|
|
||||||
The component is by default registered with the ingest manager as an ingest event listener.
|
<!-- @@@ This is too detailed for here, but maybe should be broken up and put into the sections on making a result viewer and such…
|
||||||
The viewer first loads all the viewer-supported data currently in the blackboard when Autopsy starts.
|
-->
|
||||||
During the ingest process the viewer receives events from ingest modules
|
|
||||||
(relayed by ingest manager) and it selectively refreshes parts of the tree providing real-time updates to the user.
|
\section design_data_flow Data Flow
|
||||||
When ingest is completed, the viewer responds to the final ingest data event generated by the ingest manager,
|
|
||||||
and performs a final refresh of all viewer-supported data in the blackboard.
|
\subsection design_data_flow_create Creating Nodes in DataExplorer
|
||||||
|
|
||||||
|
Data flows between the UI zones using a NetBeans node. The DataExplorer modules create the NetBeans nodes. They query the SQLite database or do whatever they want to identify the set of files that are of interest. They create the NetBeans nodes based on Sleuthkit data model objects. See the org.sleuthkit.autopsy.datamodel package for more details on this.
|
||||||
Node content support capabilities are registered in the node's Lookup.
|
|
||||||
|
\subsection design_data_flow_toResult Getting Nodes to DataResult
|
||||||
|
|
||||||
<!-- @@@ This is too detailed for here, but maybe should be broken up and put into the sections on making a result viewer and such…
|
Each DataExplorer TopComponent is responsible for creating its own DataResult TopComponent to display its results. It can choose to re-use the same TopComponent for multiple searches (as DirectoryTree does) or it can choose to make a new one each time (as FileSearch does). The setNode() method on the DataResult object is used to set the root node to display. A dummy root node must be created as the parent if a parent does not already exist.
|
||||||
-->
|
|
||||||
|
The DataExplorer is responsible for setting the double-click and right-click actions associated with the node. The default single click action is to pass data to DataContent. To override this, you must create a new DataResultViewer instance that overrides the propertyChange() method. The DataExplorer adds actions to wrapping the node in a FilterNode variant. The FilterNode then defines the actions for the node by overriding the getPreferredAction() and getActions() methods. As an example, org.sleuthkit.autopsy.directorytree.DataResultFilterNode and org.sleuthkit.autopsy.directorytree.DataResultFilterChildren wraps the nodes that are passed over by the DirectoryTree DataExplorer.
|
||||||
\section design_data_flow Data Flow
|
|
||||||
|
DataResult can send data back to its DataExplorer by making a custom action that looks up it's instance (DataExplorer.getInstance()).
|
||||||
\subsection design_data_flow_create Creating Nodes in DataExplorer
|
|
||||||
|
\subsection design_data_flow_toContent Getting Nodes to DataContent
|
||||||
Data flows between the UI zones using a NetBeans node. The DataExplorer modules create the NetBeans nodes. They query the SQLite database or do whatever they want to identify the set of files that are of interest. They create the NetBeans nodes based on Sleuthkit data model objects. See the org.sleuthkit.autopsy.datamodel package for more details on this.
|
|
||||||
|
A default DataContent viewer is created when a case is opened. To display the contents of a node, it must be passed to a DataContent instance. The default single-click behavior of the DataResultViewers is to lookup the default DataContent TopComponent and pass the selected node to it. See org.sleuthkit.autopsy.corecomponents.AbstractDataResultViewer.propertyChange(PropertyChangeEvent) for details.
|
||||||
\subsection design_data_flow_toResult Getting Nodes to DataResult
|
|
||||||
|
|
||||||
Each DataExplorer TopComponent is responsible for creating its own DataResult TopComponent to display its results. It can choose to re-use the same TopComponent for multiple searches (as DirectoryTree does) or it can choose to make a new one each time (as FileSearch does). The setNode() method on the DataResult object is used to set the root node to display. A dummy root node must be created as the parent if a parent does not already exist.
|
|
||||||
|
*/
|
||||||
The DataExplorer is responsible for setting the double-click and right-click actions associated with the node. The default single click action is to pass data to DataContent. To override this, you must create a new DataResultViewer instance that overrides the propertyChange() method. The DataExplorer adds actions to wrapping the node in a FilterNode variant. The FilterNode then defines the actions for the node by overriding the getPreferredAction() and getActions() methods. As an example, org.sleuthkit.autopsy.directorytree.DataResultFilterNode and org.sleuthkit.autopsy.directorytree.DataResultFilterChildren wraps the nodes that are passed over by the DirectoryTree DataExplorer.
|
|
||||||
|
|
||||||
DataResult can send data back to its DataExplorer by making a custom action that looks up it's instance (DataExplorer.getInstance()).
|
|
||||||
|
|
||||||
\subsection design_data_flow_toContent Getting Nodes to DataContent
|
|
||||||
|
|
||||||
A default DataContent viewer is created when a case is opened. To display the contents of a node, it must be passed to a DataContent instance. The default single-click behavior of the DataResultViewers is to lookup the default DataContent TopComponent and pass the selected node to it. See org.sleuthkit.autopsy.corecomponents.AbstractDataResultViewer.propertyChange(PropertyChangeEvent) for details.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
@ -9,11 +9,10 @@ app.name=autopsy
|
|||||||
### Must be one of: DEVELOPMENT, RELEASE
|
### Must be one of: DEVELOPMENT, RELEASE
|
||||||
#build.type=RELEASE
|
#build.type=RELEASE
|
||||||
build.type=DEVELOPMENT
|
build.type=DEVELOPMENT
|
||||||
|
|
||||||
update_versions=false
|
update_versions=false
|
||||||
#custom JVM options
|
#custom JVM options
|
||||||
#Note: can be higher on 64 bit systems, should be in sync with build.xml
|
#Note: can be higher on 64 bit systems, should be in sync with build.xml
|
||||||
run.args.extra=-J-Xms24m -J-Xmx512m -J-XX:MaxPermSize=128M -J-Xverify:none
|
run.args.extra=-J-Xms24m -J-Xmx768m -J-XX:MaxPermSize=256M -J-Xverify:none
|
||||||
auxiliary.org-netbeans-modules-apisupport-installer.license-type=apache.v2
|
auxiliary.org-netbeans-modules-apisupport-installer.license-type=apache.v2
|
||||||
auxiliary.org-netbeans-modules-apisupport-installer.os-linux=false
|
auxiliary.org-netbeans-modules-apisupport-installer.os-linux=false
|
||||||
auxiliary.org-netbeans-modules-apisupport-installer.os-macosx=false
|
auxiliary.org-netbeans-modules-apisupport-installer.os-macosx=false
|
||||||
@ -31,8 +30,7 @@ modules=\
|
|||||||
${project.org.sleuthkit.autopsy.core}:\
|
${project.org.sleuthkit.autopsy.core}:\
|
||||||
${project.org.sleuthkit.autopsy.corelibs}:\
|
${project.org.sleuthkit.autopsy.corelibs}:\
|
||||||
${project.org.sleuthkit.autopsy.sevenzip}:\
|
${project.org.sleuthkit.autopsy.sevenzip}:\
|
||||||
${project.org.sleuthkit.autopsy.timeline}:\
|
${project.org.sleuthkit.autopsy.timeline}
|
||||||
${project.org.sleuthkit.autopsy.scalpel}
|
|
||||||
project.org.sleuthkit.autopsy.core=Core
|
project.org.sleuthkit.autopsy.core=Core
|
||||||
project.org.sleuthkit.autopsy.corelibs=CoreLibs
|
project.org.sleuthkit.autopsy.corelibs=CoreLibs
|
||||||
project.org.sleuthkit.autopsy.hashdatabase=HashDatabase
|
project.org.sleuthkit.autopsy.hashdatabase=HashDatabase
|
||||||
@ -43,4 +41,4 @@ project.org.sleuthkit.autopsy.thunderbirdparser=thunderbirdparser
|
|||||||
project.org.sleuthkit.autopsy.exifparser=ExifParser
|
project.org.sleuthkit.autopsy.exifparser=ExifParser
|
||||||
project.org.sleuthkit.autopsy.sevenzip=SevenZip
|
project.org.sleuthkit.autopsy.sevenzip=SevenZip
|
||||||
project.org.sleuthkit.autopsy.timeline=Timeline
|
project.org.sleuthkit.autopsy.timeline=Timeline
|
||||||
project.org.sleuthkit.autopsy.scalpel=ScalpelCarver
|
|
||||||
|
@ -32,8 +32,6 @@ import java.util.logging.Level;
|
|||||||
import org.apache.tika.exception.TikaException;
|
import org.apache.tika.exception.TikaException;
|
||||||
import org.apache.tika.metadata.Metadata;
|
import org.apache.tika.metadata.Metadata;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestServices;
|
import org.sleuthkit.autopsy.ingest.IngestServices;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestMessage;
|
|
||||||
import org.sleuthkit.autopsy.ingest.IngestMessage.MessageType;
|
|
||||||
import org.sleuthkit.autopsy.ingest.IngestModuleAbstract.*;
|
import org.sleuthkit.autopsy.ingest.IngestModuleAbstract.*;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestModuleAbstractFile;
|
import org.sleuthkit.autopsy.ingest.IngestModuleAbstractFile;
|
||||||
import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
|
import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
|
||||||
@ -52,12 +50,10 @@ import org.sleuthkit.autopsy.ingest.PipelineContext;
|
|||||||
import org.sleuthkit.autopsy.ingest.IngestModuleInit;
|
import org.sleuthkit.autopsy.ingest.IngestModuleInit;
|
||||||
import org.sleuthkit.datamodel.AbstractFile;
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
import org.sleuthkit.datamodel.Content;
|
import org.sleuthkit.datamodel.Content;
|
||||||
import org.sleuthkit.datamodel.ContentVisitor;
|
|
||||||
import org.sleuthkit.datamodel.FsContent;
|
|
||||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||||
import org.sleuthkit.datamodel.TskData;
|
import org.sleuthkit.datamodel.TskData;
|
||||||
|
|
||||||
public class ThunderbirdMboxFileIngestModule implements IngestModuleAbstractFile {
|
public class ThunderbirdMboxFileIngestModule extends IngestModuleAbstractFile {
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(ThunderbirdMboxFileIngestModule.class.getName());
|
private static final Logger logger = Logger.getLogger(ThunderbirdMboxFileIngestModule.class.getName());
|
||||||
private static ThunderbirdMboxFileIngestModule instance = null;
|
private static ThunderbirdMboxFileIngestModule instance = null;
|
||||||
@ -67,7 +63,6 @@ public class ThunderbirdMboxFileIngestModule implements IngestModuleAbstractFile
|
|||||||
private static final String MODULE_NAME = "Thunderbird Parser";
|
private static final String MODULE_NAME = "Thunderbird Parser";
|
||||||
private final String hashDBModuleName = "Hash Lookup";
|
private final String hashDBModuleName = "Hash Lookup";
|
||||||
final public static String MODULE_VERSION = "1.0";
|
final public static String MODULE_VERSION = "1.0";
|
||||||
private String args;
|
|
||||||
|
|
||||||
public static synchronized ThunderbirdMboxFileIngestModule getDefault() {
|
public static synchronized ThunderbirdMboxFileIngestModule getDefault() {
|
||||||
if (instance == null) {
|
if (instance == null) {
|
||||||
@ -262,15 +257,6 @@ public class ThunderbirdMboxFileIngestModule implements IngestModuleAbstractFile
|
|||||||
return MODULE_VERSION;
|
return MODULE_VERSION;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getArguments() {
|
|
||||||
return args;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setArguments(String args) {
|
|
||||||
this.args = args;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(IngestModuleInit initContext) {
|
public void init(IngestModuleInit initContext) {
|
||||||
@ -288,41 +274,8 @@ public class ThunderbirdMboxFileIngestModule implements IngestModuleAbstractFile
|
|||||||
//module specific cleanup due interruption here
|
//module specific cleanup due interruption here
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ModuleType getType() {
|
|
||||||
return ModuleType.AbstractFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasSimpleConfiguration() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasAdvancedConfiguration() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public javax.swing.JPanel getSimpleConfiguration() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public javax.swing.JPanel getAdvancedConfiguration() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasBackgroundJobsRunning() {
|
public boolean hasBackgroundJobsRunning() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void saveAdvancedConfiguration() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void saveSimpleConfiguration() {
|
|
||||||
}
|
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user