Exemple #1
1
 private byte[] ExtractFileFromVHD(string filename, string referenceVHD)
 {
     byte[] file = null;
     using (VirtualDisk vhdx = DiscUtils.Vhd.Disk.OpenDisk(referenceVHD, FileAccess.Read))
     {
         NtfsFileSystem vhdbNtfs = new NtfsFileSystem(vhdx.Partitions[0].Open());
         using (Stream bootStream = vhdbNtfs.OpenFile(filename, FileMode.Open, FileAccess.Read))
         {
             file = new byte[bootStream.Length];
             int totalRead = 0;
             while (totalRead < file.Length)
             {
                 totalRead += bootStream.Read(file, totalRead, file.Length - totalRead);
             }
         }
     }
     return file;
 }
        public NtfsFileStream(NtfsFileSystem fileSystem, DirectoryEntry entry, AttributeType attrType, string attrName, FileAccess access)
        {
            _entry = entry;

            _file = fileSystem.GetFile(entry.Reference);
            _baseStream = _file.OpenStream(attrType, attrName, access);
        }
Exemple #3
0
        IEnumerable <DiscUtils.DiscFileInfo> IterateFilesystem(int partitionNumber)
        {
            IEnumerable <DiscUtils.DiscFileInfo> IterateSubdir(DiscUtils.DiscDirectoryInfo subdir)
            {
                foreach (var dir in subdir.GetDirectories())
                {
                    foreach (var subfile in IterateSubdir(dir))
                    {
                        yield return(subfile);
                    }
                }

                var files = subdir.GetFiles();

                foreach (var f in files)
                {
                    yield return(f);
                }
            }

            PartitionTable disk = OpenDisk();

            if (disk == null)
            {
                Debug.WriteLine("IterateFilesystem: Failed to open disk");
                yield break;
            }
            else if (disk.Partitions.Count - 1 < partitionNumber)
            {
                Debug.WriteLine($"IterateFilesystem: Partition {partitionNumber} does not exist");
                yield break;
            }

            using (var fsStream = disk.Partitions[partitionNumber].Open())
            {
                var            partitionStream = GetPatchedNtfsPartitionStream(fsStream);
                NtfsFileSystem fs = new DiscUtils.Ntfs.NtfsFileSystem(partitionStream);

                foreach (var file in IterateSubdir(fs.Root))
                {
                    yield return(file);
                }

                fs.Dispose();
                partitionStream.Dispose();
            }
        }
Exemple #4
0
        private void FileCopy(iSCSI iscsi, DiscDirectoryInfo[] DirInfos, WimFileSystem w, NtfsFileSystem ntfs)
        {
            foreach (DiscDirectoryInfo dir in DirInfos)
            {
                if (IsExcluded(dir.FullName))
                {
                    log.InfoFormat("Directory Skip {0}", dir.FullName);
                    continue;
                }
                FileAttributes attr = dir.Attributes;
                if ((dir.Attributes & FileAttributes.ReparsePoint) == 0)
                {
                    ntfs.CreateDirectory(dir.FullName);
                    if ((attr & FileAttributes.Temporary) == FileAttributes.Temporary)
                        attr = attr & ~FileAttributes.Temporary;
                    if ((attr & FileAttributes.Offline) == FileAttributes.Offline)
                        attr = attr & ~FileAttributes.Offline;
                    ntfs.SetAttributes(dir.FullName, attr);

                    FileCopy(iscsi, dir.GetDirectories(), w, ntfs);
                    FileCopy(iscsi, dir.GetFiles(), w, ntfs);
                }
                else
                {
                    traceLog.InfoFormat("Directory ReparsePoint {0}", dir.FullName);
                    ReparsePoint rp = w.GetReparsePoint(dir.FullName);
                    ntfs.CreateDirectory(dir.FullName);
                    ntfs.SetReparsePoint(dir.FullName, rp);
                }
            }
        }
        public void Format_SmallDisk()
        {
            long size = 8 * 1024 * 1024;
            SparseMemoryStream partStream = new SparseMemoryStream();
            //VirtualDisk disk = Vhd.Disk.InitializeDynamic(partStream, Ownership.Dispose, size);
            NtfsFileSystem.Format(partStream, "New Partition", Geometry.FromCapacity(size), 0, size / 512);

            NtfsFileSystem ntfs = new NtfsFileSystem(partStream);
            ntfs.Dump(TextWriter.Null, "");
        }
        public void Format_LargeDisk()
        {
            long size = 1024L * 1024 * 1024L * 1024; // 1 TB
            SparseMemoryStream partStream = new SparseMemoryStream();
            NtfsFileSystem.Format(partStream, "New Partition", Geometry.FromCapacity(size), 0, size / 512);

            NtfsFileSystem ntfs = new NtfsFileSystem(partStream);
            ntfs.Dump(TextWriter.Null, "");
        }
        private void DoCheck()
        {
            _context.RawStream.Position = 0;
            byte[] bytes = Utilities.ReadFully(_context.RawStream, 512);

            _context.BiosParameterBlock = BiosParameterBlock.FromBytes(bytes, 0);

            //-----------------------------------------------------------------------
            // MASTER FILE TABLE
            //

            // Bootstrap the Master File Table
            _context.Mft = new MasterFileTable(_context);
            File mftFile = new File(_context, _context.Mft.GetBootstrapRecord());

            // Verify basic MFT records before initializing the Master File Table
            PreVerifyMft(mftFile);
            _context.Mft.Initialize(mftFile);

            // Now the MFT is up and running, do more detailed analysis of it's contents - double-accounted clusters, etc
            VerifyMft();
            _context.Mft.Dump(_report, "INFO: ");

            //-----------------------------------------------------------------------
            // INDEXES
            //

            // Need UpperCase in order to verify some indexes (i.e. directories).
            File ucFile = new File(_context, _context.Mft.GetRecord(MasterFileTable.UpCaseIndex, false));
            _context.UpperCase = new UpperCase(ucFile);

            SelfCheckIndexes();

            //-----------------------------------------------------------------------
            // DIRECTORIES
            //
            VerifyDirectories();

            //-----------------------------------------------------------------------
            // WELL KNOWN FILES
            //
            VerifyWellKnownFilesExist();

            //-----------------------------------------------------------------------
            // OBJECT IDS
            //
            VerifyObjectIds();

            //-----------------------------------------------------------------------
            // FINISHED
            //

            // Temporary...
            using (NtfsFileSystem fs = new NtfsFileSystem(_context.RawStream))
            {
                if ((_reportLevels & ReportLevels.Information) != 0)
                {
                    ReportDump(fs);
                }
            }
        }
