Esempio n. 1
0
 protected NtfsFileEntry(Ntfs ntfs, FileRecord record, AttributeFileName fileName)
 {
     this.ntfs = ntfs;
     MFTRecord = record;
     FileName  = fileName;
     Init();
 }
Esempio n. 2
0
        internal NtfsDirectory(NTFSWrapper ntfsWrapper, FileRecord record, AttributeFileName fileName)
            : base(ntfsWrapper, record, fileName)
        {
            Debug.Assert(record.Flags.HasFlag(FileEntryFlags.Directory));

            PrepRecord();
        }
Esempio n. 3
0
 protected NtfsFileEntry(NTFSWrapper ntfsWrapper, FileRecord record, AttributeFileName fileName)
 {
     NTFSWrapper = ntfsWrapper;
     MFTRecord   = record;
     FileName    = fileName;
     Init();
 }
Esempio n. 4
0
        public static AttributeFileName GetPreferredDisplayName(FileRecord record)
        {
            AttributeFileName posix       = null;
            AttributeFileName win32       = null;
            AttributeFileName dos         = null;
            AttributeFileName win32AndDos = null;

            foreach (var a in record.Attributes)
            {
                if (a is AttributeFileName fileName)
                {
                    switch (fileName.FilenameNamespace)
                    {
                    case FileNamespace.POSIX:
                        posix = fileName;
                        break;

                    case FileNamespace.DOS:
                        dos = fileName;
                        break;

                    case FileNamespace.Win32:
                        win32 = fileName;
                        break;

                    case FileNamespace.Win32AndDOS:
                        win32AndDos = fileName;
                        break;
                    }
                }
            }

            if (win32 != null)
            {
                return(win32);
            }
            if (win32AndDos != null)
            {
                return(win32AndDos);
            }
            if (posix != null)
            {
                return(posix);
            }
            if (dos != null)
            {
                return(dos);
            }

            throw new Exception("ntfs: invalid filename attribute");
        }
Esempio n. 5
0
        internal static NtfsFileEntry CreateEntry(Ntfs ntfs, uint fileId, AttributeFileName fileName = null)
        {
            var record = ntfs.ReadMftRecord(fileId);

            if (fileName == null)
            {
                fileName = NtfsUtils.GetPreferredDisplayName(record);
            }

            if ((record.Flags & FileEntryFlags.Directory) != 0)
            {
                return(new NtfsDirectory(ntfs, record, fileName));
            }
            return(new NtfsFile(ntfs, record, fileName));
        }
Esempio n. 6
0
        public string BuildFileName(FileRecord record, string rootName = null)
        {
            // Get filename (and prefer the non-8dot3 variant)
            AttributeFileName fileName = NtfsUtils.GetPreferredDisplayName(record);

            if (fileName == null)
            {
                throw new NullReferenceException("Record has no FileName attribute");
            }

            string path = fileName.FileName;

            if (record.Flags.HasFlag(FileEntryFlags.Directory))
            {
                path += '\\';
            }

            // Continue till we hit SpecialMFTFiles.RootDir
            FileRecord parentRecord;

            do
            {
                // Get parent
                parentRecord = ReadMFTRecord(fileName.ParentDirectory.FileId);

                if (parentRecord == null)
                {
                    throw new NullReferenceException("A parent record was null");
                }

                fileName = NtfsUtils.GetPreferredDisplayName(parentRecord);

                if (fileName == null)
                {
                    throw new NullReferenceException("A parent record had no Filename attribute");
                }

                if (parentRecord.FileReference.FileId == (uint)SpecialMFTFiles.RootDir)
                {
                    path = rootName + '\\' + path;
                    break;
                }
                path = fileName.FileName + '\\' + path;
            }while (true);

            return(path);
        }
