Merge remote-tracking branch 'upstream/251' into develop
@ -100,7 +100,7 @@ class ReportKML implements GeneralReportModule {
|
||||
public void generateReport(String baseReportDir, ReportProgressPanel progressPanel) {
|
||||
|
||||
// Start the progress bar and setup the report
|
||||
progressPanel.setIndeterminate(false);
|
||||
progressPanel.setIndeterminate(true);
|
||||
progressPanel.start();
|
||||
progressPanel.updateStatusLabel(NbBundle.getMessage(this.getClass(), "ReportKML.progress.querying"));
|
||||
String kmlFileFullPath = baseReportDir + REPORT_KML; //NON-NLS
|
||||
@ -109,9 +109,6 @@ class ReportKML implements GeneralReportModule {
|
||||
|
||||
progressPanel.updateStatusLabel(NbBundle.getMessage(this.getClass(), "ReportKML.progress.loading"));
|
||||
|
||||
progressPanel.setMaximumProgress(5);
|
||||
progressPanel.increment();
|
||||
|
||||
ns = Namespace.getNamespace("", "http://www.opengis.net/kml/2.2"); //NON-NLS
|
||||
|
||||
Element kml = new Element("kml", ns); //NON-NLS
|
||||
@ -180,6 +177,8 @@ class ReportKML implements GeneralReportModule {
|
||||
document.addContent(gpsSearchesFolder);
|
||||
document.addContent(gpsTrackpointsFolder);
|
||||
|
||||
ReportProgressPanel.ReportStatus result = ReportProgressPanel.ReportStatus.COMPLETE;
|
||||
|
||||
/**
|
||||
* In the following code, nulls are okay, and are handled when we go to
|
||||
* write out the KML feature. Nulls are expected to be returned from any
|
||||
@ -189,32 +188,49 @@ class ReportKML implements GeneralReportModule {
|
||||
* as anyone could write a module that adds additional attributes to an
|
||||
* artifact.
|
||||
*
|
||||
* If there are any issues reading the database getting artifacts and
|
||||
* attributes, or any exceptions thrown during this process, a severe
|
||||
* error is logged, the report is marked as "Incomplete KML Report", and
|
||||
* we use a best-effort method to generate KML information on everything
|
||||
* we can successfully pull out of the database.
|
||||
*/
|
||||
try {
|
||||
for (BlackboardArtifact artifact : skCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_METADATA_EXIF)) {
|
||||
try {
|
||||
Long timestamp = getLong(artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED);
|
||||
String desc = getDescriptionFromArtifact(artifact, "EXIF Metadata With Locations"); //NON-NLS
|
||||
Double lat = getDouble(artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE);
|
||||
Double lon = getDouble(artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE);
|
||||
Element point = makePoint(lat, lon, getDouble(artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_ALTITUDE));
|
||||
Path destination = null;
|
||||
|
||||
if (lat != null && lat != 0.0 && lon != null && lon != 0.0) {
|
||||
AbstractFile abstractFile = artifact.getSleuthkitCase().getAbstractFileById(artifact.getObjectID());
|
||||
if (abstractFile != null) {
|
||||
destination = Paths.get(baseReportDir, abstractFile.getName());
|
||||
copyFileUsingStream(abstractFile, destination.toFile());
|
||||
Path path = null;
|
||||
copyFileUsingStream(abstractFile, Paths.get(baseReportDir, abstractFile.getName()).toFile());
|
||||
try {
|
||||
path = Paths.get(removeLeadingImgAndVol(abstractFile.getUniquePath()));
|
||||
} catch (TskCoreException ex) {
|
||||
path = Paths.get(abstractFile.getParentPath(), abstractFile.getName());
|
||||
}
|
||||
String formattedCoordinates = String.format("%.2f, %.2f", lat, lon);
|
||||
gpsExifMetadataFolder.addContent(makePlacemarkWithPicture(abstractFile.getName(), FeatureColor.RED, desc, timestamp, point, destination, formattedCoordinates));
|
||||
if (path == null) {
|
||||
path = Paths.get(abstractFile.getName());
|
||||
}
|
||||
|
||||
gpsExifMetadataFolder.addContent(makePlacemarkWithPicture(abstractFile.getName(), FeatureColor.RED, desc, timestamp, point, path, formattedCoordinates));
|
||||
}
|
||||
} catch (TskCoreException | IOException ex) {
|
||||
} catch (Exception ex) {
|
||||
logger.log(Level.SEVERE, "Could not extract photo information.", ex); //NON-NLS
|
||||
result = ReportProgressPanel.ReportStatus.ERROR;
|
||||
}
|
||||
}
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, "Could not extract photos with EXIF metadata.", ex); //NON-NLS
|
||||
result = ReportProgressPanel.ReportStatus.ERROR;
|
||||
}
|
||||
|
||||
try {
|
||||
for (BlackboardArtifact artifact : skCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_BOOKMARK)) {
|
||||
try {
|
||||
Long timestamp = getLong(artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME);
|
||||
String desc = getDescriptionFromArtifact(artifact, "GPS Bookmark"); //NON-NLS
|
||||
Double lat = getDouble(artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE);
|
||||
@ -223,13 +239,19 @@ class ReportKML implements GeneralReportModule {
|
||||
String bookmarkName = getString(artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME);
|
||||
String formattedCoordinates = String.format("%.2f, %.2f", lat, lon);
|
||||
gpsBookmarksFolder.addContent(makePlacemark(bookmarkName, FeatureColor.BLUE, desc, timestamp, point, formattedCoordinates));
|
||||
} catch (Exception ex) {
|
||||
logger.log(Level.SEVERE, "Could not extract Bookmark information.", ex); //NON-NLS
|
||||
result = ReportProgressPanel.ReportStatus.ERROR;
|
||||
}
|
||||
}
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, "Could not get GPS Bookmarks from database.", ex); //NON-NLS
|
||||
result = ReportProgressPanel.ReportStatus.ERROR;
|
||||
}
|
||||
|
||||
try {
|
||||
for (BlackboardArtifact artifact : skCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_LAST_KNOWN_LOCATION)) {
|
||||
try {
|
||||
Long timestamp = getLong(artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME);
|
||||
String desc = getDescriptionFromArtifact(artifact, "GPS Last Known Location"); //NON-NLS
|
||||
Double lat = getDouble(artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE);
|
||||
@ -238,13 +260,19 @@ class ReportKML implements GeneralReportModule {
|
||||
Element point = makePoint(lat, lon, alt);
|
||||
String formattedCoordinates = String.format("%.2f, %.2f", lat, lon);
|
||||
gpsLastKnownLocationFolder.addContent(makePlacemark("Last Known Location", FeatureColor.PURPLE, desc, timestamp, point, formattedCoordinates)); //NON-NLS
|
||||
} catch (Exception ex) {
|
||||
logger.log(Level.SEVERE, "Could not extract Last Known Location information.", ex); //NON-NLS
|
||||
result = ReportProgressPanel.ReportStatus.ERROR;
|
||||
}
|
||||
}
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, "Could not get GPS Last Known Location from database.", ex); //NON-NLS
|
||||
result = ReportProgressPanel.ReportStatus.ERROR;
|
||||
}
|
||||
|
||||
try {
|
||||
for (BlackboardArtifact artifact : skCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_ROUTE)) {
|
||||
try {
|
||||
Long timestamp = getLong(artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME);
|
||||
String desc = getDescriptionFromArtifact(artifact, "GPS Route");
|
||||
Double latitudeStart = getDouble(artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE_START);
|
||||
@ -265,9 +293,14 @@ class ReportKML implements GeneralReportModule {
|
||||
|
||||
formattedCoordinates = String.format("%.2f, %.2f", latitudeEnd, longitudeEnd);
|
||||
gpsRouteFolder.addContent(makePlacemark("End", FeatureColor.GREEN, desc, timestamp, endingPoint, formattedCoordinates)); //NON-NLS
|
||||
} catch (Exception ex) {
|
||||
logger.log(Level.SEVERE, "Could not extract GPS Route information.", ex); //NON-NLS
|
||||
result = ReportProgressPanel.ReportStatus.ERROR;
|
||||
}
|
||||
}
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, "Could not get GPS Routes from database.", ex); //NON-NLS
|
||||
result = ReportProgressPanel.ReportStatus.ERROR;
|
||||
}
|
||||
|
||||
try {
|
||||
@ -290,10 +323,12 @@ class ReportKML implements GeneralReportModule {
|
||||
}
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, "Could not get GPS Searches from database.", ex); //NON-NLS
|
||||
result = ReportProgressPanel.ReportStatus.ERROR;
|
||||
}
|
||||
|
||||
try {
|
||||
for (BlackboardArtifact artifact : skCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_TRACKPOINT)) {
|
||||
try {
|
||||
Long timestamp = getLong(artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME);
|
||||
String desc = getDescriptionFromArtifact(artifact, "GPS Trackpoint"); //NON-NLS
|
||||
Double lat = getDouble(artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE);
|
||||
@ -312,26 +347,14 @@ class ReportKML implements GeneralReportModule {
|
||||
trackName = "GPS Trackpoint";
|
||||
}
|
||||
gpsTrackpointsFolder.addContent(makePlacemark(trackName, FeatureColor.YELLOW, desc, timestamp, point, formattedCoordinates));
|
||||
} catch (Exception ex) {
|
||||
logger.log(Level.SEVERE, "Could not extract Trackpoint information.", ex); //NON-NLS
|
||||
result = ReportProgressPanel.ReportStatus.ERROR;
|
||||
}
|
||||
}
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, "Could not get GPS Trackpoints from database.", ex); //NON-NLS
|
||||
}
|
||||
|
||||
progressPanel.increment();
|
||||
|
||||
try (FileOutputStream writer = new FileOutputStream(kmlFileFullPath)) {
|
||||
XMLOutputter outputter = new XMLOutputter(Format.getPrettyFormat());
|
||||
outputter.output(kmlDocument, writer);
|
||||
Case.getCurrentCase().addReport(kmlFileFullPath,
|
||||
NbBundle.getMessage(this.getClass(), "ReportKML.genReport.srcModuleName.text"),
|
||||
NbBundle.getMessage(this.getClass(), "ReportKML.genReport.reportName"));
|
||||
} catch (IOException ex) {
|
||||
logger.log(Level.SEVERE, "Could not write the KML file.", ex); //NON-NLS
|
||||
progressPanel.complete(ReportProgressPanel.ReportStatus.ERROR);
|
||||
} catch (TskCoreException ex) {
|
||||
String errorMessage = String.format("Error adding %s to case as a report", kmlFileFullPath); //NON-NLS
|
||||
logger.log(Level.SEVERE, errorMessage, ex);
|
||||
progressPanel.complete(ReportProgressPanel.ReportStatus.ERROR);
|
||||
result = ReportProgressPanel.ReportStatus.ERROR;
|
||||
}
|
||||
|
||||
// Copy the style sheet
|
||||
@ -341,10 +364,29 @@ class ReportKML implements GeneralReportModule {
|
||||
FileUtil.copy(input, output);
|
||||
} catch (IOException ex) {
|
||||
logger.log(Level.SEVERE, "Error placing KML stylesheet. The .KML file will not function properly.", ex); //NON-NLS
|
||||
result = ReportProgressPanel.ReportStatus.ERROR;
|
||||
}
|
||||
|
||||
progressPanel.increment();
|
||||
progressPanel.complete(ReportProgressPanel.ReportStatus.COMPLETE);
|
||||
try (FileOutputStream writer = new FileOutputStream(kmlFileFullPath)) {
|
||||
XMLOutputter outputter = new XMLOutputter(Format.getPrettyFormat());
|
||||
outputter.output(kmlDocument, writer);
|
||||
String prependedStatus = "";
|
||||
if (result == ReportProgressPanel.ReportStatus.ERROR) {
|
||||
prependedStatus = "Incomplete ";
|
||||
}
|
||||
Case.getCurrentCase().addReport(kmlFileFullPath,
|
||||
NbBundle.getMessage(this.getClass(), "ReportKML.genReport.srcModuleName.text"),
|
||||
prependedStatus + NbBundle.getMessage(this.getClass(), "ReportKML.genReport.reportName"));
|
||||
} catch (IOException ex) {
|
||||
logger.log(Level.SEVERE, "Could not write the KML file.", ex); //NON-NLS
|
||||
progressPanel.complete(ReportProgressPanel.ReportStatus.ERROR);
|
||||
} catch (TskCoreException ex) {
|
||||
String errorMessage = String.format("Error adding %s to case as a report", kmlFileFullPath); //NON-NLS
|
||||
logger.log(Level.SEVERE, errorMessage, ex);
|
||||
result = ReportProgressPanel.ReportStatus.ERROR;
|
||||
}
|
||||
|
||||
progressPanel.complete(result);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -723,35 +765,33 @@ class ReportKML implements GeneralReportModule {
|
||||
* coordinate-bearing feature (Point, LineString, etc) and places it in the
|
||||
* Placemark element.
|
||||
*
|
||||
* @param name Placemark name
|
||||
* @param name Placemark file name
|
||||
* @param color Placemark color
|
||||
* @param description Description for the info bubble on the map
|
||||
* @param timestamp Placemark timestamp
|
||||
* @param feature The feature to show. Could be Point, LineString, etc.
|
||||
* @param path The path to the file on disk
|
||||
* @param path The path to the file in the source image
|
||||
* @param coordinates The coordinates to display in the list view snippet
|
||||
*
|
||||
* @return the entire KML Placemark, including a picture.
|
||||
*/
|
||||
private Element makePlacemarkWithPicture(String name, FeatureColor color, String description, Long timestamp, Element feature, Path path, String coordinates) {
|
||||
Element placemark = new Element("Placemark", ns); //NON-NLS
|
||||
Element desc = new Element("description", ns); //NON-NLS
|
||||
if (name != null && !name.isEmpty()) {
|
||||
placemark.addContent(new Element("name", ns).addContent(name)); //NON-NLS
|
||||
String image = "<img src='" + name + "' width='400'/>"; //NON-NLS
|
||||
desc.addContent(image);
|
||||
}
|
||||
|
||||
placemark.addContent(new Element("styleUrl", ns).addContent(color.getColor())); //NON-NLS
|
||||
Element desc = new Element("description", ns); //NON-NLS
|
||||
|
||||
if (path != null) {
|
||||
String pathAsString = path.toString();
|
||||
if (pathAsString != null && !pathAsString.isEmpty()) {
|
||||
String image = "<img src='file:///" + pathAsString + "' width='400'/>"; //NON-NLS
|
||||
desc.addContent(image);
|
||||
desc.addContent(description + "<b>Source Path:</b> " + pathAsString);
|
||||
}
|
||||
}
|
||||
|
||||
desc.addContent(description + "<b>File Path:</b> " + path.toString());
|
||||
placemark.addContent(desc);
|
||||
|
||||
if (timestamp != null) {
|
||||
Element time = new Element("TimeStamp", ns); //NON-NLS
|
||||
time.addContent(new Element("when", ns).addContent(getTimeStamp(timestamp))); //NON-NLS
|
||||
@ -805,4 +845,36 @@ class ReportKML implements GeneralReportModule {
|
||||
public JPanel getConfigurationPanel() {
|
||||
return null; // No configuration panel
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a smash-n-grab from AbstractFile.createNonUniquePath(String).
|
||||
* This method is intended to be removed when img_ and vol_ are no longer
|
||||
* added to images and volumes respectively, OR when AbstractFile is sorted
|
||||
* out with respect to this.
|
||||
*
|
||||
* @param uniquePath The path to sanitize.
|
||||
*
|
||||
* @return path without leading img_/vol_ in position 0 or 1 respectively.
|
||||
*/
|
||||
private static String removeLeadingImgAndVol(String uniquePath) {
|
||||
// split the path into parts
|
||||
String[] pathSegments = uniquePath.replaceFirst("^/*", "").split("/"); //NON-NLS
|
||||
|
||||
// Replace image/volume name if they exist in specific entries
|
||||
if (pathSegments.length > 0) {
|
||||
pathSegments[0] = pathSegments[0].replaceFirst("^img_", ""); //NON-NLS
|
||||
}
|
||||
if (pathSegments.length > 1) {
|
||||
pathSegments[1] = pathSegments[1].replaceFirst("^vol_", ""); //NON-NLS
|
||||
}
|
||||
|
||||
// Assemble the path
|
||||
StringBuilder strbuf = new StringBuilder();
|
||||
for (String segment : pathSegments) {
|
||||
if (!segment.isEmpty()) {
|
||||
strbuf.append("/").append(segment);
|
||||
}
|
||||
}
|
||||
return strbuf.toString();
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2014-16 Basis Technology Corp.
|
||||
* Copyright 2011-2016 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -521,7 +521,15 @@ public abstract class AbstractVisualizationPane<X, Y, NodeType extends Node, Cha
|
||||
//make a copy of the list sorted by position along axis
|
||||
SortedList<Axis.TickMark<X>> tickMarks = getXAxis().getTickMarks().sorted(Comparator.comparing(Axis.TickMark::getPosition));
|
||||
|
||||
if (tickMarks.isEmpty() == false) {
|
||||
if (tickMarks.isEmpty()) {
|
||||
/*
|
||||
* Since StackedBarChart does some funky animation/background thread
|
||||
* stuff, sometimes there are no tick marks even though there is
|
||||
* data. Dispatching another call to layoutDateLables() allows that
|
||||
* stuff time to run before we check a gain.
|
||||
*/
|
||||
Platform.runLater(this::layoutDateLabels);
|
||||
} else {
|
||||
//get the spacing between ticks in the underlying axis
|
||||
double spacing = getTickSpacing();
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2014-16 Basis Technology Corp.
|
||||
* Copyright 2011-2016 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -56,8 +56,8 @@ import org.sleuthkit.autopsy.timeline.ui.TimeLineChart;
|
||||
import org.sleuthkit.autopsy.timeline.utils.RangeDivisionInfo;
|
||||
|
||||
/**
|
||||
* Customized {@link StackedBarChart<String, Number>} used to display the event
|
||||
* counts in {@link CountsViewPane}
|
||||
* Customized StackedBarChart<String, Number> used to display the event counts
|
||||
* in CountsViewPane.
|
||||
*/
|
||||
final class EventCountsChart extends StackedBarChart<String, Number> implements TimeLineChart<String> {
|
||||
|
||||
@ -70,10 +70,11 @@ final class EventCountsChart extends StackedBarChart<String, Number> implements
|
||||
private IntervalSelector<? extends String> intervalSelector;
|
||||
|
||||
final ObservableList<Node> selectedNodes;
|
||||
|
||||
/**
|
||||
* * the RangeDivisionInfo for the currently displayed time range, used to
|
||||
* correct the interval provided {@link EventCountsChart#intervalSelector}
|
||||
* by padding the end with one 'period'
|
||||
* the RangeDivisionInfo for the currently displayed time range, used to
|
||||
* correct the interval provided by intervalSelector by padding the end with
|
||||
* one 'period'
|
||||
*/
|
||||
private RangeDivisionInfo rangeInfo;
|
||||
|
||||
@ -81,6 +82,7 @@ final class EventCountsChart extends StackedBarChart<String, Number> implements
|
||||
super(dateAxis, countAxis);
|
||||
this.controller = controller;
|
||||
this.filteredEvents = controller.getEventsModel();
|
||||
|
||||
//configure constant properties on axes and chart
|
||||
dateAxis.setAnimated(true);
|
||||
dateAxis.setLabel(null);
|
||||
@ -114,25 +116,10 @@ final class EventCountsChart extends StackedBarChart<String, Number> implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearIntervalSelector() {
|
||||
getChartChildren().remove(intervalSelector);
|
||||
intervalSelector = null;
|
||||
}
|
||||
|
||||
public void clearContextMenu() {
|
||||
chartContextMenu = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* used by {@link CountsViewPane#BarClickHandler} to close the context menu
|
||||
* when the bar menu is requested
|
||||
*
|
||||
* @return the context menu for this chart
|
||||
*/
|
||||
public ContextMenu getContextMenu() {
|
||||
return chartContextMenu;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContextMenu getContextMenu(MouseEvent clickEvent) {
|
||||
if (chartContextMenu != null) {
|
||||
@ -150,6 +137,12 @@ final class EventCountsChart extends StackedBarChart<String, Number> implements
|
||||
return controller;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearIntervalSelector() {
|
||||
getChartChildren().remove(intervalSelector);
|
||||
intervalSelector = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IntervalSelector<? extends String> getIntervalSelector() {
|
||||
return intervalSelector;
|
||||
@ -158,6 +151,8 @@ final class EventCountsChart extends StackedBarChart<String, Number> implements
|
||||
@Override
|
||||
public void setIntervalSelector(IntervalSelector<? extends String> newIntervalSelector) {
|
||||
intervalSelector = newIntervalSelector;
|
||||
//Add a listener that sizes the interval selector to its preferred size.
|
||||
intervalSelector.prefHeightProperty().addListener(observable -> newIntervalSelector.autosize());
|
||||
getChartChildren().add(getIntervalSelector());
|
||||
}
|
||||
|
||||
@ -213,8 +208,8 @@ final class EventCountsChart extends StackedBarChart<String, Number> implements
|
||||
tooltip.setGraphic(new ImageView(eventType.getFXImage()));
|
||||
Tooltip.install(node, tooltip);
|
||||
|
||||
node.setOnMouseEntered((mouseEntered) -> node.setEffect(new DropShadow(10, eventType.getColor())));
|
||||
node.setOnMouseExited((MouseEvent mouseExited) -> node.setEffect(selectedNodes.contains(node) ? SELECTED_NODE_EFFECT : null));
|
||||
node.setOnMouseEntered(mouseEntered -> node.setEffect(new DropShadow(10, eventType.getColor())));
|
||||
node.setOnMouseExited(mouseExited -> node.setEffect(selectedNodes.contains(node) ? SELECTED_NODE_EFFECT : null));
|
||||
node.setOnMouseClicked(new BarClickHandler(item));
|
||||
}
|
||||
});
|
||||
|
@ -18,7 +18,7 @@ The module should be able to extract the following:
|
||||
|
||||
NOTE: These database formats vary by version of OS and different vendors can place the databases in different places. Autopsy may not support all versions and vendors.
|
||||
|
||||
NOTE: This module is not exhaustive with its support for Android. It was created as a starting point for others to contribute plug-ins for 3rd party apps. See the <a href="http://sleuthkit.org/autopsy/docs/api-docs/4.0/mod_mobile_page.html">Developer docs</a> for information on writing modules.
|
||||
NOTE: This module is not exhaustive with its support for Android. It was created as a starting point for others to contribute plug-ins for 3rd party apps. See the <a href="http://sleuthkit.org/autopsy/docs/api-docs/4.1/mod_mobile_page.html">Developer docs</a> for information on writing modules.
|
||||
|
||||
|
||||
Configuration
|
||||
|
@ -10,7 +10,7 @@ Each case has its own directory that is named based on the case name. The direct
|
||||
|
||||
There are several ways to create a new case:
|
||||
- The opening splash screen has a button to create a new case.
|
||||
- The "File", "Create New Case" menu item
|
||||
- The "Case", "Create New Case" menu item
|
||||
|
||||
The New Case wizard dialog will open and you will need to enter the case name and base directory. A directory for the case will be created inside of the "base directory". If the directory already exists, you will need to either delete the existing directory or choose a different combination of names.
|
||||
|
||||
@ -26,7 +26,7 @@ After you create the case, you will be prompted to add a data source, as describ
|
||||
|
||||
To open a case, either:
|
||||
- Choose "Open Existing Case" or "Open Recent Case" from the opening splash screen.
|
||||
- Choose the "File", "Open Case" menu item or "File", "Open Recent Case"
|
||||
- Choose the "Case", "Open Case" menu item or "Case", "Open Recent Case"
|
||||
|
||||
Navigate to the case directory and select the ".aut" file.
|
||||
|
||||
|
@ -15,7 +15,7 @@ Autopsy supports three types of data sources:
|
||||
You can add a data source in several ways:
|
||||
- After you create a case, it automatically prompts you to add a data source.
|
||||
- There is a toolbar item to add a Data Source when a case is open.
|
||||
- The "File", "Add Data Source" menu item when a case is open.
|
||||
- The "Case", "Add Data Source" menu item when a case is open.
|
||||
|
||||
The data source must remain accessible for the duration of the analysis because the case contains a reference to the data source. It does <b>not</b> copy the data source into the case folder.
|
||||
|
||||
@ -79,6 +79,9 @@ You can add files or folders that are on your local computer (or on a shared dri
|
||||
Some things to note when doing this:
|
||||
- Autopsy ignores the time stamps on files that it adds this way because they could be the timestamps when they were copied onto your examination device.
|
||||
- If you have a USB-attached device that you are analyzing and you choose to add the device's contents using this method, then note that it will not look at unallocated space or deleted files. Autopsy will only be able to see the allocated files. You should add the device as a "Logical Drive" to analyze the unallocated space.
|
||||
- You can modify the name of the Logical File Set from the default LogicalFileSet# by clicking the "Change" button as shown in the screenshot below:
|
||||
|
||||
\image html change_logical_file_set_display_name.PNG
|
||||
|
||||
To add logical files:
|
||||
-# Choose "Logical Files" from the pull down.
|
||||
|
@ -1,5 +1,5 @@
|
||||
<hr/>
|
||||
<p><i>Copyright © 2012-2015 Basis Technology. Generated on $date<br/>
|
||||
<p><i>Copyright © 2012-2016 Basis Technology. Generated on $date<br/>
|
||||
This work is licensed under a
|
||||
<a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/us/">Creative Commons Attribution-Share Alike 3.0 United States License</a>.
|
||||
</i></p>
|
||||
|
BIN
docs/doxygen-user/images/change_logical_file_set_display_name.PNG
Executable file
After Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 1.3 MiB After Width: | Height: | Size: 1.1 MiB |
Before Width: | Height: | Size: 65 KiB After Width: | Height: | Size: 68 KiB |
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 69 KiB |
Before Width: | Height: | Size: 80 KiB After Width: | Height: | Size: 82 KiB |
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 46 KiB |
BIN
docs/doxygen-user/images/ingest_progress_snapshot.PNG
Executable file
After Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 63 KiB |
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 56 KiB |
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 65 KiB |
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 57 KiB |
Before Width: | Height: | Size: 109 KiB After Width: | Height: | Size: 123 KiB |
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 54 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 16 KiB |
BIN
docs/doxygen-user/images/nsrl_import_process.PNG
Normal file → Executable file
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 76 KiB |
BIN
docs/doxygen-user/images/nsrl_imported.PNG
Normal file → Executable file
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 68 KiB |
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 23 KiB |
BIN
docs/doxygen-user/images/open_log_folder.PNG
Executable file
After Width: | Height: | Size: 8.2 KiB |
BIN
docs/doxygen-user/images/open_output_folder.PNG
Executable file
After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 79 KiB After Width: | Height: | Size: 85 KiB |
Before Width: | Height: | Size: 191 KiB After Width: | Height: | Size: 192 KiB |
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 63 KiB |
Before Width: | Height: | Size: 464 KiB After Width: | Height: | Size: 539 KiB |
@ -52,4 +52,9 @@ Ingest modules run in the background. An ingest module can provide you results
|
||||
|
||||
All of the official Autopsy modules send results to the blackboard, but if you install third-party apps, then they may choose any approach -- including a pop-up window each time they find something.
|
||||
|
||||
\section ingest_monitoring Viewing Ongoing Ingest Activity
|
||||
While Ingest is running, one can use the "Ingest Progress Snapshot" tool to see what activity is going on at the moment. Click on "Help", "Get Ingest Progress Snapshot" to view the dialog shown in the screenshot below.
|
||||
\image html ingest_progress_snapshot.PNG
|
||||
To refresh the view, use the "Refresh" button.
|
||||
|
||||
*/
|
||||
|
@ -75,8 +75,8 @@ The log file should end up looking like this (modified lines are highlighted in
|
||||
<br><br>
|
||||
\image html log4j.PNG
|
||||
<br><br>
|
||||
5. From an Autopsy installation, copy the folder <i>"C:\Program Files\Autopsy-4.0\autopsy\solr\solr\configsets"</i> to <i>"C:\Bitnami\solr-4.10.3-0\apache-solr\solr"</i>.
|
||||
6. From an Autopsy installation, copy the folder <i>"C:\Program Files\Autopsy-4.0\autopsy\solr\solr\lib"</i> to <i>"C:\Bitnami\solr-4.10.3-0\apache-solr\solr"</i>.
|
||||
5. From an Autopsy installation, copy the folder <i>"C:\Program Files\Autopsy-4.1\autopsy\solr\solr\configsets"</i> to <i>"C:\Bitnami\solr-4.10.3-0\apache-solr\solr"</i>.
|
||||
6. From an Autopsy installation, copy the folder <i>"C:\Program Files\Autopsy-4.1\autopsy\solr\solr\lib"</i> to <i>"C:\Bitnami\solr-4.10.3-0\apache-solr\solr"</i>.
|
||||
7. Start a Windows command prompt as administrator by pressing _Start_, typing _command_, right clicking on _Command Prompt_, and clicking on _Run as administrator_. Then run the following command to install the _solrJetty_ service:
|
||||
<br><br>
|
||||
<i>cmd /c C:\\Bitnami\\solr-4.10.3-0\\apache-solr\\scripts\\serviceinstall.bat INSTALL</i>
|
||||
|
13
docs/doxygen-user/logs_and_output_page.dox
Executable file
@ -0,0 +1,13 @@
|
||||
/*! \page logs_and_output_page Logs, Output, and Progress
|
||||
There are several shortcuts for getting to the output folder, log folder, and progress shapshot shown below.
|
||||
<br><br>
|
||||
To open the Case output folder, use "Tools", "Open Output Folder" as shown below:
|
||||
\image html open_output_folder.PNG
|
||||
<br><br>
|
||||
To open the Case log folder, use "Help", "Open Log Folder" as shown below:
|
||||
\image html open_log_folder.PNG
|
||||
<br><br>
|
||||
While Ingest is running, one can use the "Ingest Progress Snapshot" tool to see what activity is going on at the moment. Click on "Help", "Get Ingest Progress Snapshot" to view the dialog shown in the screenshot below.
|
||||
\image html ingest_progress_snapshot.PNG
|
||||
To refresh the view, use the "Refresh" button.
|
||||
*/
|
@ -41,6 +41,7 @@ The following topics are available here:
|
||||
- \subpage file_search_page
|
||||
- \subpage timeline_page
|
||||
- \subpage stix_page
|
||||
- \subpage logs_and_output_page
|
||||
- Reporting
|
||||
- \subpage tagging_page
|
||||
- \subpage reporting_page
|
||||
|
@ -5,10 +5,10 @@
|
||||
Data sources are added to a <strong>case</strong>. A case can have a single data source or it can have multiple data sources. Currently, a single report is generated for an entire case, so if you need to report on individual data sources, then you should use one data source per case. If there are many drives/phones/other data sources for one investigation, then your case should have multiple data sources.
|
||||
|
||||
\subsection s2 Creating a Case
|
||||
To create a case, use either the "Create New Case" option on the Welcome screen or from the "File" menu. This will start the <strong>New Case Wizard</strong>. You will need to supply it with the name of the case and a directory to store the case results into. You can optionally provide case numbers and reviewer names.
|
||||
To create a case, use either the "Create New Case" option on the Welcome screen or from the "Case" menu. This will start the <strong>New Case Wizard</strong>. You will need to supply it with the name of the case and a directory to store the case results into. You can optionally provide case numbers and reviewer names.
|
||||
|
||||
\subsection s3 Adding a Data Source
|
||||
The next step is to add an input data source to the case. The <strong>Add Data Source Wizard</strong> will start automatically after the case is created or you can manually start it from the "File" menu or toolbar. You will need to choose the type of input data source to add (image, local disk, or logical files and folders). Next, supply it with the location of the source to add.
|
||||
The next step is to add an input data source to the case. The <strong>Add Data Source Wizard</strong> will start automatically after the case is created or you can manually start it from the "Case" menu or toolbar. You will need to choose the type of input data source to add (image, local disk, or logical files and folders). Next, supply it with the location of the source to add.
|
||||
|
||||
|
||||
- For a disk image, browse to the first file in the set (Autopsy will find the rest of the files). Autopsy currently supports E01 and raw (dd) files.
|
||||
@ -114,7 +114,7 @@ You can select an image or video from the upper right and view the video or imag
|
||||
A final report can be generated that will include all analysis results.
|
||||
Use the "Generate Report" button to create this.
|
||||
It will create an HTML or XLS report in the Reports folder of the case folder.
|
||||
If you forgot the location of your case folder, you can determine it using the "Case Properties" option in the "File" menu.
|
||||
If you forgot the location of your case folder, you can determine it using the "Case Properties" option in the "Case" menu.
|
||||
There is also an option to export report files to a separate folder outside of the case folder.
|
||||
|
||||
*/
|