Exemple #8
0
        private void CopyFile(NtfsFileSystem sourceNtfs, NtfsFileSystem destNtfs, string path)
        {
            if (IsExcluded(path))
            {
                return;
            }

            using (Stream s = sourceNtfs.OpenFile(path, FileMode.Open, FileAccess.Read))
            using (Stream d = destNtfs.OpenFile(path, FileMode.Create, FileAccess.ReadWrite))
            {
                d.SetLength(s.Length);
                int numRead = s.Read(s_copyBuffer, 0, s_copyBuffer.Length);
                while (numRead > 0)
                {
                    d.Write(s_copyBuffer, 0, numRead);
                    numRead = s.Read(s_copyBuffer, 0, s_copyBuffer.Length);
                }
            }

            destNtfs.SetSecurity(path, sourceNtfs.GetSecurity(path));
            destNtfs.SetFileStandardInformation(path, sourceNtfs.GetFileStandardInformation(path));
        }
Exemple #9
0
        protected override void DoRun()
        {
            VolumeManager volMgr = new VolumeManager();
            foreach (string disk in _diskFiles.Values)
            {
                volMgr.AddDisk(VirtualDisk.OpenDisk(disk, FileAccess.Read, UserName, Password));
            }

            Stream partitionStream = null;
            if (!string.IsNullOrEmpty(VolumeId))
            {
                partitionStream = volMgr.GetVolume(VolumeId).Open();
            }
            else if (Partition >= 0)
            {
                partitionStream = volMgr.GetPhysicalVolumes()[Partition].Open();
            }
            else
            {
                partitionStream = volMgr.GetLogicalVolumes()[0].Open();
            }

            SparseStream cacheStream = SparseStream.FromStream(partitionStream, Ownership.None);
            cacheStream = new BlockCacheStream(cacheStream, Ownership.None);

            NtfsFileSystem fs = new NtfsFileSystem(cacheStream);
            fs.NtfsOptions.HideHiddenFiles = !_showHidden.IsPresent;
            fs.NtfsOptions.HideSystemFiles = !_showSystem.IsPresent;
            fs.NtfsOptions.HideMetafiles = !_showMeta.IsPresent;

            fs.Dump(Console.Out, "");
        }