Esempio n. 7
0
 internal NtfsDirectory(Ntfs ntfs, FileRecord record, AttributeFileName fileName)
     : base(ntfs, record, fileName)
 {
 }
        private static void PrettyPrintAttribute(NTFSParser parser, Options options, FileRecord record, Attribute attrib, int indentCount)
        {
            string indent = "";

            for (int i = 0; i < indentCount; i++)
            {
                indent += SingleIndent;
            }

            AwesomeConsole.Write(indent + attrib.Id + ": ");
            PrintType(attrib.Type);

            AwesomeConsole.Write(" ");
            PrintName(attrib.AttributeName, true, true);

            if (attrib.NonResidentFlag == ResidentFlag.NonResident)
            {
                AwesomeConsole.Write(" (NonResident)", ConsoleColor.Red);
            }

            AwesomeConsole.WriteLine();

            indent += SingleIndent;

            switch (attrib.Type)
            {
            case AttributeType.STANDARD_INFORMATION:
                AttributeStandardInformation standardInformation = (AttributeStandardInformation)attrib;

                AwesomeConsole.WriteLine(indent + "Creation Time: " + standardInformation.TimeCreated + " " + standardInformation.TimeCreated.Kind);
                AwesomeConsole.WriteLine(indent + "Modified Time: " + standardInformation.TimeModified + " " + standardInformation.TimeModified.Kind);
                AwesomeConsole.WriteLine(indent + "Accessed Time: " + standardInformation.TimeAccessed + " " + standardInformation.TimeAccessed.Kind);
                AwesomeConsole.WriteLine(indent + "Mft Modified : " + standardInformation.TimeMftModified + " " + standardInformation.TimeMftModified.Kind);

                break;

            case AttributeType.ATTRIBUTE_LIST:
                AttributeList list = (AttributeList)attrib;

                foreach (AttributeListItem listItem in list.Items)
                {
                    AwesomeConsole.Write(indent + listItem.AttributeId + ": ");
                    PrintType(listItem.Type);
                    AwesomeConsole.Write(" ");

                    PrintName(listItem.Name, true, true);
                    AwesomeConsole.Write(" ");

                    if (record.FileReference == listItem.BaseFile)
                    {
                        AwesomeConsole.Write("(this record)", ConsoleColor.DarkGray);
                    }
                    else
                    {
                        PrintReference(listItem.BaseFile);
                    }

                    AwesomeConsole.WriteLine();
                }

                break;

            case AttributeType.FILE_NAME:
                AttributeFileName fileName = (AttributeFileName)attrib;

                using (AwesomeConsole.BeginSequentialWrite())
                {
                    AwesomeConsole.Write(indent + "Parent dir: ");
                    AwesomeConsole.WriteLine(fileName.ParentDirectory, ConsoleColor.Cyan);
                }

                AwesomeConsole.WriteLine(indent + "Namespace: " + fileName.FilenameNamespace);

                AwesomeConsole.Write(indent + "Flags: ");
                PrintEnums(fileName.FileFlags);
                AwesomeConsole.WriteLine();

                AwesomeConsole.Write(indent + "Name: ");
                PrintName(fileName.FileName, false, true);
                AwesomeConsole.WriteLine();

                AwesomeConsole.WriteLine(indent + "C Time: " + fileName.CTime + " " + fileName.CTime.Kind);
                AwesomeConsole.WriteLine(indent + "M Time: " + fileName.MTime + " " + fileName.MTime.Kind);
                AwesomeConsole.WriteLine(indent + "A Time: " + fileName.ATime + " " + fileName.ATime.Kind);
                AwesomeConsole.WriteLine(indent + "R Time: " + fileName.RTime + " " + fileName.RTime.Kind);

                break;

            case AttributeType.DATA:
                AttributeData data = (AttributeData)attrib;

                if (data.NonResidentFlag == ResidentFlag.Resident)
                {
                    AwesomeConsole.WriteLine(indent + "Data length: {0:N0} Bytes", data.ResidentHeader.ContentLength);
                }
                else
                {
                    AwesomeConsole.WriteLine(indent + "Data length: {0:N0} Bytes", data.NonResidentHeader.ContentSize);

                    AwesomeConsole.Write(indent + "VCN: ");
                    PrintRange(parser, options, data.NonResidentHeader.StartingVCN, data.NonResidentHeader.EndingVCN - data.NonResidentHeader.StartingVCN);
                    AwesomeConsole.WriteLine();

                    AwesomeConsole.WriteLine(indent + "Fragments: {0:N0}", data.NonResidentHeader.Fragments.Length);

                    AwesomeConsole.WriteLine(indent + SingleIndent + "LCN-range, cluster count, VCN-range", ConsoleColor.DarkGray);

                    foreach (DataFragment fragment in data.NonResidentHeader.Fragments)
                    {
                        AwesomeConsole.Write(indent + SingleIndent);
                        PrintRange(parser, options, fragment.LCN, fragment.Clusters);
                        AwesomeConsole.Write(SingleIndent);
                        PrintSize(parser, options, fragment.Clusters);
                        AwesomeConsole.Write(SingleIndent);
                        PrintRange(parser, options, fragment.StartingVCN, fragment.Clusters);

                        if (fragment.IsCompressed)
                        {
                            AwesomeConsole.Write(" (Compressed)");
                        }
                        if (fragment.IsSparseFragment)
                        {
                            AwesomeConsole.Write(" (Sparse)");
                        }

                        AwesomeConsole.WriteLine();
                    }
                }

                break;

            case AttributeType.OBJECT_ID:
                AttributeObjectId objectId = (AttributeObjectId)attrib;

                AwesomeConsole.Write(indent + "ObjectId    : ");
                PrintGUID(objectId.ObjectId);
                AwesomeConsole.WriteLine();

                AwesomeConsole.Write(indent + "BithVolumeId: ");
                PrintGUID(objectId.BithVolumeId);
                AwesomeConsole.WriteLine();

                AwesomeConsole.Write(indent + "BithObjectId: ");
                PrintGUID(objectId.BithObjectId);
                AwesomeConsole.WriteLine();

                AwesomeConsole.Write(indent + "DomainId    : ");
                PrintGUID(objectId.DomainId);
                AwesomeConsole.WriteLine();

                break;

            case AttributeType.SECURITY_DESCRIPTOR:
                AttributeSecurityDescriptor securityDescriptor = (AttributeSecurityDescriptor)attrib;

                AwesomeConsole.Write(indent + "SID: ");
                PrintSID(securityDescriptor.UserSID);
                AwesomeConsole.WriteLine();

                AwesomeConsole.Write(indent + "GID: ");
                PrintSID(securityDescriptor.GroupSID);
                AwesomeConsole.WriteLine();

                AwesomeConsole.Write(indent + "Flags: ");
                PrintEnums(securityDescriptor.ControlFlags);
                AwesomeConsole.WriteLine();

                AwesomeConsole.WriteLine();

                AwesomeConsole.WriteLine(indent + "SACL: " + (securityDescriptor.SACL == null ? 0 : securityDescriptor.SACL.ACECount));
                if (securityDescriptor.SACL == null)
                {
                    AwesomeConsole.WriteLine(indent + SingleIndent + "Not present", ConsoleColor.Red);
                }
                else
                {
                    foreach (ACE ace in securityDescriptor.SACL.ACEs)
                    {
                        PrintACE(indent, ace);
                    }
                }

                AwesomeConsole.WriteLine(indent + "DACL: " + (securityDescriptor.DACL == null ? 0 : securityDescriptor.DACL.ACECount));
                if (securityDescriptor.DACL == null)
                {
                    AwesomeConsole.WriteLine(indent + SingleIndent + "Not present", ConsoleColor.Red);
                }
                else
                {
                    foreach (ACE ace in securityDescriptor.DACL.ACEs)
                    {
                        PrintACE(indent, ace);
                    }
                }

                break;

            case AttributeType.VOLUME_NAME:
                AttributeVolumeName volumeName = (AttributeVolumeName)attrib;

                AwesomeConsole.Write(indent + "Name: ");
                PrintName(volumeName.VolumeName);
                AwesomeConsole.WriteLine();

                break;

            case AttributeType.VOLUME_INFORMATION:
                AttributeVolumeInformation volumeInformation = (AttributeVolumeInformation)attrib;

                AwesomeConsole.WriteLine(indent + "Reserved: " + volumeInformation.Reserved);
                AwesomeConsole.WriteLine(indent + "MajorVersion: " + volumeInformation.MajorVersion + "." + volumeInformation.MinorVersion);

                AwesomeConsole.Write(indent + "VolumeInformationFlag: ");
                PrintEnums(volumeInformation.VolumeInformationFlag);
                AwesomeConsole.WriteLine();

                break;

            case AttributeType.INDEX_ROOT:
                AttributeIndexRoot indexRoot = (AttributeIndexRoot)attrib;

                AwesomeConsole.WriteLine(indent + "IndexType: " + indexRoot.IndexType);
                AwesomeConsole.WriteLine(indent + "CollationRule: " + indexRoot.CollationRule);
                AwesomeConsole.WriteLine(indent + "IndexAllocationSize: " + indexRoot.IndexAllocationSize);
                AwesomeConsole.WriteLine(indent + "ClustersPrIndexRecord: " + indexRoot.ClustersPrIndexRecord);
                AwesomeConsole.WriteLine();

                AwesomeConsole.WriteLine(indent + "SizeOfIndexTotal: " + indexRoot.SizeOfIndexTotal);
                AwesomeConsole.WriteLine(indent + "IndexFlags: " + indexRoot.IndexFlags);
                AwesomeConsole.WriteLine(indent + "Entries: " + indexRoot.Entries.Length);

                foreach (IndexEntry entry in indexRoot.Entries)
                {
                    AwesomeConsole.Write(indent + SingleIndent);
                    PrintReference(entry.FileRefence);

                    if (entry.ChildFileName != null)
                    {
                        AwesomeConsole.Write(" ");
                        PrintName(entry.ChildFileName.FileName, true);
                        AwesomeConsole.Write(" ");
                        PrintEnums(entry.ChildFileName.FileFlags);
                    }

                    AwesomeConsole.WriteLine();
                }

                break;

            case AttributeType.INDEX_ALLOCATION:
                AttributeIndexAllocation indexAllocation = (AttributeIndexAllocation)attrib;

                AwesomeConsole.WriteLine(indent + "Chunks: " + indexAllocation.Indexes.Length);

                for (int i = 0; i < indexAllocation.Indexes.Length; i++)
                {
                    IndexAllocationChunk chunk = indexAllocation.Indexes[i];
                    AwesomeConsole.WriteLine(indent + SingleIndent + string.Format("{0:N0}: {1:N0} of {2:N0} Bytes used", i, chunk.SizeOfIndexTotal, chunk.SizeOfIndexAllocated));
                }

                AwesomeConsole.WriteLine(indent + "Entries: " + indexAllocation.Entries.Length);

                foreach (IndexEntry entry in indexAllocation.Entries)
                {
                    AwesomeConsole.Write(indent + SingleIndent);
                    PrintReference(entry.FileRefence);

                    if (entry.ChildFileName != null)
                    {
                        AwesomeConsole.Write(" ");
                        PrintName(entry.ChildFileName.FileName, true);
                        AwesomeConsole.Write(" ");
                        PrintEnums(entry.ChildFileName.FileFlags);
                    }

                    AwesomeConsole.WriteLine();
                }

                break;

            case AttributeType.BITMAP:
                AttributeBitmap bitmap = (AttributeBitmap)attrib;

                AwesomeConsole.WriteLine(indent + "Bitfield Size: {0:N0} ({1:N0} bytes)", bitmap.Bitfield.Length, bitmap.Bitfield.Length / 8);

                // Print out 4 lines of 64 bits
                const int bitsPrLine = 64;

                for (int line = 0; line < 4; line++)
                {
                    if (bitmap.Bitfield.Length <= line * bitsPrLine)
                    {
                        break;
                    }

                    AwesomeConsole.Write(indent + "{0,-6}", (line * bitsPrLine) + ":");

                    for (int offset = line * bitsPrLine; offset < line * bitsPrLine + bitsPrLine; offset += 8)
                    {
                        if (bitmap.Bitfield.Length <= offset)
                        {
                            break;
                        }

                        for (int j = offset; j < offset + 8; j++)
                        {
                            if (bitmap.Bitfield.Length <= j)
                            {
                                break;
                            }

                            AwesomeConsole.Write(bitmap.Bitfield[j] ? "1" : "0");
                        }

                        AwesomeConsole.Write(" ");
                    }

                    AwesomeConsole.WriteLine();
                }

                if (bitmap.Bitfield.Length > 256)
                {
                    PrintError(indent + "Bitfield was longer than 256 bits, so the rest wasn't printed.");
                    AwesomeConsole.WriteLine();
                }

                break;

            case AttributeType.LOGGED_UTILITY_STREAM:
                AttributeLoggedUtilityStream loggedUtilityStream = (AttributeLoggedUtilityStream)attrib;

                AwesomeConsole.WriteLine(indent + "Data: {0:N0} Bytes", loggedUtilityStream.Data.Length);

                break;

            default:
                if (Debugger.IsAttached)
                {
                    Debugger.Break();
                }
                PrintError(attrib.Type + " not supported");
                break;
            }
        }
        static void Main(string[] args)
        {
            const char driveLetter = 'E';
            RawDisk    disk        = new RawDisk(driveLetter);

            using (Stream stream = disk.CreateDiskStream())
                using (Stream streama = disk.CreateDiskStream())
                {
                    NTFSParser parser  = new NTFSParser(stream);
                    NTFSParser parsera = new NTFSParser(streama);

                    int longest = 0;
                    foreach (FileRecord record in parser.GetRecords(true))
                    {
                        int count = record.Attributes.Count;

                        if (count > longest)
                        {
                            longest = count;
                            Console.WriteLine(record.FileReference + " - " + count);
                        }
                    }
                }

            NTFSDiskProvider provider = new NTFSDiskProvider(disk);

            NTFSWrapper ntfsWrapper = new NTFSWrapper(provider, 524288);

            ntfsWrapper.InitializeCommon();

            Console.WriteLine("Read NTFS. Version: " + ntfsWrapper.NTFSVersion);

            // Filerecord bitmap
            ntfsWrapper.ParseNonResidentAttribute(ntfsWrapper.FileMFT.Attributes.OfType <AttributeBitmap>().Single());
            BitArray bitmapData = ntfsWrapper.FileMFT.Attributes.OfType <AttributeBitmap>().Single().Bitfield;

            HashSet <AttributeType> types = new HashSet <AttributeType>();

            // Read fragmented file
            for (uint i = 0; i < ntfsWrapper.FileRecordCount; i++)
            {
                if (!ntfsWrapper.InRawDiskCache(i))
                {
                    ntfsWrapper.PrepRawDiskCache(i);
                }

                if (!bitmapData[(int)i])
                {
                    continue;
                }

                FileRecord record = ntfsWrapper.ReadMFTRecord(i);

                if (record.Flags.HasFlag(FileEntryFlags.FileInUse))
                {
                    ntfsWrapper.ParseNonResidentAttributes(record);
                }

                Console.Write("Read {0:N0} of {1:N0} - ({2:N0} bytes {3:N0} allocated)", i, ntfsWrapper.FileRecordCount, record.SizeOfFileRecord, record.SizeOfFileRecordAllocated);

                if (record.Flags.HasFlag(FileEntryFlags.FileInUse))
                {
                    Console.ForegroundColor = ConsoleColor.Magenta;
                    Console.Write(" (InUse)");
                    Console.ForegroundColor = ConsoleColor.Gray;
                }
                else
                {
                    Console.ForegroundColor = ConsoleColor.DarkMagenta;
                    Console.Write(" (Not InUse)");
                    Console.ForegroundColor = ConsoleColor.Gray;
                }

                if (bitmapData[(int)i])
                {
                    Console.ForegroundColor = ConsoleColor.Magenta;
                    Console.Write(" (Bitmap:InUse)");
                    Console.ForegroundColor = ConsoleColor.Gray;
                }
                else
                {
                    Console.ForegroundColor = ConsoleColor.DarkMagenta;
                    Console.Write(" (Bitmap:Not InUse)");
                    Console.ForegroundColor = ConsoleColor.Gray;
                }

                if (record.Flags.HasFlag(FileEntryFlags.Directory))
                {
                    Console.ForegroundColor = ConsoleColor.Yellow;
                    Console.Write(" (dir)");
                    Console.ForegroundColor = ConsoleColor.Gray;
                }

                if (record.BaseFile.FileId != 0)
                {
                    Console.ForegroundColor = ConsoleColor.Yellow;
                    Console.Write(" (base: {0})", record.BaseFile);
                    Console.ForegroundColor = ConsoleColor.Gray;
                }

                if (Enum.IsDefined(typeof(SpecialMFTFiles), record.FileReference.FileId))
                {
                    Console.ForegroundColor = ConsoleColor.Green;
                    Console.Write(" ({0})", (SpecialMFTFiles)record.FileReference.FileId);
                    Console.ForegroundColor = ConsoleColor.Gray;
                }

                Console.WriteLine();

                foreach (Attribute attribute in record.Attributes.Concat(record.ExternalAttributes).OrderBy(s => s.Id))
                {
                    bool wasNew = types.Add(attribute.Type);
                    if (wasNew)
                    {
                        File.AppendAllLines("out.txt", new[] { record.FileReference + ": " + attribute.Type });
                        Debugger.Break();
                    }

                    string name = string.IsNullOrWhiteSpace(attribute.AttributeName) ? string.Empty : " '" + attribute.AttributeName + "'";

                    Console.Write("  " + attribute.Id + " (" + attribute.Type);

                    if (name != string.Empty)
                    {
                        Console.ForegroundColor = ConsoleColor.Green;
                        Console.Write(name);
                        Console.ForegroundColor = ConsoleColor.Gray;
                    }

                    Console.Write(")");

                    AttributeFileName attributeFileName = attribute as AttributeFileName;
                    if (attributeFileName != null)
                    {
                        Console.ForegroundColor = ConsoleColor.Red;
                        Console.Write(" '{0}'", attributeFileName.FileName);
                        Console.ForegroundColor = ConsoleColor.Gray;
                    }

                    AttributeData attributeData = attribute as AttributeData;
                    if (attributeData != null)
                    {
                        Console.ForegroundColor = ConsoleColor.Red;
                        Console.Write(" {0}", attributeData.NonResidentFlag);

                        Console.ForegroundColor = ConsoleColor.Green;
                        Console.Write(" ({0:N0} bytes)", attributeData.NonResidentFlag == ResidentFlag.NonResident ? attributeData.NonResidentHeader.ContentSize : (ulong)attributeData.DataBytes.Length);

                        if (attributeData.NonResidentFlag == ResidentFlag.Resident)
                        {
                            Console.ForegroundColor = ConsoleColor.Red;
                            Console.Write(" ('{0}')", Encoding.ASCII.GetString(attributeData.DataBytes, 0, Math.Min(attributeData.DataBytes.Length, 30)));
                        }
                        else
                        {
                            Console.ForegroundColor = ConsoleColor.Cyan;
                            Console.WriteLine();

                            foreach (DataFragment fragment in attributeData.DataFragments)
                            {
                                Console.Write("    LCN: {0:N0} ({1:N0} clusters) ", fragment.LCN, fragment.Clusters);

                                if (fragment.IsCompressed)
                                {
                                    Console.ForegroundColor = ConsoleColor.Blue;
                                    Console.Write(" (Compressed)");
                                    Console.ForegroundColor = ConsoleColor.Cyan;
                                }

                                if (fragment.IsSparseFragment)
                                {
                                    Console.ForegroundColor = ConsoleColor.Blue;
                                    Console.Write(" (Sparse)");
                                    Console.ForegroundColor = ConsoleColor.Cyan;
                                }

                                Console.WriteLine();
                            }
                        }

                        Console.ForegroundColor = ConsoleColor.Gray;
                    }

                    Console.WriteLine();
                }

                Console.WriteLine();
            }

            Console.WriteLine("Done.");
            Console.ReadLine();
        }
