diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties
index cca8104c38..bf6adc0de3 100644
--- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties
+++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties
@@ -23,10 +23,13 @@ FileTypeIdGlobalSettingsPanel.mimeTypeLabel.text=MIME Type
FileTypeIdGlobalSettingsPanel.saveTypeButton.text=Save
FileTypeIdGlobalSettingsPanel.signatureComboBox.rawItem=Bytes (Hex)
FileTypeIdGlobalSettingsPanel.signatureComboBox.asciiItem=String (ASCII)
+FileTypeIdGlobalSettingsPanel.offsetComboBox.startItem=Start
+FileTypeIdGlobalSettingsPanel.offsetComboBox.endItem=End
FileTypeIdGlobalSettingsPanel.JOptionPane.invalidMIMEType.message=MIME type is required.
FileTypeIdGlobalSettingsPanel.JOptionPane.invalidMIMEType.title=Missing MIME Type
FileTypeIdGlobalSettingsPanel.JOptionPane.invalidSignature.message=Signature is required.
FileTypeIdGlobalSettingsPanel.JOptionPane.invalidSignature.title=Missing Signature
+FileTypeIdGlobalSettingsPanel.JOptionPane.invalidOffset.length=Offset must not be smaller than signature size.
FileTypeIdGlobalSettingsPanel.JOptionPane.invalidOffset.message=Offset must be a positive integer.
FileTypeIdGlobalSettingsPanel.JOptionPane.invalidOffset.title=Invalid Offset
FileTypeIdGlobalSettingsPanel.JOptionPane.invalidRawSignatureBytes.message=The signature has one or more invalid hexadecimal digits.
@@ -46,4 +49,4 @@ FileTypeIdGlobalSettingsPanel.jLabel2.text=MIME Types:
FileTypeIdGlobalSettingsPanel.jLabel3.text=Autopsy can automatically detect many file types. Add your custom file types here.
FileTypeIdGlobalSettingsPanel.startUp.fileTypeDetectorInitializationException.msg=Error initializing the file type detector.
FileTypeIdIngestModule.startUp.fileTypeDetectorInitializationException.msg=Error initializing the file type detector.
-
+FileTypeIdGlobalSettingsPanel.offsetRelativeToLabel.text=Offset is relative to
diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileType.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileType.java
index 30c9525603..84e4186975 100644
--- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileType.java
+++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileType.java
@@ -51,7 +51,7 @@ class FileType {
*/
FileType(String mimeType, final Signature signature, String filesSetName, boolean alert) {
this.mimeType = mimeType;
- this.signature = new Signature(signature.getSignatureBytes(), signature.getOffset(), signature.getType());
+ this.signature = new Signature(signature.getSignatureBytes(), signature.getOffset(), signature.getType(), signature.isRelativeToStart());
this.interestingFilesSetName = filesSetName;
this.alert = alert;
}
@@ -71,7 +71,7 @@ class FileType {
* @return The signature.
*/
Signature getSignature() {
- return new Signature(signature.getSignatureBytes(), signature.getOffset(), signature.getType());
+ return new Signature(signature.getSignatureBytes(), signature.getOffset(), signature.getType(), signature.isRelativeToStart());
}
/**
@@ -148,6 +148,7 @@ class FileType {
private final byte[] signatureBytes;
private final long offset;
private final Type type;
+ private final boolean isRelativeToStart;
/**
* Creates a file signature consisting of a sequence of bytes at a
@@ -162,6 +163,7 @@ class FileType {
this.signatureBytes = Arrays.copyOf(signatureBytes, signatureBytes.length);
this.offset = offset;
this.type = type;
+ this.isRelativeToStart = true;
}
/**
@@ -175,6 +177,7 @@ class FileType {
this.signatureBytes = signatureString.getBytes(StandardCharsets.US_ASCII);
this.offset = offset;
this.type = Type.ASCII;
+ this.isRelativeToStart = true;
}
/**
@@ -190,6 +193,56 @@ class FileType {
this.signatureBytes = Arrays.copyOf(signatureBytes, signatureBytes.length);
this.offset = offset;
this.type = Type.RAW;
+ this.isRelativeToStart = true;
+ }
+
+ /**
+ * Creates a file signature consisting of a sequence of bytes at a
+ * specific offset within a file.
+ *
+ * @param signatureBytes The signature bytes.
+ * @param offset The offset of the signature bytes.
+ * @param type The type of data in the byte array. Impacts
+ * how it is displayed to the user in the UI.
+ * @param isRelativeToStart Determines whether this signature is relative to start.
+ */
+ Signature(final byte[] signatureBytes, long offset, Type type, boolean isRelativeToStart) {
+ this.signatureBytes = Arrays.copyOf(signatureBytes, signatureBytes.length);
+ this.offset = offset;
+ this.type = type;
+ this.isRelativeToStart = isRelativeToStart;
+ }
+
+ /**
+ * Creates a file signature consisting of an ASCII string at a
+ * specific offset within a file.
+ *
+ * @param signatureString The ASCII string
+ * @param offset The offset of the signature bytes.
+ * @param isRelativeToStart Determines whether this signature is relative to start.
+ */
+ Signature(String signatureString, long offset, boolean isRelativeToStart) {
+ this.signatureBytes = signatureString.getBytes(StandardCharsets.US_ASCII);
+ this.offset = offset;
+ this.type = Type.ASCII;
+ this.isRelativeToStart = isRelativeToStart;
+ }
+
+ /**
+ * Creates a file signature consisting of a sequence of bytes at a
+ * specific offset within a file. If bytes correspond to an ASCII
+ * string, use one of the other constructors so that the string is
+ * displayed to the user instead of the raw bytes.
+ *
+ * @param signatureBytes The signature bytes.
+ * @param offset The offset of the signature bytes.
+ * @param isRelativeToStart Determines whether this signature is relative to start.
+ */
+ Signature(final byte[] signatureBytes, long offset, boolean isRelativeToStart) {
+ this.signatureBytes = Arrays.copyOf(signatureBytes, signatureBytes.length);
+ this.offset = offset;
+ this.type = Type.RAW;
+ this.isRelativeToStart = isRelativeToStart;
}
/**
@@ -218,6 +271,10 @@ class FileType {
Type getType() {
return type;
}
+
+ boolean isRelativeToStart() {
+ return isRelativeToStart;
+ }
/**
* Determines whether or not the signature is contained within a given
@@ -228,12 +285,15 @@ class FileType {
* @return True or false.
*/
boolean containedIn(final AbstractFile file) {
- if (file.getSize() < (offset + signatureBytes.length)) {
+ long actualOffset = offset;
+ if(!isRelativeToStart)
+ actualOffset = file.getSize() - 1 - offset;
+ if (file.getSize() < (actualOffset + signatureBytes.length)) {
return false; /// too small, can't contain this signature
}
try {
byte[] buffer = new byte[signatureBytes.length];
- int bytesRead = file.read(buffer, offset, signatureBytes.length);
+ int bytesRead = file.read(buffer, actualOffset, signatureBytes.length);
return ((bytesRead == signatureBytes.length) && (Arrays.equals(buffer, signatureBytes)));
} catch (TskCoreException ex) {
/**
diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.form b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.form
index bfc83ee709..2b4647356c 100644
--- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.form
+++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.form
@@ -49,40 +49,50 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -107,7 +117,7 @@
-
+
@@ -138,12 +148,17 @@
+
+
+
+
+
-
-
+
+
-
+
@@ -350,5 +365,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.java
index 5380234490..9e1b1f3320 100644
--- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.java
+++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeIdGlobalSettingsPanel.java
@@ -52,6 +52,8 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
private static final String RAW_SIGNATURE_TYPE_COMBO_BOX_ITEM = NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.signatureComboBox.rawItem");
private static final String ASCII_SIGNATURE_TYPE_COMBO_BOX_ITEM = NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.signatureComboBox.asciiItem");
+ private static final String START_OFFSET_RELATIVE_COMBO_BOX_ITEM = NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.offsetComboBox.startItem");
+ private static final String END_OFFSET_RELATIVE_COMBO_BOX_ITEM = NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.offsetComboBox.endItem");
/**
* The list model for the file types list component of this panel is the set
* of MIME types associated with the user-defined file types. A mapping of
@@ -88,6 +90,7 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
private void customizeComponents() {
setFileTypesListModel();
setSignatureTypeComboBoxModel();
+ setOffsetRealtiveToComboBoxModel();
clearTypeDetailsComponents();
addTypeListSelectionListener();
addTextFieldListeners();
@@ -111,6 +114,17 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
signatureTypeComboBox.setModel(sigTypeComboBoxModel);
signatureTypeComboBox.setSelectedItem(FileTypeIdGlobalSettingsPanel.RAW_SIGNATURE_TYPE_COMBO_BOX_ITEM);
}
+
+ /**
+ * Sets the model for the signature type combo box.
+ */
+ private void setOffsetRealtiveToComboBoxModel() {
+ DefaultComboBoxModel offsetRelComboBoxModel = new DefaultComboBoxModel<>();
+ offsetRelComboBoxModel.addElement(FileTypeIdGlobalSettingsPanel.START_OFFSET_RELATIVE_COMBO_BOX_ITEM);
+ offsetRelComboBoxModel.addElement(FileTypeIdGlobalSettingsPanel.END_OFFSET_RELATIVE_COMBO_BOX_ITEM);
+ offsetRelativeToComboBox.setModel(offsetRelComboBoxModel);
+ offsetRelativeToComboBox.setSelectedItem(FileTypeIdGlobalSettingsPanel.START_OFFSET_RELATIVE_COMBO_BOX_ITEM);
+ }
/**
* Adds a listener to the types list component so that the components in the
@@ -270,6 +284,7 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
}
}
signatureTextField.setText(signatureBytes);
+ offsetRelativeToComboBox.setSelectedItem(signature.isRelativeToStart() ? FileTypeIdGlobalSettingsPanel.START_OFFSET_RELATIVE_COMBO_BOX_ITEM : FileTypeIdGlobalSettingsPanel.END_OFFSET_RELATIVE_COMBO_BOX_ITEM);
offsetTextField.setText(Long.toString(signature.getOffset()));
postHitCheckBox.setSelected(fileType.alertOnMatch());
filesSetNameTextField.setEnabled(postHitCheckBox.isSelected());
@@ -289,6 +304,7 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
signatureTypeComboBox.setSelectedItem(FileTypeIdGlobalSettingsPanel.RAW_SIGNATURE_TYPE_COMBO_BOX_ITEM);
hexPrefixLabel.setVisible(true);
signatureTextField.setText("0000"); //NON-NLS
+ offsetRelativeToComboBox.setSelectedItem(FileTypeIdGlobalSettingsPanel.START_OFFSET_RELATIVE_COMBO_BOX_ITEM);
offsetTextField.setText(""); //NON-NLS
postHitCheckBox.setSelected(false);
filesSetNameTextField.setText(""); //NON-NLS
@@ -360,6 +376,8 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
jLabel1 = new javax.swing.JLabel();
jLabel2 = new javax.swing.JLabel();
jLabel3 = new javax.swing.JLabel();
+ offsetRelativeToComboBox = new javax.swing.JComboBox();
+ offsetRelativeToLabel = new javax.swing.JLabel();
setMaximumSize(new java.awt.Dimension(500, 300));
setPreferredSize(new java.awt.Dimension(500, 300));
@@ -439,6 +457,8 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
org.openide.awt.Mnemonics.setLocalizedText(jLabel3, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.jLabel3.text")); // NOI18N
+ org.openide.awt.Mnemonics.setLocalizedText(offsetRelativeToLabel, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.offsetRelativeToLabel.text")); // NOI18N
+
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
@@ -465,33 +485,40 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(layout.createSequentialGroup()
- .addComponent(mimeTypeLabel)
- .addGap(30, 30, 30)
- .addComponent(mimeTypeTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 176, javax.swing.GroupLayout.PREFERRED_SIZE))
- .addComponent(postHitCheckBox)
- .addGroup(layout.createSequentialGroup()
- .addComponent(signatureTypeLabel)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
- .addComponent(signatureTypeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 176, javax.swing.GroupLayout.PREFERRED_SIZE))
- .addGroup(layout.createSequentialGroup()
- .addComponent(signatureLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 73, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
- .addComponent(hexPrefixLabel)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(signatureTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 160, javax.swing.GroupLayout.PREFERRED_SIZE))
- .addGroup(layout.createSequentialGroup()
- .addComponent(offsetLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 71, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
- .addComponent(offsetTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 178, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addGap(21, 21, 21)
.addComponent(filesSetNameLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
- .addComponent(filesSetNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 182, javax.swing.GroupLayout.PREFERRED_SIZE)))
+ .addComponent(filesSetNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 182, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addGroup(layout.createSequentialGroup()
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addComponent(mimeTypeLabel)
+ .addGap(30, 30, 30)
+ .addComponent(mimeTypeTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 176, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addComponent(postHitCheckBox)
+ .addGroup(layout.createSequentialGroup()
+ .addComponent(signatureTypeLabel)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addComponent(signatureTypeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 176, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addGroup(layout.createSequentialGroup()
+ .addComponent(signatureLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 73, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addComponent(hexPrefixLabel)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(signatureTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 160, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addGroup(layout.createSequentialGroup()
+ .addComponent(offsetLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 71, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addComponent(offsetTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 178, javax.swing.GroupLayout.PREFERRED_SIZE)))
+ .addGap(6, 6, 6)))
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addComponent(saveTypeButton)
- .addGap(8, 8, 8))))
+ .addGap(8, 8, 8))
+ .addGroup(layout.createSequentialGroup()
+ .addComponent(offsetRelativeToLabel)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addComponent(offsetRelativeToComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))))
.addComponent(jLabel1)
.addComponent(jLabel3))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
@@ -509,7 +536,7 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
.addGroup(layout.createSequentialGroup()
.addComponent(jLabel2)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(typesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 177, Short.MAX_VALUE)
+ .addComponent(typesScrollPane)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(deleteTypeButton)
@@ -532,11 +559,15 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
.addComponent(hexPrefixLabel)
.addComponent(signatureTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addComponent(signatureLabel))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(offsetLabel)
+ .addComponent(offsetTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
- .addComponent(offsetTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(offsetLabel))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addComponent(offsetRelativeToComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(offsetRelativeToLabel))
+ .addGap(16, 16, 16)
.addComponent(postHitCheckBox)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
@@ -596,6 +627,7 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
byte[] signatureBytes;
if (FileType.Signature.Type.RAW == sigType) {
try {
+ sigString = sigString.replaceAll("\\s", "");
signatureBytes = DatatypeConverter.parseHexBinary(sigString);
} catch (IllegalArgumentException ex) {
JOptionPane.showMessageDialog(null,
@@ -612,8 +644,16 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
* Get the offset.
*/
long offset;
+ boolean isRelativeToStart = offsetRelativeToComboBox.getSelectedItem() == FileTypeIdGlobalSettingsPanel.START_OFFSET_RELATIVE_COMBO_BOX_ITEM;
try {
- offset = Long.parseUnsignedLong(offsetTextField.getText());
+ offset = Long.parseUnsignedLong(offsetTextField.getText());
+ if(!isRelativeToStart && signatureBytes.length > offset+1) {
+ JOptionPane.showMessageDialog(null,
+ NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidOffset.length"),
+ NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidOffset.title"),
+ JOptionPane.ERROR_MESSAGE);
+ return;
+ }
} catch (NumberFormatException ex) {
JOptionPane.showMessageDialog(null,
NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidOffset.message"),
@@ -640,7 +680,7 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
/**
* Put it all together and reset the file types list component.
*/
- FileType.Signature signature = new FileType.Signature(signatureBytes, offset, sigType);
+ FileType.Signature signature = new FileType.Signature(signatureBytes, offset, sigType, isRelativeToStart);
FileType fileType = new FileType(typeName, signature, filesSetName, postHitCheckBox.isSelected());
FileType selected = typesList.getSelectedValue();
if (selected != null) {
@@ -683,6 +723,8 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
private javax.swing.JTextField mimeTypeTextField;
private javax.swing.JButton newTypeButton;
private javax.swing.JLabel offsetLabel;
+ private javax.swing.JComboBox offsetRelativeToComboBox;
+ private javax.swing.JLabel offsetRelativeToLabel;
private javax.swing.JTextField offsetTextField;
private javax.swing.JCheckBox postHitCheckBox;
private javax.swing.JButton saveTypeButton;
diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypes.xsd b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypes.xsd
index 26aa720ff1..d5812bcf19 100644
--- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypes.xsd
+++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypes.xsd
@@ -13,8 +13,16 @@
-
-
+
+
+
+
+
+
+
+
+
+
@@ -25,7 +33,7 @@
-
+
diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/UserDefinedFileTypesManager.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/UserDefinedFileTypesManager.java
index d06750dc66..d8a7275282 100644
--- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/UserDefinedFileTypesManager.java
+++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/UserDefinedFileTypesManager.java
@@ -38,6 +38,7 @@ import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
import org.sleuthkit.autopsy.coreutils.XMLUtil;
import org.sleuthkit.autopsy.modules.filetypeid.FileType.Signature;
+import org.w3c.dom.Node;
import org.xml.sax.SAXException;
/**
@@ -67,6 +68,7 @@ final class UserDefinedFileTypesManager {
private static final String SIGNATURE_TYPE_ATTRIBUTE = "type"; //NON-NLS
private static final String BYTES_TAG_NAME = "Bytes"; //NON-NLS
private static final String OFFSET_TAG_NAME = "Offset"; //NON-NLS
+ private static final String RELATIVE_ATTRIBUTE = "RelativeToStart";
private static final String INTERESTING_FILES_SET_TAG_NAME = "InterestingFileSset"; //NON-NLS
private static final String ALERT_ATTRIBUTE = "alert"; //NON-NLS
private static final String ENCODING_FOR_XML_FILE = "UTF-8"; //NON-NLS
@@ -376,6 +378,7 @@ final class UserDefinedFileTypesManager {
Element offsetElem = doc.createElement(OFFSET_TAG_NAME);
offsetElem.setTextContent(DatatypeConverter.printLong(signature.getOffset()));
+ offsetElem.setAttribute(RELATIVE_ATTRIBUTE, String.valueOf(signature.isRelativeToStart()));
signatureElem.appendChild(offsetElem);
signatureElem.setAttribute(SIGNATURE_TYPE_ATTRIBUTE, signature.getType().toString());
@@ -485,10 +488,17 @@ final class UserDefinedFileTypesManager {
String sigBytesString = getChildElementTextContent(signatureElem, BYTES_TAG_NAME);
byte[] signatureBytes = DatatypeConverter.parseHexBinary(sigBytesString);
- String offsetString = getChildElementTextContent(signatureElem, OFFSET_TAG_NAME);
+ Element offsetElem = (Element) signatureElem.getElementsByTagName(OFFSET_TAG_NAME).item(0);
+ String offsetString = offsetElem.getTextContent();
long offset = DatatypeConverter.parseLong(offsetString);
+
+ String relativeString = offsetElem.getAttribute(RELATIVE_ATTRIBUTE);
+ if(relativeString == null || relativeString.equals(""))
+ return new Signature(signatureBytes, offset, signatureType);
+
+ boolean isRelative = DatatypeConverter.parseBoolean(relativeString);
- return new Signature(signatureBytes, offset, signatureType);
+ return new Signature(signatureBytes, offset, signatureType, isRelative);
}
/**
@@ -526,11 +536,14 @@ final class UserDefinedFileTypesManager {
* @param elem The parent element.
* @param tagName The tag name of the child element.
*
- * @return The text content.
+ * @return The text content or null if the tag doesn't exist.
*/
private static String getChildElementTextContent(Element elem, String tagName) {
NodeList childElems = elem.getElementsByTagName(tagName);
- Element childElem = (Element) childElems.item(0);
+ Node childNode = childElems.item(0);
+ if(childNode == null)
+ return null;
+ Element childElem = (Element) childNode;
return childElem.getTextContent();
}