Exemple #10
0
        protected override void DoRun()
        {
            if (!IsAdministrator())
            {
                Console.WriteLine("\nThis utility must be run as an administrator!\n");
                Environment.Exit(1);
            }

            DiskImageBuilder builder = DiskImageBuilder.GetBuilder(OutputDiskType, OutputDiskVariant);
            builder.GenericAdapterType = AdapterType;

            string[] sourceVolume = _volumes.Values;

            uint diskNumber;

            List<CloneVolume> cloneVolumes = GatherVolumes(sourceVolume, out diskNumber);

            if (!Quiet)
            {
                Console.WriteLine("Inspecting Disk...");
            }

            // Construct a stream representing the contents of the cloned disk.
            BiosPartitionedDiskBuilder contentBuilder;
            Geometry biosGeometry;
            Geometry ideGeometry;
            long capacity;
            using (Disk disk = new Disk(diskNumber))
            {
                contentBuilder = new BiosPartitionedDiskBuilder(disk);
                biosGeometry = disk.BiosGeometry;
                ideGeometry = disk.Geometry;
                capacity = disk.Capacity;
            }

            // Preserve the IDE (aka Physical) geometry
            builder.Geometry = ideGeometry;

            // Translate the BIOS (aka Logical) geometry
            GeometryTranslation translation = _translation.EnumValue;
            if (builder.PreservesBiosGeometry && translation == GeometryTranslation.Auto)
            {
                // If the new format preserves BIOS geometry, then take no action if asked for 'auto'
                builder.BiosGeometry = biosGeometry;
                translation = GeometryTranslation.None;
            }
            else
            {
                builder.BiosGeometry = ideGeometry.TranslateToBios(0, translation);
            }

            if (translation != GeometryTranslation.None)
            {
                contentBuilder.UpdateBiosGeometry(builder.BiosGeometry);
            }

            IVssBackupComponents backupCmpnts;
            int status;
            if (Marshal.SizeOf(typeof(IntPtr)) == 4)
            {
                status = NativeMethods.CreateVssBackupComponents(out backupCmpnts);
            }
            else
            {
                status = NativeMethods.CreateVssBackupComponents64(out backupCmpnts);
            }

            Guid snapshotSetId = CreateSnapshotSet(cloneVolumes, backupCmpnts);

            if (!Quiet)
            {
                Console.Write("Copying Disk...");
            }

            foreach (var sv in cloneVolumes)
            {
                Volume sourceVol = new Volume(sv.SnapshotProperties.SnapshotDeviceObject, sv.SourceExtent.ExtentLength);

                SnapshotStream rawVolStream = new SnapshotStream(sourceVol.Content, Ownership.None);
                rawVolStream.Snapshot();

                byte[] volBitmap;
                int clusterSize;
                using (NtfsFileSystem ntfs = new NtfsFileSystem(rawVolStream))
                {
                    ntfs.NtfsOptions.HideSystemFiles = false;
                    ntfs.NtfsOptions.HideHiddenFiles = false;
                    ntfs.NtfsOptions.HideMetafiles = false;

                    // Remove VSS snapshot files (can be very large)
                    foreach (string filePath in ntfs.GetFiles(@"\System Volume Information", "*{3808876B-C176-4e48-B7AE-04046E6CC752}"))
                    {
                        ntfs.DeleteFile(filePath);
                    }

                    // Remove the page file
                    if (ntfs.FileExists(@"\Pagefile.sys"))
                    {
                        ntfs.DeleteFile(@"\Pagefile.sys");
                    }

                    // Remove the hibernation file
                    if (ntfs.FileExists(@"\hiberfil.sys"))
                    {
                        ntfs.DeleteFile(@"\hiberfil.sys");
                    }

                    using (Stream bitmapStream = ntfs.OpenFile(@"$Bitmap", FileMode.Open))
                    {
                        volBitmap = new byte[bitmapStream.Length];

                        int totalRead = 0;
                        int numRead = bitmapStream.Read(volBitmap, 0, volBitmap.Length - totalRead);
                        while (numRead > 0)
                        {
                            totalRead += numRead;
                            numRead = bitmapStream.Read(volBitmap, totalRead, volBitmap.Length - totalRead);
                        }
                    }

                    clusterSize = (int)ntfs.ClusterSize;

                    if (translation != GeometryTranslation.None)
                    {
                        ntfs.UpdateBiosGeometry(builder.BiosGeometry);
                    }
                }

                List<StreamExtent> extents = new List<StreamExtent>(BitmapToRanges(volBitmap, clusterSize));
                SparseStream partSourceStream = SparseStream.FromStream(rawVolStream, Ownership.None, extents);

                for (int i = 0; i < contentBuilder.PartitionTable.Partitions.Count; ++i)
                {
                    var part = contentBuilder.PartitionTable.Partitions[i];
                    if (part.FirstSector * 512 == sv.SourceExtent.StartingOffset)
                    {
                        contentBuilder.SetPartitionContent(i, partSourceStream);
                    }
                }
            }
            SparseStream contentStream = contentBuilder.Build();

            // Write out the disk images
            string dir = Path.GetDirectoryName(_destDisk.Value);
            string file = Path.GetFileNameWithoutExtension(_destDisk.Value);

            builder.Content = contentStream;
            DiskImageFileSpecification[] fileSpecs = builder.Build(file);

            for (int i = 0; i < fileSpecs.Length; ++i)
            {
                // Construct the destination file path from the directory of the primary file.
                string outputPath = Path.Combine(dir, fileSpecs[i].Name);

                // Force the primary file to the be one from the command-line.
                if (i == 0)
                {
                    outputPath = _destDisk.Value;
                }

                using (SparseStream vhdStream = fileSpecs[i].OpenStream())
                using (FileStream fs = new FileStream(outputPath, FileMode.Create, FileAccess.ReadWrite))
                {
                    StreamPump pump = new StreamPump()
                    {
                        InputStream = vhdStream,
                        OutputStream = fs,
                    };

                    long totalBytes = 0;
                    foreach (var se in vhdStream.Extents)
                    {
                        totalBytes += se.Length;
                    }

                    if (!Quiet)
                    {
                        Console.WriteLine();
                        DateTime now = DateTime.Now;
                        pump.ProgressEvent += (o, e) => { ShowProgress(fileSpecs[i].Name, totalBytes, now, o, e); };
                    }

                    pump.Run();

                    if (!Quiet)
                    {
                        Console.WriteLine();
                    }
                }
            }

            // Complete - tidy up
            CallAsyncMethod(backupCmpnts.BackupComplete);

            long numDeleteFailed;
            Guid deleteFailed;
            backupCmpnts.DeleteSnapshots(snapshotSetId, 2 /*VSS_OBJECT_SNAPSHOT_SET*/, true, out numDeleteFailed, out deleteFailed);

            Marshal.ReleaseComObject(backupCmpnts);
        }