Esempio n. 10
0
 internal NtfsFileEntry CreateEntry(uint fileId, AttributeFileName fileName = null)
 {
     return(CreateEntry(ntfs, fileId, fileName));
 }
Esempio n. 11
0
        internal static NtfsFileEntry CreateEntry(NTFSWrapper ntfsWrapper, uint fileId, AttributeFileName fileName = null)
        {
            if (fileName == null)
            {
                // Dig up a preferred name
                FileRecord tmpRecord = ntfsWrapper.ReadMFTRecord(fileId);
                fileName = NtfsUtils.GetPreferredDisplayName(tmpRecord);
            }

            NtfsFileEntry entry = ntfsWrapper.FileCache.Get(fileId, fileName.FileName.GetHashCode());

            if (entry != null)
            {
                Debug.WriteLine("Got from cache: " + fileId + ":" + fileName.Id);
                return(entry);
            }

            // Create it
            FileRecord record = ntfsWrapper.ReadMFTRecord(fileId);

            if (record.Flags.HasFlag(FileEntryFlags.Directory))
            {
                entry = new NtfsDirectory(ntfsWrapper, record, fileName);
            }
            else
            {
                entry = new NtfsFile(ntfsWrapper, record, fileName);
            }

            ntfsWrapper.FileCache.Set(fileId, fileName.Id, entry);

            return(entry);
        }