public void Dump(TextWriter writer, string indent) { writer.WriteLine(indent + "SECURITY DESCRIPTORS"); using (Stream s = _file.OpenStream(AttributeType.Data, "$SDS", FileAccess.Read)) { byte[] buffer = Utilities.ReadFully(s, (int)s.Length); foreach (KeyValuePair <IdIndexKey, IdIndexData> entry in _idIndex.Entries) { int pos = (int)entry.Value.SdsOffset; SecurityDescriptorRecord rec = new SecurityDescriptorRecord(); if (!rec.Read(buffer, pos)) { break; } string secDescStr = "--unknown--"; if (rec.SecurityDescriptor[0] != 0) { RawSecurityDescriptor sd = new RawSecurityDescriptor(rec.SecurityDescriptor, 0); secDescStr = sd.GetSddlForm(AccessControlSections.All); } writer.WriteLine(indent + " SECURITY DESCRIPTOR RECORD"); writer.WriteLine(indent + " Hash: " + rec.Hash); writer.WriteLine(indent + " Id: " + rec.Id); writer.WriteLine(indent + " File Offset: " + rec.OffsetInFile); writer.WriteLine(indent + " Size: " + rec.EntrySize); writer.WriteLine(indent + " Value: " + secDescStr); } } }
private SecurityDescriptor ReadDescriptor(IndexData data) { using (Stream s = _file.OpenStream(AttributeType.Data, "$SDS", FileAccess.Read)) { s.Position = data.SdsOffset; byte[] buffer = Utilities.ReadFully(s, data.SdsLength); SecurityDescriptorRecord record = new SecurityDescriptorRecord(); record.Read(buffer, 0); return(new SecurityDescriptor(new RawSecurityDescriptor(record.SecurityDescriptor, 0))); } }
public uint AddDescriptor(RawSecurityDescriptor newDescriptor) { // Search to see if this is a known descriptor SecurityDescriptor newDescObj = new SecurityDescriptor(newDescriptor); uint newHash = newDescObj.CalcHash(); byte[] newByteForm = new byte[newDescObj.Size]; newDescObj.WriteTo(newByteForm, 0); foreach (KeyValuePair <HashIndexKey, HashIndexData> entry in _hashIndex.FindAll(new HashFinder(newHash))) { SecurityDescriptor stored = ReadDescriptor(entry.Value); byte[] storedByteForm = new byte[stored.Size]; stored.WriteTo(storedByteForm, 0); if (Utilities.AreEqual(newByteForm, storedByteForm)) { return(entry.Value.Id); } } long offset = _nextSpace; // Write the new descriptor to the end of the existing descriptors SecurityDescriptorRecord record = new SecurityDescriptorRecord(); record.SecurityDescriptor = newByteForm; record.Hash = newHash; record.Id = _nextId; // If we'd overflow into our duplicate block, skip over it to the // start of the next block if ((offset + record.Size) / BlockSize % 2 == 1) { _nextSpace = Utilities.RoundUp(offset, BlockSize * 2); offset = _nextSpace; } record.OffsetInFile = offset; byte[] buffer = new byte[record.Size]; record.WriteTo(buffer, 0); using (Stream s = _file.OpenStream(AttributeType.Data, "$SDS", FileAccess.ReadWrite)) { s.Position = _nextSpace; s.Write(buffer, 0, buffer.Length); s.Position = BlockSize + _nextSpace; s.Write(buffer, 0, buffer.Length); } // Make the next descriptor land at the end of this one _nextSpace = Utilities.RoundUp(_nextSpace + buffer.Length, 16); _nextId++; // Update the indexes HashIndexData hashIndexData = new HashIndexData(); hashIndexData.Hash = record.Hash; hashIndexData.Id = record.Id; hashIndexData.SdsOffset = record.OffsetInFile; hashIndexData.SdsLength = (int)record.EntrySize; HashIndexKey hashIndexKey = new HashIndexKey(); hashIndexKey.Hash = record.Hash; hashIndexKey.Id = record.Id; _hashIndex[hashIndexKey] = hashIndexData; IdIndexData idIndexData = new IdIndexData(); idIndexData.Hash = record.Hash; idIndexData.Id = record.Id; idIndexData.SdsOffset = record.OffsetInFile; idIndexData.SdsLength = (int)record.EntrySize; IdIndexKey idIndexKey = new IdIndexKey(); idIndexKey.Id = record.Id; _idIndex[idIndexKey] = idIndexData; _file.UpdateRecordInMft(); return(record.Id); }
public uint AddDescriptor(RawSecurityDescriptor newDescriptor) { // Search to see if this is a known descriptor SecurityDescriptor newDescObj = new SecurityDescriptor(newDescriptor); uint newHash = newDescObj.CalcHash(); byte[] newByteForm = new byte[newDescObj.Size]; newDescObj.WriteTo(newByteForm, 0); foreach (var entry in _hashIndex.FindAll(new HashFinder(newHash))) { SecurityDescriptor stored = ReadDescriptor(entry.Value); byte[] storedByteForm = new byte[stored.Size]; stored.WriteTo(storedByteForm, 0); if (Utilities.AreEqual(newByteForm, storedByteForm)) { return(entry.Value.Id); } } long offset = _nextSpace; // Write the new descriptor to the end of the existing descriptors SecurityDescriptorRecord record = new SecurityDescriptorRecord(); record.SecurityDescriptor = newByteForm; record.Hash = newHash; record.Id = _nextId; record.OffsetInFile = offset; byte[] buffer = new byte[record.Size]; record.WriteTo(buffer, 0); if (offset + buffer.Length > 0x40000) { throw new NotImplementedException("Excessive number of security descriptors - running into redundant storage area"); } using (Stream s = _file.OpenStream(AttributeType.Data, "$SDS", FileAccess.ReadWrite)) { s.Position = _nextSpace; s.Write(buffer, 0, buffer.Length); s.Position = 0x40000 + _nextSpace; s.Write(buffer, 0, buffer.Length); } // Make the next descriptor land at the end of this one _nextSpace = Utilities.RoundUp(_nextSpace + buffer.Length, 16); _nextId++; // Update the indexes HashIndexData hashIndexData = new HashIndexData(); hashIndexData.Hash = record.Hash; hashIndexData.Id = record.Id; hashIndexData.SdsOffset = record.OffsetInFile; hashIndexData.SdsLength = (int)record.EntrySize; HashIndexKey hashIndexKey = new HashIndexKey(); hashIndexKey.Hash = record.Hash; hashIndexKey.Id = record.Id; _hashIndex[hashIndexKey] = hashIndexData; IdIndexData idIndexData = new IdIndexData(); idIndexData.Hash = record.Hash; idIndexData.Id = record.Id; idIndexData.SdsOffset = record.OffsetInFile; idIndexData.SdsLength = (int)record.EntrySize; IdIndexKey idIndexKey = new IdIndexKey(); idIndexKey.Id = record.Id; _idIndex[idIndexKey] = idIndexData; _file.UpdateRecordInMft(); return(record.Id); }