Exemple #11
0
        public NtfsFileSystem Format(Stream stream)
        {
            _context = new NtfsContext();
            _context.Options = new NtfsOptions();
            _context.RawStream = stream;
            _context.AttributeDefinitions = new AttributeDefinitions();

            string localAdminString = (ComputerAccount == null)
                    ? "LA"
                    : new SecurityIdentifier(WellKnownSidType.AccountAdministratorSid, ComputerAccount).ToString();

            using (new NtfsTransaction())
            {
                _clusterSize = 4096;
                _mftRecordSize = 1024;
                _indexBufferSize = 4096;

                long totalClusters = ((SectorCount - 1) * Sizes.Sector) / _clusterSize;

                // Allocate a minimum of 8KB for the boot loader, but allow for more
                int numBootClusters = Utilities.Ceil(Math.Max((int)(8 * Sizes.OneKiB), BootCode == null ? 0 : BootCode.Length), _clusterSize);

                // Place MFT mirror in the middle of the volume
                _mftMirrorCluster = totalClusters / 2;
                uint numMftMirrorClusters = 1;

                // The bitmap is also near the middle
                _bitmapCluster = _mftMirrorCluster + 13;
                int numBitmapClusters = (int)Utilities.Ceil((totalClusters / 8), _clusterSize);

                // The MFT bitmap goes 'near' the start - approx 10% in - but ensure we avoid the bootloader
                long mftBitmapCluster = Math.Max(3 + (totalClusters / 10), numBootClusters);
                int numMftBitmapClusters = 1;

                // The MFT follows it's bitmap
                _mftCluster = mftBitmapCluster + numMftBitmapClusters;
                int numMftClusters = 8;

                if (_mftCluster + numMftClusters > _mftMirrorCluster
                    || _bitmapCluster + numBitmapClusters >= totalClusters)
                {
                    throw new IOException("Unable to determine initial layout of NTFS metadata - disk may be too small");
                }

                CreateBiosParameterBlock(stream, numBootClusters * _clusterSize);

                _context.Mft = new MasterFileTable(_context);
                File mftFile = _context.Mft.InitializeNew(_context, mftBitmapCluster, (ulong)numMftBitmapClusters, (long)_mftCluster, (ulong)numMftClusters);

                File bitmapFile = CreateFixedSystemFile(MasterFileTable.BitmapIndex, _bitmapCluster, (ulong)numBitmapClusters, true);
                _context.ClusterBitmap = new ClusterBitmap(bitmapFile);
                _context.ClusterBitmap.MarkAllocated(0, numBootClusters);
                _context.ClusterBitmap.MarkAllocated(_bitmapCluster, numBitmapClusters);
                _context.ClusterBitmap.MarkAllocated(mftBitmapCluster, numMftBitmapClusters);
                _context.ClusterBitmap.MarkAllocated(_mftCluster, numMftClusters);
                _context.ClusterBitmap.SetTotalClusters(totalClusters);
                bitmapFile.UpdateRecordInMft();

                File mftMirrorFile = CreateFixedSystemFile(MasterFileTable.MftMirrorIndex, _mftMirrorCluster, numMftMirrorClusters, true);

                File logFile = CreateSystemFile(MasterFileTable.LogFileIndex);
                using (Stream s = logFile.OpenStream(AttributeType.Data, null, FileAccess.ReadWrite))
                {
                    s.SetLength(Math.Min(Math.Max(2 * Sizes.OneMiB, (totalClusters / 500) * (long)_clusterSize), 64 * Sizes.OneMiB));
                    byte[] buffer = new byte[1024 * 1024];
                    for (int i = 0; i < buffer.Length; ++i)
                    {
                        buffer[i] = 0xFF;
                    }

                    long totalWritten = 0;
                    while (totalWritten < s.Length)
                    {
                        int toWrite = (int)Math.Min(s.Length - totalWritten, buffer.Length);
                        s.Write(buffer, 0, toWrite);
                        totalWritten += toWrite;
                    }
                }

                File volumeFile = CreateSystemFile(MasterFileTable.VolumeIndex);
                NtfsStream volNameStream = volumeFile.CreateStream(AttributeType.VolumeName, null);
                volNameStream.SetContent(new VolumeName(Label ?? "New Volume"));
                NtfsStream volInfoStream = volumeFile.CreateStream(AttributeType.VolumeInformation, null);
                volInfoStream.SetContent(new VolumeInformation(3, 1, VolumeInformationFlags.None));
                SetSecurityAttribute(volumeFile, "O:" + localAdminString + "G:BAD:(A;;0x12019f;;;SY)(A;;0x12019f;;;BA)");
                volumeFile.UpdateRecordInMft();

                _context.GetFileByIndex = delegate(long index) { return new File(_context, _context.Mft.GetRecord(index, false)); };
                _context.AllocateFile = delegate(FileRecordFlags frf) { return new File(_context, _context.Mft.AllocateRecord(frf, false)); };

                File attrDefFile = CreateSystemFile(MasterFileTable.AttrDefIndex);
                _context.AttributeDefinitions.WriteTo(attrDefFile);
                SetSecurityAttribute(attrDefFile, "O:" + localAdminString + "G:BAD:(A;;FR;;;SY)(A;;FR;;;BA)");
                attrDefFile.UpdateRecordInMft();

                File bootFile = CreateFixedSystemFile(MasterFileTable.BootIndex, 0, (uint)numBootClusters, false);
                SetSecurityAttribute(bootFile, "O:" + localAdminString + "G:BAD:(A;;FR;;;SY)(A;;FR;;;BA)");
                bootFile.UpdateRecordInMft();

                File badClusFile = CreateSystemFile(MasterFileTable.BadClusIndex);
                badClusFile.CreateStream(AttributeType.Data, "$Bad");
                badClusFile.UpdateRecordInMft();

                File secureFile = CreateSystemFile(MasterFileTable.SecureIndex, FileRecordFlags.HasViewIndex);
                secureFile.RemoveStream(secureFile.GetStream(AttributeType.Data, null));
                _context.SecurityDescriptors = SecurityDescriptors.Initialize(secureFile);
                secureFile.UpdateRecordInMft();

                File upcaseFile = CreateSystemFile(MasterFileTable.UpCaseIndex);
                _context.UpperCase = UpperCase.Initialize(upcaseFile);
                upcaseFile.UpdateRecordInMft();

                File objIdFile = File.CreateNew(_context, FileRecordFlags.IsMetaFile | FileRecordFlags.HasViewIndex, FileAttributeFlags.None);
                objIdFile.RemoveStream(objIdFile.GetStream(AttributeType.Data, null));
                objIdFile.CreateIndex("$O", (AttributeType)0, AttributeCollationRule.MultipleUnsignedLongs);
                objIdFile.UpdateRecordInMft();

                File reparseFile = File.CreateNew(_context, FileRecordFlags.IsMetaFile | FileRecordFlags.HasViewIndex, FileAttributeFlags.None);
                reparseFile.CreateIndex("$R", (AttributeType)0, AttributeCollationRule.MultipleUnsignedLongs);
                reparseFile.UpdateRecordInMft();

                File quotaFile = File.CreateNew(_context, FileRecordFlags.IsMetaFile | FileRecordFlags.HasViewIndex, FileAttributeFlags.None);
                Quotas.Initialize(quotaFile);

                Directory extendDir = CreateSystemDirectory(MasterFileTable.ExtendIndex);
                extendDir.AddEntry(objIdFile, "$ObjId", FileNameNamespace.Win32AndDos);
                extendDir.AddEntry(reparseFile, "$Reparse", FileNameNamespace.Win32AndDos);
                extendDir.AddEntry(quotaFile, "$Quota", FileNameNamespace.Win32AndDos);
                extendDir.UpdateRecordInMft();

                Directory rootDir = CreateSystemDirectory(MasterFileTable.RootDirIndex);
                rootDir.AddEntry(mftFile, "$MFT", FileNameNamespace.Win32AndDos);
                rootDir.AddEntry(mftMirrorFile, "$MFTMirr", FileNameNamespace.Win32AndDos);
                rootDir.AddEntry(logFile, "$LogFile", FileNameNamespace.Win32AndDos);
                rootDir.AddEntry(volumeFile, "$Volume", FileNameNamespace.Win32AndDos);
                rootDir.AddEntry(attrDefFile, "$AttrDef", FileNameNamespace.Win32AndDos);
                rootDir.AddEntry(rootDir, ".", FileNameNamespace.Win32AndDos);
                rootDir.AddEntry(bitmapFile, "$Bitmap", FileNameNamespace.Win32AndDos);
                rootDir.AddEntry(bootFile, "$Boot", FileNameNamespace.Win32AndDos);
                rootDir.AddEntry(badClusFile, "$BadClus", FileNameNamespace.Win32AndDos);
                rootDir.AddEntry(secureFile, "$Secure", FileNameNamespace.Win32AndDos);
                rootDir.AddEntry(upcaseFile, "$UpCase", FileNameNamespace.Win32AndDos);
                rootDir.AddEntry(extendDir, "$Extend", FileNameNamespace.Win32AndDos);
                SetSecurityAttribute(rootDir, "O:" + localAdminString + "G:BUD:(A;OICI;FA;;;BA)(A;OICI;FA;;;SY)(A;OICIIO;GA;;;CO)(A;OICI;0x1200a9;;;BU)(A;CI;LC;;;BU)(A;CIIO;DC;;;BU)(A;;0x1200a9;;;WD)");
                rootDir.UpdateRecordInMft();

                // A number of records are effectively 'reserved'
                for (long i = MasterFileTable.ExtendIndex + 1; i <= 15; i++)
                {
                    File f = CreateSystemFile(i);
                    SetSecurityAttribute(f, "O:S-1-5-21-1708537768-746137067-1060284298-1003G:BAD:(A;;0x12019f;;;SY)(A;;0x12019f;;;BA)");
                    f.UpdateRecordInMft();
                }
            }

            // XP-style security permissions setup
            NtfsFileSystem ntfs = new NtfsFileSystem(stream);

            ntfs.SetSecurity(@"$MFT", new RawSecurityDescriptor("O:" + localAdminString + "G:BAD:(A;;FR;;;SY)(A;;FR;;;BA)"));
            ntfs.SetSecurity(@"$MFTMirr", new RawSecurityDescriptor("O:" + localAdminString + "G:BAD:(A;;FR;;;SY)(A;;FR;;;BA)"));
            ntfs.SetSecurity(@"$LogFile", new RawSecurityDescriptor("O:" + localAdminString + "G:BAD:(A;;FR;;;SY)(A;;FR;;;BA)"));
            ntfs.SetSecurity(@"$Bitmap", new RawSecurityDescriptor("O:" + localAdminString + "G:BAD:(A;;FR;;;SY)(A;;FR;;;BA)"));
            ntfs.SetSecurity(@"$BadClus", new RawSecurityDescriptor("O:" + localAdminString + "G:BAD:(A;;FR;;;SY)(A;;FR;;;BA)"));
            ntfs.SetSecurity(@"$UpCase", new RawSecurityDescriptor("O:" + localAdminString + "G:BAD:(A;;FR;;;SY)(A;;FR;;;BA)"));
            ntfs.SetSecurity(@"$Secure", new RawSecurityDescriptor("O:" + localAdminString + "G:BAD:(A;;0x12019f;;;SY)(A;;0x12019f;;;BA)"));
            ntfs.SetSecurity(@"$Extend", new RawSecurityDescriptor("O:" + localAdminString + "G:BAD:(A;;0x12019f;;;SY)(A;;0x12019f;;;BA)"));
            ntfs.SetSecurity(@"$Extend\$Quota", new RawSecurityDescriptor("O:" + localAdminString + "G:BAD:(A;;0x12019f;;;SY)(A;;0x12019f;;;BA)"));
            ntfs.SetSecurity(@"$Extend\$ObjId", new RawSecurityDescriptor("O:" + localAdminString + "G:BAD:(A;;0x12019f;;;SY)(A;;0x12019f;;;BA)"));
            ntfs.SetSecurity(@"$Extend\$Reparse", new RawSecurityDescriptor("O:" + localAdminString + "G:BAD:(A;;0x12019f;;;SY)(A;;0x12019f;;;BA)"));

            ntfs.CreateDirectory("System Volume Information");
            ntfs.SetAttributes("System Volume Information", FileAttributes.Hidden | FileAttributes.System | FileAttributes.Directory);
            ntfs.SetSecurity("System Volume Information", new RawSecurityDescriptor("O:BAG:SYD:(A;OICI;FA;;;SY)"));

            using (Stream s = ntfs.OpenFile(@"System Volume Information\MountPointManagerRemoteDatabase", FileMode.Create))
            {
            }

            ntfs.SetAttributes(@"System Volume Information\MountPointManagerRemoteDatabase", FileAttributes.Hidden | FileAttributes.System | FileAttributes.Archive);
            ntfs.SetSecurity(@"System Volume Information\MountPointManagerRemoteDatabase", new RawSecurityDescriptor("O:BAG:SYD:(A;;FA;;;SY)"));
            return ntfs;
        }
