/** * Go down the registry tree to find a key with the given name. * * @param root Root of the registry hive * @param name Name of the subkey to seach for * @return The matching subkey or null if not found */ public RegistryKey findKey(RegistryKey root, String name) { RegistryKey currentKey = root; // Split the key name into parts String[] parts = name.split("\\\\"); for (String part : parts) { if (part.length() > 0) { try { currentKey = currentKey.getSubkey(part); } catch (Exception ex) { // We get an exception if the value wasn't found (not a RegistryParseException). // There doesn't seem to be a cleaner way to test for existance without cycling though // everything ourselves. (Broad catch because things other than RegistryParseException // can happen) return null; } } } // If we make it this far, we've found it return currentKey; }
/** * Test the Registry object against one registry file. * * @param a_regInfo The registry file * @return Result of the test */ private ObservableResult testRegistryFile(RegistryFileInfo a_regInfo) { try { RegistryKey root = openRegistry(a_regInfo.tempFileName); RegistryKey result = findKey(root, obj.getKey().getValue().toString()); if (result == null) { // Take another shot looking for the key minus the first part of the path (sometimes the // hive file name is here). This should only happen if the hive name started // with "HKEY" if ((obj.getHive() != null) && obj.getHive().getValue().toString().startsWith("HKEY")) { // NON-NLS String[] parts = obj.getKey().getValue().toString().split("\\\\"); String newKey = ""; for (int i = 1; i < parts.length; i++) { if (newKey.length() > 0) { newKey += "\\"; } newKey += parts[i]; } result = findKey(root, newKey); } if (result == null) { return new ObservableResult( id, "RegistryObject: Could not find key " + obj.getKey().getValue(), // NON-NLS spacing, ObservableResult.ObservableState.FALSE, null); } } if ((obj.getValues() == null) || (obj.getValues().getValues().isEmpty())) { // No values to test List<StixArtifactData> artData = new ArrayList<StixArtifactData>(); artData.add( new StixArtifactData(a_regInfo.abstractFile.getId(), id, "Registry")); // NON-NLS return new ObservableResult( id, "RegistryObject: Found key " + obj.getKey().getValue(), // NON-NLS spacing, ObservableResult.ObservableState.TRUE, artData); } // Test all the values for (org.mitre.cybox.objects.RegistryValueType stixRegValue : obj.getValues().getValues()) { try { for (RegistryValue valFromFile : result.getValueList()) { // Test if the name field matches (if present) boolean nameSuccess = true; // True if the name matches or isn't present if (stixRegValue.getName() != null) { try { nameSuccess = compareStringObject(stixRegValue.getName(), valFromFile.getName()); } catch (UnsupportedEncodingException ex) { nameSuccess = false; } } boolean valueSuccess = true; if (nameSuccess && (stixRegValue.getData() != null)) { switch (valFromFile.getValueType()) { case REG_SZ: case REG_EXPAND_SZ: try { valueSuccess = compareStringObject( stixRegValue.getData(), valFromFile.getValue().getAsString()); } catch (UnsupportedEncodingException ex) { valueSuccess = false; } break; case REG_DWORD: case REG_BIG_ENDIAN: case REG_QWORD: // Only support "equals" for now. if ((stixRegValue.getData().getCondition() == null) || (stixRegValue.getData().getCondition() == ConditionTypeEnum.EQUALS)) { // Try to convert the STIX string to a long try { long stixValue = Long.decode(stixRegValue.getData().getValue().toString()); try { valueSuccess = (stixValue == valFromFile.getValue().getAsNumber()); } catch (UnsupportedEncodingException ex) { valueSuccess = false; } } catch (NumberFormatException ex) { // We probably weren't looking at a numeric field to begin with, // so getting this exception isn't really an error. valueSuccess = false; } } else { valueSuccess = false; } break; default: // Nothing to do here. These are the types we don't handle: // REG_BIN, REG_FULL_RESOURCE_DESCRIPTOR, REG_LINK, REG_MULTI_SZ, REG_NONE, // REG_RESOURCE_LIST, REG_RESOURCE_REQUIREMENTS_LIST } } if (nameSuccess && valueSuccess) { // Found a match for all values List<StixArtifactData> artData = new ArrayList<StixArtifactData>(); artData.add( new StixArtifactData(a_regInfo.abstractFile.getId(), id, "Registry")); // NON-NLS return new ObservableResult( id, "RegistryObject: Found key " + obj.getKey().getValue() // NON-NLS + " and value " + stixRegValue.getName().getValue().toString() // NON-NLS + " = " + stixRegValue.getData().getValue().toString(), spacing, ObservableResult.ObservableState.TRUE, artData); } } } catch (Exception ex) { // Broad catch here becase the registry parser can create all kinds of exceptions beyond // what it reports. return new ObservableResult( id, "RegistryObject: Exception during evaluation: " + ex.getLocalizedMessage(), // NON-NLS spacing, ObservableResult.ObservableState.INDETERMINATE, null); } } } catch (TskCoreException ex) { return new ObservableResult( id, "RegistryObject: Exception during evaluation: " + ex.getLocalizedMessage(), // NON-NLS spacing, ObservableResult.ObservableState.INDETERMINATE, null); } return new ObservableResult( id, "RegistryObject: Not done", // NON-NLS spacing, ObservableResult.ObservableState.INDETERMINATE, null); }