added files sets to standard sets

This commit is contained in:
Greg DiCristofaro 2020-06-02 09:51:01 -04:00
parent 555feb94f2
commit cb5af3e93a
7 changed files with 182 additions and 112 deletions

View File

@ -45,7 +45,7 @@ public final class FilesSet implements Serializable {
private final boolean ignoreKnownFiles;
private final boolean ignoreUnallocatedSpace;
private final boolean readOnly;
private final boolean standardSet;
private final int versionNumber;
private final Map<String, Rule> rules = new HashMap<>();
@ -75,13 +75,16 @@ public final class FilesSet implements Serializable {
* the set.
* @param ignoreUnallocatedSpace Whether or not to exclude unallocated space
* from the set.
* @param readOnly Whether or not the FilesSet should be read only (if not it is editable).
* @param versionNumber The versionNumber for the FilesSet so that older versions can be replaced with newer versions.
* @param standardSet Whether or not the FilesSet is considered a
* standard interesting set file.
* @param versionNumber The versionNumber for the FilesSet so that
* older versions can be replaced with newer
* versions.
* @param rules The rules that define the set. May be null,
* but a set with no rules is the empty set.
*/
public FilesSet(String name, String description, boolean ignoreKnownFiles, boolean ignoreUnallocatedSpace, Map<String, Rule> rules,
boolean readOnly, int versionNumber) {
boolean standardSet, int versionNumber) {
if ((name == null) || (name.isEmpty())) {
throw new IllegalArgumentException("Interesting files set name cannot be null or empty");
}
@ -90,7 +93,7 @@ public final class FilesSet implements Serializable {
throw new IllegalArgumentException("version number must be >= 0");
}
this.readOnly = readOnly;
this.standardSet = standardSet;
this.versionNumber = versionNumber;
this.name = name;
@ -103,23 +106,21 @@ public final class FilesSet implements Serializable {
}
/**
* Returns whether or not the file set is read only.
* @return Whether or not the file set is read only.
* @return Whether or not the FilesSet is considered a standard interesting
* set file.
*/
boolean isReadOnly() {
return readOnly;
boolean isStandardSet() {
return standardSet;
}
/**
* Returns he versionNumber for the FilesSet so that older versions can be replaced with newer versions.
* @return The versionNumber for the FilesSet so that older versions can be replaced with newer versions.
* @return The versionNumber for the FilesSet so that older versions can be
* replaced with newer versions.
*/
int getVersionNumber() {
return versionNumber;
}
/**
* Gets the name of this interesting files set.
*
@ -673,7 +674,6 @@ public final class FilesSet implements Serializable {
* To ensure compatibility with existing serialized configuration
* settings, this class cannot have a 'serialVersionUID'.
*/
private final TextMatcher textMatcher;
/**
@ -832,7 +832,6 @@ public final class FilesSet implements Serializable {
* To ensure compatibility with existing serialized configuration
* settings, this class cannot have a 'serialVersionUID'.
*/
private final static long SECS_PER_DAY = 60 * 60 * 24;
private int daysIncluded;
@ -922,7 +921,7 @@ public final class FilesSet implements Serializable {
private static List<String> normalize(List<String> extensions) {
List<String> values = new ArrayList<>(extensions);
for (int i=0; i < values.size(); i++) {
for (int i = 0; i < values.size(); i++) {
values.set(i, normalize(values.get(i)));
}

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<INTERESTING_FILE_SETS>
<INTERESTING_FILE_SET description="Identifies installed cloud storage applications" ignoreKnown="false" name="Cloud Storage">
<NAME name="CloudMe" regex="false" typeFilter="file">CloudMe.exe</NAME>
<NAME name="Resilio" regex="false" typeFilter="file">Resilio Sync.exe</NAME>
<NAME name="pCloud" regex="false" typeFilter="file">pcloud.exe</NAME>
<NAME name="Slack" regex="false" typeFilter="file">slack.exe</NAME>
<NAME name="iCloud Drive" regex="false" typeFilter="file">iCloudDrive.exe</NAME>
<NAME name="Google Stream" regex="false" typeFilter="file">GoogleDriveFS.exe</NAME>
<NAME name="GoodSync" regex="false" typeFilter="file">goodsync.exe</NAME>
<NAME name="Synqion" regex="false" typeFilter="file">synqion.exe</NAME>
<NAME name="NextCloud" regex="false" typeFilter="file">nextcloud.exe</NAME>
<NAME name="OneDrive Windows App" regex="false" typeFilter="file">microsoft.microsoftskydrive.exe</NAME>
<NAME name="Carbonite Safe Server" regex="false" typeFilter="file">CloudScheduler.exe</NAME>
<NAME name="Google Drive" regex="false" typeFilter="file">googledrivesync.exe</NAME>
<NAME name="DropBox Installer" regex="false" typeFilter="file">dropbox.exe</NAME>
<NAME name="SugarSync" regex="false" typeFilter="file">sugarsync.exe</NAME>
<NAME name="Carbonite" regex="false" typeFilter="file">carboniteUI.exe</NAME>
<NAME name="OwnCloud" regex="false" typeFilter="file">owncloud.exe</NAME>
<NAME name="Adobe Creative Cloud" regex="false" typeFilter="file">creative cloud.exe</NAME>
<NAME name="DropBox Windows App" regex="false" typeFilter="file">DropboxUniversal.exe </NAME>
<NAME name="MEGA Privacy Windows App" regex="false" typeFilter="file">MegaApp.exe</NAME>
<NAME name="Yandex Disk" regex="false" typeFilter="file">yandexdisk2.exe</NAME>
<NAME name="eFileCabinet" regex="false" typeFilter="file">efcClient.exe</NAME>
<NAME name="Amazon Photo Backup" regex="false" typeFilter="file">amazonphotos.exe</NAME>
<NAME name="Zoho Docs" regex="false" typeFilter="file">zohodocs.exe</NAME>
<NAME name="MEGAsync" regex="false" typeFilter="file">MEGAsync.exe</NAME>
<NAME name="SpiderOak One " regex="false" typeFilter="file">SpiderOakONE.exe</NAME>
<NAME name="Box" regex="false" typeFilter="file">box.exe</NAME>
<NAME name="OneDrive" regex="false" typeFilter="file">onedrive.exe</NAME>
<NAME name="Sync" regex="false" typeFilter="file">sync-taskbar.exe</NAME>
</INTERESTING_FILE_SET>
</INTERESTING_FILE_SETS>

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<INTERESTING_FILE_SETS>
<INTERESTING_FILE_SET description="" ignoreKnown="false" name="Cryptocurrency Wallets">
<NAME name="Electrum Portable" regex="true" typeFilter="file">^electrum(.*)portable.exe</NAME>
<NAME name="Jaxx" regex="false" typeFilter="file">jaxx liberty.exe</NAME>
<NAME name="Electron Cash Standalone" regex="true" typeFilter="file">^electron-cash(.*).exe$</NAME>
<NAME name="Exodus" regex="false" typeFilter="file">exodus.exe</NAME>
<NAME name="Bitcoin Wallet" regex="false" typeFilter="file">bitcoin-qt.exe</NAME>
<NAME name="Dogecoin" regex="false" typeFilter="file">dogecoin-qt.exe</NAME>
<NAME name="Zecwallet" regex="false" typeFilter="file">Zecwallet Fullnode.exe</NAME>
<NAME name="Litecoin" regex="false" typeFilter="file">litecoin-qt.exe</NAME>
<NAME name="Zel Core" regex="false" typeFilter="file">zelcore.exe</NAME>
<NAME name="BitPay" regex="false" typeFilter="file">bitpay.exe</NAME>
<NAME name="Verge Tor QT Wallet" regex="false" typeFilter="file">verge-qt.exe</NAME>
<NAME name="Atomic Wallet" regex="false" typeFilter="file">atomic wallet.exe</NAME>
<NAME name="Bitcoin Armory" regex="false" typeFilter="file">armoryqt.exe</NAME>
<NAME name="Eidoo Wallet" regex="false" typeFilter="file">eidoo.exe</NAME>
<NAME name="Electron Cash Portable" regex="true" typeFilter="file">^electron-cash(.*)portable.exe$</NAME>
<NAME name="Monero GUI Wallet" regex="false" typeFilter="file">monero-wallet-gui.exe</NAME>
<NAME name="Coinomi Wallet" regex="false" typeFilter="file">coinomi.exe</NAME>
<NAME name="Electron Cash" regex="false" typeFilter="file">electron-cash.exe</NAME>
<NAME name="Zel Core Portable" regex="false" typeFilter="file">zelcore-portable.exe</NAME>
<NAME name="Qtum Core" regex="false" typeFilter="file">qtum-qt.exe</NAME>
<NAME name="Dash Core Wallet" regex="false" typeFilter="file">dash-qt.exe</NAME>
<NAME name="Zecwallet Lite" regex="false" typeFilter="file">Zecwallet Lite.exe</NAME>
<NAME name="Copay" regex="false" typeFilter="file">copay.exe</NAME>
<NAME name="Multidoge Wallet" regex="false" typeFilter="file">multidoge.exe</NAME>
<NAME name="Neon Wallet" regex="false" typeFilter="file">neon.exe</NAME>
<NAME name="Dash Electrum Wallet" regex="true" typeFilter="file">^electrum-dash(.*).exe$</NAME>
<NAME name="Lisk Wallet" regex="false" typeFilter="file">lisk.exe</NAME>
<NAME name="Stargazer Wallet" regex="false" typeFilter="file">stargazer.exe</NAME>
<NAME name="GreenAddress Wallet" regex="false" typeFilter="file">GreenAddress Wallet.exe</NAME>
<NAME name="Electrum" regex="true" typeFilter="file">^electrum(.*).exe</NAME>
<NAME name="Qtum Electrum" regex="true" typeFilter="file">^Qtum-electrum-win-(.*).exe$</NAME>
<NAME name="Bither" regex="false" typeFilter="file">BitherWinLauncher.exe</NAME>
<NAME name="Toast Wallet" regex="false" typeFilter="file">toastwallet.exe</NAME>
<NAME name="Guarda Wallet" regex="false" typeFilter="file">guarda.exe</NAME>
</INTERESTING_FILE_SET>
</INTERESTING_FILE_SETS>

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<INTERESTING_FILE_SETS>
<INTERESTING_FILE_SET description="Finds Encryption Programs installed on the machine" ignoreKnown="false" name="Encryption Programs">
<NAME name="CryptoExpert 8" regex="false" typeFilter="file">cexpertcmd.exe</NAME>
<NAME name="aescrypt" regex="false" typeFilter="file">aescrypt.exe</NAME>
<NAME name="7z" regex="false" typeFilter="file">7z.exe</NAME>
<NAME name="Gpg4win" regex="false" typeFilter="file">gdbus.exe</NAME>
<NAME name="AxCrypt" regex="false" typeFilter="file">AxCrypt.exe</NAME>
<NAME name="Encrypto" regex="false" typeFilter="file">Encrypto.exe</NAME>
<NAME name="Cryptomator" regex="false" typeFilter="file">Cryptomator.exe</NAME>
<NAME name="KeePass" regex="false" typeFilter="file">KeePass.exe</NAME>
<NAME name="certainsafe" regex="false" typeFilter="file">certainsafe.exe</NAME>
<NAME name="Tutanota Desktop" regex="false" typeFilter="file">Tutanota Desktop.exe</NAME>
<NAME name="BitLocker" regex="false" typeFilter="all">BitLockerDeviceEncryption.exe</NAME>
<NAME name="EncFSMP" regex="false" typeFilter="file">EncFSMP.exe</NAME>
<NAME name="HTTPS Everywhere" regex="false" typeFilter="file">HTTPS Everywhere</NAME>
<NAME name="Tor Browser" regex="false" typeFilter="all">Tor Browser</NAME>
<NAME name="CryptoExpert 8" regex="false" typeFilter="file"> cexpert_gui.exe</NAME>
<NAME name="GnuPG" regex="false" typeFilter="file"> gpg.exe</NAME>
<NAME name="Folder Lock" regex="false" typeFilter="file">Folder Lock.exe</NAME>
<NAME name="Gihosoft File Encryption" regex="false" typeFilter="file">GFileEncryption.exe</NAME>
<NAME name="VeraCrypt" regex="false" typeFilter="file">VeraCrypt.exe</NAME>
<NAME name="Proton Bridge" regex="false" typeFilter="file">Desktop-Bridge.exe</NAME>
</INTERESTING_FILE_SET>
</INTERESTING_FILE_SETS>

View File

@ -0,0 +1,2 @@
Whenever files are added or removed from this folder, StandardInterestingFilesSetsLoader.INTERESTING_FILESETS_RULES_NAMES needs to be altered accordingly.

View File

@ -80,7 +80,7 @@ class InterestingItemsFilesSetSettings implements Serializable {
private static final Logger logger = Logger.getLogger(InterestingItemsFilesSetSettings.class.getName());
private static final String TYPE_FILTER_ATTR = "typeFilter"; //NON-NLS
private static final String EXTENSION_RULE_TAG = "EXTENSION"; //NON-NLS
private static final String READONLY = "readOnly";
private static final String STANDARD_SET = "standardSet";
private static final String VERSION_NUMBER = "versionNumber";
private Map<String, FilesSet> filesSets;
@ -382,15 +382,15 @@ class InterestingItemsFilesSetSettings implements Serializable {
ignoreUnallocatedSpace = Boolean.parseBoolean(ignoreUnallocated);
}
String isReadonlyString = setElem.getAttribute(READONLY);
boolean isReadOnly = false;
if (StringUtils.isNotBlank(isReadonlyString)) {
isReadOnly = Boolean.parseBoolean(isReadonlyString);
String isStandardSetString = setElem.getAttribute(STANDARD_SET);
boolean isStandardSet = false;
if (StringUtils.isNotBlank(isStandardSetString)) {
isStandardSet = Boolean.parseBoolean(isStandardSetString);
}
String versionNumberString = setElem.getAttribute(VERSION_NUMBER);
int versionNumber = 0;
if (StringUtils.isNotBlank(isReadonlyString)) {
if (StringUtils.isNotBlank(isStandardSetString)) {
try {
versionNumber = Integer.parseInt(versionNumberString);
}
@ -424,7 +424,7 @@ class InterestingItemsFilesSetSettings implements Serializable {
// Make the files set. Note that degenerate sets with no rules are
// allowed to facilitate the separation of set definition and rule
// definitions. A set without rules is simply the empty set.
FilesSet set = new FilesSet(setName, description, ignoreKnownFiles, ignoreUnallocatedSpace, rules, isReadOnly, versionNumber);
FilesSet set = new FilesSet(setName, description, ignoreKnownFiles, ignoreUnallocatedSpace, rules, isStandardSet, versionNumber);
filesSets.put(set.getName(), set);
}
// Note: This method takes a file path to support the possibility of
@ -479,7 +479,7 @@ class InterestingItemsFilesSetSettings implements Serializable {
}
Document doc = XMLUtil.loadDoc(InterestingItemsFilesSetSettings.class, xmlFile.getPath());
return readDefinitionsXML(doc, xmlFile);
return readDefinitionsXML(doc, xmlFile.getPath());
}
/**
@ -495,25 +495,25 @@ class InterestingItemsFilesSetSettings implements Serializable {
* @throws
* org.sleuthkit.autopsy.modules.interestingitems.FilesSetsManager.FilesSetsManagerException
*/
static Map<String, FilesSet> readDefinitionsXML(Document doc, File xmlFile) throws FilesSetsManager.FilesSetsManagerException {
static Map<String, FilesSet> readDefinitionsXML(Document doc, String resourceName) throws FilesSetsManager.FilesSetsManagerException {
// Parse the XML in the file.
Map<String, FilesSet> filesSets = new HashMap<>();
if (doc == null) {
logger.log(Level.SEVERE, "FilesSet definition file at {0}", (xmlFile == null) ? "<null>" : xmlFile.getPath()); // NON-NLS
logger.log(Level.SEVERE, "FilesSet definition file at {0}", resourceName); // NON-NLS
return filesSets;
}
// Get the root element.
Element root = doc.getDocumentElement();
if (root == null) {
logger.log(Level.SEVERE, "Failed to get root {0} element tag of FilesSet definition file at {1}",
new Object[]{FILE_SETS_ROOT_TAG, (xmlFile == null) ? "<null>" : xmlFile.getPath()}); // NON-NLS
new Object[]{FILE_SETS_ROOT_TAG, resourceName}); // NON-NLS
return filesSets;
}
// Read in the files set definitions.
NodeList setElems = root.getElementsByTagName(FILE_SET_TAG);
for (int i = 0; i < setElems.getLength(); ++i) {
readFilesSet((Element) setElems.item(i), filesSets, xmlFile.getPath());
readFilesSet((Element) setElems.item(i), filesSets, resourceName);
}
return filesSets;
}
@ -561,7 +561,7 @@ class InterestingItemsFilesSetSettings implements Serializable {
setElement.setAttribute(NAME_ATTR, set.getName());
setElement.setAttribute(DESC_ATTR, set.getDescription());
setElement.setAttribute(IGNORE_KNOWN_FILES_ATTR, Boolean.toString(set.ignoresKnownFiles()));
setElement.setAttribute(READONLY, Boolean.toString(set.isReadOnly()));
setElement.setAttribute(STANDARD_SET, Boolean.toString(set.isStandardSet()));
setElement.setAttribute(VERSION_NUMBER, Integer.toString(set.getVersionNumber()));
// Add the child elements for the set membership rules.
// All conditions of a rule will be written as a single element in the xml

View File

@ -18,28 +18,24 @@
*/
package org.sleuthkit.autopsy.modules.interestingitems;
import com.google.common.collect.ImmutableList;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.logging.Level;
import org.apache.commons.io.FileUtils;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.openide.modules.OnStart;
import org.openide.util.Exceptions;
import org.openide.util.NbBundle.Messages;
import org.openide.util.io.NbObjectOutputStream;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
/**
* When the interesting items module loads, this runnable loads standard
@ -48,6 +44,14 @@ import org.sleuthkit.autopsy.coreutils.PlatformUtil;
@OnStart
public class StandardInterestingFilesSetsLoader implements Runnable {
// The list of class resources representing the standard interesting files sets
// NOTE: This list must be updated to correspond to the standard interesting files sets in 'InterestingFileSetRules'
private final static List<String> INTERESTING_FILESETS_RULES_NAMES = ImmutableList.of(
"Cloud Storage.xml",
"Cryptocurrency Wallets.xml",
"Encryption Programs.xml"
);
private static final Logger LOGGER = Logger.getLogger(StandardInterestingFilesSetsLoader.class.getName());
private static final String CONFIG_DIR = "InterestingFileSetRules";
@ -116,43 +120,6 @@ public class StandardInterestingFilesSetsLoader implements Runnable {
return standardInterestingFileSets;
}
private static List<String> getResourceFolderContents(String directory) {
// taken from https://stackoverflow.com/questions/11012819/how-can-i-get-a-resource-folder-from-inside-my-jar-file
final File jarFile = new File(StandardInterestingFilesSetsLoader.class.getProtectionDomain().getCodeSource().getLocation().getPath());
List<String> toRet = new ArrayList<>();
if(jarFile.isFile()) {
JarFile jar = null;
try {
jar = new JarFile(jarFile);
final Enumeration<JarEntry> entries = jar.entries(); //gives ALL entries in jar
while(entries.hasMoreElements()) {
final String name = entries.nextElement().getName();
if (name.startsWith(directory + "/")) { //filter according to the path
toRet.add(name);
}
}
jar.close();
} catch (IOException ex) {
LOGGER.log(Level.SEVERE, "There was an error reading contents of jar file.", ex);
} finally {
if (jar != null) {
try {
jar.close();
} catch (IOException ex) {
LOGGER.log(Level.SEVERE, "There was an error closing jar resources while loading contents.", ex);
}
}
}
} else {
LOGGER.log(Level.WARNING, "Jar file could not be opened. No standard interesting files sets will be loaded.");
}
return toRet;
}
/**
* Add the InterestingFileSetRules directory to the users app data config
* directory for Autopsy if not already present.
@ -162,14 +129,14 @@ public class StandardInterestingFilesSetsLoader implements Runnable {
* non-null.
*/
private static void copyRulesDirectory(File rulesConfigDir) {
try {
for (String resourceFile : getResourceFolderContents(DEFAULT_XML_FILTER)) {
updateStandardFilesSetConfigFile(rulesConfigDir, resourceFile);
for (String resourceFile : INTERESTING_FILESETS_RULES_NAMES) {
String resourcePath = "./" + CONFIG_DIR + "/" + resourceFile;
if (StandardInterestingFilesSetsLoader.class.getResource(resourcePath) == null) {
LOGGER.log(Level.SEVERE, String.format("Expected resource: %s could not be found at %s.", resourceFile, resourcePath));
} else {
InputStream fileSetStream = StandardInterestingFilesSetsLoader.class.getResourceAsStream(resourcePath);
updateStandardFilesSetConfigFile(rulesConfigDir, fileSetStream, resourceFile);
}
} catch (IOException ex) {
LOGGER.log(Level.SEVERE, String.format("There was an error copying %s to %s.",
resourceDirectory.getAbsolutePath(), rulesConfigDir.getAbsolutePath()), ex);
}
}
@ -178,17 +145,22 @@ public class StandardInterestingFilesSetsLoader implements Runnable {
* corresponding files set on disk or the files set on disk has an older
* version.
*
* @param rulesConfigDir The directory for standard interesting files sets.
* @param resourceInputStream The standard interesting files set resource file
* located within the jar.
* @param rulesConfigDir The directory for standard interesting files
* sets.
* @param resourceInputStream The standard interesting files set resource
* file located within the jar.
* @param resourceName The filename of the resource to be copied.
*/
private static void updateStandardFilesSetConfigFile(File rulesConfigDir, InputStream resourceInputStream, String resourceName) {
File configDirFile = new File(rulesConfigDir, resourceName);
Map<String, FilesSet> resourceFilesSet = null;
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
try {
resourceFilesSet = InterestingItemsFilesSetSettings.readDefinitionsXML(resourceFile);
} catch (FilesSetsManager.FilesSetsManagerException ex) {
DocumentBuilder builder = builderFactory.newDocumentBuilder();
Document xmlDoc = builder.parse(resourceInputStream);
resourceFilesSet = InterestingItemsFilesSetSettings.readDefinitionsXML(xmlDoc, resourceName);
} catch (ParserConfigurationException | SAXException | IOException | FilesSetsManager.FilesSetsManagerException ex) {
LOGGER.log(Level.SEVERE, "Unable to read FilesSet data from resource file: " + resourceName, ex);
return;
}
@ -243,8 +215,8 @@ public class StandardInterestingFilesSetsLoader implements Runnable {
if (destFileSet != null) {
// If and only if there is a naming conflict with a user-defined rule set, append (Custom)
// to the user-defined rule set and add it back to the Map.
if (appendCustom && srcFileSet.isReadOnly() != destFileSet.isReadOnly()) {
if (srcFileSet.isReadOnly()) {
if (appendCustom && srcFileSet.isStandardSet() != destFileSet.isStandardSet()) {
if (srcFileSet.isStandardSet()) {
addCustomFile(dest, key, destFileSet);
} else {
addCustomFile(dest, key, srcFileSet);
@ -280,8 +252,8 @@ public class StandardInterestingFilesSetsLoader implements Runnable {
"StandardInterestingFileSetsLoader.customSuffixed={0} (Custom)"
})
private static void addCustomFile(Map<String, FilesSet> dest, String key, FilesSet srcFilesSet) {
if (srcFilesSet.isReadOnly()) {
LOGGER.log(Level.SEVERE, "An attempt to create a custom file that was not readonly");
if (srcFilesSet.isStandardSet()) {
LOGGER.log(Level.SEVERE, "An attempt to create a custom file that was a standard set.");
return;
}