Exemple #12
0
        protected override void DoRun()
        {
            VolumeManager volMgr = new VolumeManager();
            foreach (string disk in _diskFiles.Values)
            {
                volMgr.AddDisk(VirtualDisk.OpenDisk(disk, FileAccess.Read, UserName, Password));
            }

            VolumeInfo volInfo = null;
            if (!string.IsNullOrEmpty(VolumeId))
            {
                volInfo = volMgr.GetVolume(VolumeId);
            }
            else if (Partition >= 0)
            {
                volInfo = volMgr.GetPhysicalVolumes()[Partition];
            }
            else
            {
                volInfo = volMgr.GetLogicalVolumes()[0];
            }

            using (NtfsFileSystem fs = new NtfsFileSystem(volInfo.Open()))
            {
                MasterFileTable mft = fs.GetMasterFileTable();
                if (_recoverFile.IsPresent)
                {
                    MasterFileTableEntry entry = mft[long.Parse(_recoverFile.Value)];
                    IBuffer content = GetContent(entry);
                    if (content == null)
                    {
                        Console.WriteLine("Sorry, unable to recover content");
                        Environment.Exit(1);
                    }

                    string outFile = _recoverFile.Value + "__recovered.bin";
                    if (File.Exists(outFile))
                    {
                        Console.WriteLine("Sorry, the file already exists: " + outFile);
                        Environment.Exit(1);
                    }

                    using (FileStream outFileStream = new FileStream(outFile, FileMode.CreateNew, FileAccess.Write))
                    {
                        Pump(content, outFileStream);
                    }

                    Console.WriteLine("Possible file contents saved as: " + outFile);
                    Console.WriteLine();
                    Console.WriteLine("Caution! It is rare for the file contents of deleted files to be intact - most");
                    Console.WriteLine("likely the contents recovered are corrupt as the space has been reused.");
                }
                else
                {
                    foreach (var entry in mft.GetEntries(EntryStates.NotInUse))
                    {
                        // Skip entries with no attributes, they've probably never been used.  We're certainly
                        // not going to manage to recover any useful data from them.
                        if (entry.Attributes.Count == 0)
                            continue;

                        // Skip directories - any useful files inside will be found separately
                        if ((entry.Flags & MasterFileTableEntryFlags.IsDirectory) != 0)
                            continue;

                        long size = GetSize(entry);
                        string path = GetPath(mft, entry);

                        if (!_showMeta.IsPresent && path.StartsWith(@"<root>\$Extend"))
                            continue;

                        if (!_showZeroSize.IsPresent && size == 0)
                            continue;

                        Console.WriteLine("Index: {0,-4}   Size: {1,-8}   Path: {2}", entry.Index, Utilities.ApproximateDiskSize(size), path);
                    }
                }
            }
        }
Exemple #13
0
        protected override void DoRun()
        {
            if (DiskSize <= 0)
            {
                DisplayHelp();
                return;
            }

            using (VirtualDisk sourceDisk = VirtualDisk.OpenDisk(_sourceFile.Value, FileAccess.Read, UserName, Password))
            using (VirtualDisk destDisk = VirtualDisk.CreateDisk(OutputDiskType, OutputDiskVariant, _destFile.Value, DiskParameters, UserName, Password))
            {
                if (destDisk is DiscUtils.Vhd.Disk)
                {
                    ((DiscUtils.Vhd.Disk)destDisk).AutoCommitFooter = false;
                }

                // Copy the MBR from the source disk, and invent a new signature for this new disk
                destDisk.SetMasterBootRecord(sourceDisk.GetMasterBootRecord());
                destDisk.Signature = new Random().Next();

                SparseStream sourcePartStream = SparseStream.FromStream(sourceDisk.Partitions[0].Open(), Ownership.None);
                NtfsFileSystem sourceNtfs = new NtfsFileSystem(sourcePartStream);

                // Copy the OS boot code into memory, so we can apply it when formatting the new disk
                byte[] bootCode;
                using (Stream bootStream = sourceNtfs.OpenFile("$Boot", FileMode.Open, FileAccess.Read))
                {
                    bootCode = new byte[bootStream.Length];
                    int totalRead = 0;
                    while (totalRead < bootCode.Length)
                    {
                        totalRead += bootStream.Read(bootCode, totalRead, bootCode.Length - totalRead);
                    }
                }

                // Partition the new disk with a single NTFS partition
                BiosPartitionTable.Initialize(destDisk, WellKnownPartitionType.WindowsNtfs);
                VolumeManager volMgr = new VolumeManager(destDisk);

                string label = _labelSwitch.IsPresent ? _labelSwitch.Value : sourceNtfs.VolumeLabel;
                using (NtfsFileSystem destNtfs = NtfsFileSystem.Format(volMgr.GetLogicalVolumes()[0], label, bootCode))
                {
                    destNtfs.SetSecurity(@"\", sourceNtfs.GetSecurity(@"\"));
                    destNtfs.NtfsOptions.ShortNameCreation = ShortFileNameOption.Disabled;

                    sourceNtfs.NtfsOptions.HideHiddenFiles = false;
                    sourceNtfs.NtfsOptions.HideSystemFiles = false;
                    CopyFiles(sourceNtfs, destNtfs, @"\", true);

                    if (destNtfs.FileExists(@"\boot\BCD"))
                    {
                        // Force all boot entries in the BCD to point to the newly created NTFS partition - does _not_ cope with
                        // complex multi-volume / multi-boot scenarios at all.
                        using (Stream bcdStream = destNtfs.OpenFile(@"\boot\BCD", FileMode.Open, FileAccess.ReadWrite))
                        {
                            using (RegistryHive hive = new RegistryHive(bcdStream))
                            {
                                Store store = new Store(hive.Root);
                                foreach (var obj in store.Objects)
                                {
                                    foreach (var elem in obj.Elements)
                                    {
                                        if (elem.Format == DiscUtils.BootConfig.ElementFormat.Device)
                                        {
                                            elem.Value = DiscUtils.BootConfig.ElementValue.ForDevice(elem.Value.ParentObject, volMgr.GetPhysicalVolumes()[0]);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Exemple #14
0
        private void CopyFiles(NtfsFileSystem sourceNtfs, NtfsFileSystem destNtfs, string path, bool subs)
        {
            if (subs)
            {
                foreach (var dir in sourceNtfs.GetDirectories(path))
                {
                    if (!IsExcluded(dir))
                    {
                        int hardLinksRemaining = sourceNtfs.GetHardLinkCount(dir) - 1;
                        bool newDir = false;

                        long sourceFileId = sourceNtfs.GetFileId(dir);
                        string refPath;
                        if (_uniqueFiles.TryGetValue(sourceFileId, out refPath))
                        {
                            // If this is another name for a known dir, recreate the hard link
                            destNtfs.CreateHardLink(refPath, dir);
                        }
                        else
                        {
                            destNtfs.CreateDirectory(dir);
                            newDir = true;

                            FileAttributes fileAttrs = sourceNtfs.GetAttributes(dir);
                            if ((fileAttrs & FileAttributes.ReparsePoint) != 0)
                            {
                                destNtfs.SetReparsePoint(dir, sourceNtfs.GetReparsePoint(dir));
                            }

                            destNtfs.SetAttributes(dir, fileAttrs);

                            destNtfs.SetSecurity(dir, sourceNtfs.GetSecurity(dir));
                        }

                        // File may have a short name
                        string shortName = sourceNtfs.GetShortName(dir);
                        if (!string.IsNullOrEmpty(shortName) && shortName != dir)
                        {
                            destNtfs.SetShortName(dir, shortName);
                            --hardLinksRemaining;
                        }

                        if (newDir)
                        {
                            if (hardLinksRemaining > 0)
                            {
                                _uniqueFiles[sourceFileId] = dir;
                            }
                            CopyFiles(sourceNtfs, destNtfs, dir, subs);
                        }

                        // Set standard information last (includes modification timestamps)
                        destNtfs.SetFileStandardInformation(dir, sourceNtfs.GetFileStandardInformation(dir));
                    }
                }
            }

            foreach (var file in sourceNtfs.GetFiles(path))
            {
                Console.WriteLine(file);

                int hardLinksRemaining = sourceNtfs.GetHardLinkCount(file) - 1;

                long sourceFileId = sourceNtfs.GetFileId(file);

                string refPath;
                if (_uniqueFiles.TryGetValue(sourceFileId, out refPath))
                {
                    // If this is another name for a known file, recreate the hard link
                    destNtfs.CreateHardLink(refPath, file);
                }
                else
                {
                    CopyFile(sourceNtfs, destNtfs, file);

                    if (hardLinksRemaining > 0)
                    {
                        _uniqueFiles[sourceFileId] = file;
                    }
                }

                // File may have a short name
                string shortName = sourceNtfs.GetShortName(file);
                if (!string.IsNullOrEmpty(shortName) && shortName != file)
                {
                    destNtfs.SetShortName(file, shortName);
                }
            }
        }
Exemple #15
0
        private void FileCopy(iSCSI iscsi, DiscFileInfo[] FileInfos, WimFileSystem w, NtfsFileSystem ntfs)
        {
            foreach (DiscFileInfo file in FileInfos)
            {
                if (IsExcluded(file.FullName))
                {
                    log.InfoFormat("File Skip {0}", file.FullName);
                    continue;
                }
                FileAttributes attr = file.Attributes;
                if ((attr & FileAttributes.ReparsePoint) == 0)
                {
                    using (Stream source = w.OpenFile(file.FullName, FileMode.Open, FileAccess.Read))
                    {
                        using (Stream destin = ntfs.OpenFile(file.FullName, FileMode.Create, FileAccess.Write))
                        {
                            iscsi.WimCopy(source, destin, Path.GetFileName(file.FullName), false, wimFileIndex++, wimFileCount);
                        }
                    }

                    if ((attr & FileAttributes.Temporary) == FileAttributes.Temporary)
                        attr = attr & ~FileAttributes.Temporary;
                    if ((attr & FileAttributes.Offline) == FileAttributes.Offline)
                        attr = attr & ~FileAttributes.Offline;
                    ntfs.SetAttributes(file.FullName, attr);
                }
                else
                {
                    traceLog.InfoFormat("Reparse Point: {0}", file.FullName);
                    ReparsePoint rp = w.GetReparsePoint(file.FullName);
                    ntfs.SetReparsePoint(file.FullName, rp);
                }
            }
        }
Exemple #16
0
 private void AddBootMgr(NtfsFileSystem ntfs, byte[] BootMgr)
 {
     if (!ntfs.FileExists(@"\bootmgr"))
     {
         using (Stream bcdStream = ntfs.OpenFile(@"\bootmgr", FileMode.CreateNew, FileAccess.ReadWrite))
         {
             bcdStream.Write(BootMgr, 0, BootMgr.Length);
         }
     }
 }
Exemple #17
0
 private void AddBCD(NtfsFileSystem ntfs, byte[] BCD)
 {
     if (!ntfs.DirectoryExists(@"\boot"))
     {
         ntfs.CreateDirectory(@"\boot");
     }
     if (!ntfs.FileExists(@"\boot\BCD"))
     {
         using (Stream bcdStream = ntfs.OpenFile(@"\boot\BCD", FileMode.CreateNew, FileAccess.ReadWrite))
         {
             bcdStream.Write(BCD, 0, BCD.Length);
         }
     }
 }
Exemple #18
0
        private static void UpdateBiosGeometry(SparseStream contentStream, Geometry oldGeometry, Geometry newGeometry)
        {
            BiosPartitionTable partTable = new BiosPartitionTable(contentStream, oldGeometry);
            partTable.UpdateBiosGeometry(newGeometry);

            VolumeManager volMgr = new VolumeManager(contentStream);
            foreach (var volume in volMgr.GetLogicalVolumes())
            {
                foreach (var fsInfo in FileSystemManager.DetectDefaultFileSystems(volume.Open()))
                {
                    if (fsInfo.Name == "NTFS")
                    {
                        using (NtfsFileSystem fs = new NtfsFileSystem(volume.Open()))
                        {
                            fs.UpdateBiosGeometry(newGeometry);
                        }
                    }
                }
            }
        }
Exemple #19
-1
 private void FixBCD(NtfsFileSystem ntfs, VolumeManager volMgr)
 {
     if (ntfs.FileExists(@"\boot\BCD"))
     {
         // Force all boot entries in the BCD to point to the newly created NTFS partition - does _not_ cope with
         // complex multi-volume / multi-boot scenarios at all.
         using (Stream bcdStream = ntfs.OpenFile(@"\boot\BCD", FileMode.Open, FileAccess.ReadWrite))
         {
             using (RegistryHive hive = new RegistryHive(bcdStream))
             {
                 Store store = new Store(hive.Root);
                 foreach (var obj in store.Objects)
                 {
                     foreach (var elem in obj.Elements)
                     {
                         if (elem.Format == DiscUtils.BootConfig.ElementFormat.Device)
                         {
                             elem.Value = DiscUtils.BootConfig.ElementValue.ForDevice(elem.Value.ParentObject, volMgr.GetPhysicalVolumes()[0]);
                         }
                     }
                 }
             }
         }
     }
 }