Exemple #1
0
        public FatTable(string fileName, BootSector parentBootSector, string description, int fatTableNumber)
        {
            Description = description;

            ParentBootSector = parentBootSector;
            Logger           = ParentBootSector.Logger;
            StartAddress     = ParentBootSector.GetFatTableStartByte(fatTableNumber);

            var aLogger = Logger;//to avoid var as ref

            RawValue = Common.Common.ReadBytesFromImageAsHex(fileName, StartAddress, ParentBootSector.FatSizeInBytes(), ref aLogger);
            Size     = RawValue.Length / 2;

            if (Size != GetExpectedSize())
            {
                var err =
                    $"in {MethodBase.GetCurrentMethod().Name}.. Actual size of read Fat[{Size}] != Expected size [{GetExpectedSize()}]... Operation terminated";
                Logger.LogMessage(err, LogMsgType.Fatal);
                throw new Exception(err);
            }

            if (parentBootSector.FatType == FatType.Fat12)
            {
                //I already have the value as Hex so read only 3 hex no need to treat it as bytes
                ParsedEntries = Conversion.Split(RawValue, 6).ToList();
            }
        }
Exemple #2
0
        public FilesystemInformation(BootSector BS, FSInfoSector FSInfo)
        {
            InitializeComponent();
            this.MaximumSize = this.MinimumSize = this.Size;
            BootSector       = BS;
            FSInfoSector     = FSInfo;

            //General
            this.volumeIDLabel.Text = BootSector.GetVolumeID();
            this.volumeLabel.Text   = BootSector.GetVolumeLabel();

            //Boot Sector
            this.labelBPS.Text = BootSector.GetBytesPerSector().ToString();
            this.labelSPC.Text = BootSector.GetSectorsPerCluster().ToString();
            this.labelSectoresReservados.Text = BootSector.GetReservedSectors().ToString();
            this.labelTotalSectores.Text      = BootSector.GetTotalSectoresFAT32().ToString();
            this.labelFATSize.Text            = BootSector.SizeOfFAT().ToString();

            //FSInfo Sector
            this.lastAllocatedCluster.Text = FSInfoSector.GetLastAllocatedCluster().ToString();
            this.freeClusters.Text         = FSInfoSector.GetFreeClusterCount().ToString();

            //File Allocation Table
            fatSize.Text    = BootSector.SizeOfFAT().ToString();
            fat1Offset.Text = BootSector.FATOffset().ToString();
            fat2Offset.Text = BootSector.FAT2Offset().ToString();
        }
Exemple #3
0
        /// <summary>
        /// Gets the offset of the data (file) area
        /// </summary>
        /// <param name="bs"></param>
        /// <returns>long</returns>
        /// <exception cref="System.IO.IOException"></exception>
        public static long GetFilesOffset(BootSector bs)
        {
            var offset = GetRootDirOffset(bs);

            offset += bs.GetRootDirEntryCount() * 32;

            return(offset);
        }
        static void Main(string[] args)
        {
            char driveLetter = 'C';

            if (args.Length == 1)
            {
                driveLetter = args[0][0];
            }

            using (RawDisk disk = new RawDisk(driveLetter))
            {
                MftDiskExtents res = new MftDiskExtents();

                byte[]     ntfsBoot = disk.ReadSectors(0, 1);
                BootSector boot     = BootSector.ParseData(ntfsBoot, ntfsBoot.Length, 0);
                Console.WriteLine("MFT is at LCN " + boot.MFTCluster);

                MftDetails mft = GetMftDetails(disk, boot);
                Console.WriteLine("MFT is in " + mft.MftExtents.Length + " extents");

                res.Extents.AddRange(mft.MftExtents);

                using (RawDiskStream diskStream = disk.CreateDiskStream())
                    using (NtfsDiskStream mftStream = new NtfsDiskStream(diskStream, false, mft.MftExtents, (uint)disk.ClusterSize, 0, (long)mft.MftSize))
                    {
                        uint   sectorsPrRecord = (uint)(boot.MFTRecordSizeBytes / disk.SectorSize);
                        ushort bytesPrSector   = (ushort)disk.SectorSize;

                        int records = (int)(mftStream.Length / boot.MFTRecordSizeBytes);

                        byte[] tmp = new byte[boot.MFTRecordSizeBytes];
                        while (true)
                        {
                            int read = mftStream.Read(tmp, 0, tmp.Length);
                            if (read < boot.MFTRecordSizeBytes)
                            {
                                Console.WriteLine("Stopped reading as we got " + read + " bytes instead of " + tmp.Length + " bytes");
                                break;
                            }

                            FileRecord rec = FileRecord.Parse(tmp, 0, bytesPrSector, sectorsPrRecord);

                            // Keep track of all external extents to the MFT
                            RecordExternalDiskExtents(rec, res);

                            //// Special case for LIST attributes, since they can further reference more extents outside the MFT
                            //ProcessNonResidentListAttributes(disk, rec);
                        }
                    }

                long clustersTotal = res.Extents.Sum(x => x.Clusters);

                Console.WriteLine("To copy: {0:N0} extents", res.Extents.Count);
                Console.WriteLine("{0:N0} clusters, {1:N0} bytes", clustersTotal, clustersTotal * disk.ClusterSize);
            }

            Console.ReadLine();
        }
 private void GetDiskBootSector()
 {
     DiskStream.Seek(0, SeekOrigin.Begin);
     byte[] bTemp = new byte[512];
     DiskStream.Read(bTemp, 0, 512);
     DiskBootSector = new BootSector(bTemp);
     DiskBootSector.FATOffset();
     DiskBootSector.SectorOffsetForCluster(4);
 }
Exemple #6
0
 public FatSharp(FileStream fatfs)
 {
     lock (fatfs)
     {
         fatfs.Seek(0, SeekOrigin.Begin);
         byte[] block = new byte[512];
         fatfs.Read(block, 0, 512);
         BPB = BootSector.Create(block, fatfs);
         //FatStream = fatfs;
     }
 }
Exemple #7
0
        /// <summary>
        /// Gets the offset (in bytes) of the root directory with the given index
        /// </summary>
        /// <param name="bs"></param>
        /// <returns>long</returns>
        /// <exception cref="System.IO.IOException"></exception>
        public static long GetRootDirOffset(BootSector bs)
        {
            long sectSize    = bs.GetBytesPerSector();
            var  sectsPerFat = bs.GetSectorsPerFat();
            var  fats        = bs.GetNrFats();

            var offset = GetFatOffset(bs, 0);

            offset += fats * sectsPerFat * sectSize;

            return(offset);
        }
Exemple #8
0
        /// <summary>
        /// Gets the offset (in bytes) of the fat with the given index
        /// </summary>
        /// <param name="bs"></param>
        /// <param name="fatNr">(0..)</param>
        /// <returns>long</returns>
        /// <exception cref="System.IO.IOException"></exception>
        public static long GetFatOffset(BootSector bs, int fatNr)
        {
            long sectSize    = bs.GetBytesPerSector();
            var  sectsPerFat = bs.GetSectorsPerFat();
            long resSects    = bs.GetNrReservedSectors();

            var offset  = resSects * sectSize;
            var fatSize = sectsPerFat * sectSize;

            offset += fatNr * fatSize;

            return(offset);
        }
Exemple #9
0
        private void BS_Read()
        {
            FileInfo fi = new FileInfo(SelectedFile);
            //Ok here we go.

            BootSector bs = BootSector.Load(fi.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None));

            DirEntBase[] d = bs.Root.LoadDirEnts();
            Print("Loaded {0} DirEnts in the root directory!", d.Length);
            int free = 0;

            for (int i = 0; i < d.Length; i++)
            {
                DoEvents();
                if (d[i].IsLFNEnt)
                {
                    Print("Entry {0} is a long filename entry.", i);
                }
                else if (d[i].IsDIREnt)
                {
                    string Name = d[i].DirEnt.Filename;
                    if ((Name == "." || Name == ".."))
                    {
                        Print("Entry {0} is a reference to itself or parent directory.");
                        continue;
                    }
                    Print("Entry {0} is a normal Directory Entry.", i);
                    DirectoryEntry de = new DirectoryEntry(d, i);
                    Print("{0}: Short Name: {1}", i, de.ShortFilename);
                    Print("{0}: Long  Name: {1}", i, de.LongFilename);
                    Print("{0}: Attributes: {1}", i, de.Attributes);
                    Print("{0}: Starts at Cluster: {1} and is {2} byte(s) long.", i, de.StartCluster, de.FileLength);
                    if ((de.Attributes & FATFileAttribute.SubDirectory) == FATFileAttribute.SubDirectory)
                    {
                        DumpDirectory("/" + de.LongFilename, bs, de.StartCluster);
                    }
                }
                else if (d[i].IsDeletedFile)
                {
                    Print("Entry {0} contains a deleted file", i);
                    Print("{0}: {1}", i, d[i].DirEnt.EightDOTThreeName);
                }
                else
                {
                    free++;
                }
            }
            Print("There are {0} free entries out of {1} total entries", free, d.Length);
            Print("The root directory is {0}% Full.", Math.Floor(((((double)d.Length - (double)free) / (double)d.Length) * 100)));
            GC.KeepAlive(bs);
        }
Exemple #10
0
        private void InitiateBoot()
        {
            // Read first 512 bytes
            byte[] data = new byte[512];
            _diskStream.Seek(0, SeekOrigin.Begin);
            _diskStream.Read(data, 0, data.Length);

            // Parse boot
            _boot = BootSector.ParseData(data, data.Length, 0);

            // Get filerecord size
            BytesPrFileRecord = _boot.MFTRecordSizeBytes;
            _sectorsPrRecord  = _boot.MFTRecordSizeBytes / _boot.BytesPrSector;
        }
        private void CreateBoot()
        {
            boot = new BootSector();
            byte[] bootSector = boot.DataWritter();
            BytesOccupied += (uint)bootSector.Length;

            var memory = new MemoryStream();

            memory.Write(bootSector, 0, bootSector.Length);
            memory.Flush();
            memory.Seek(0, SeekOrigin.Begin);
            memory.CopyTo(diskStream);
            //diskStream.Position = bootSector.Length;
        }
Exemple #12
0
        private void DumpDirectory(string Path, BootSector BPB, int ClusterNumber)
        {
            Cluster pointer = Cluster.Load(BPB, (ushort)ClusterNumber);

            Print("In directory:", Path);
            DirEntBase[] d    = pointer.DirectoryEntries;
            int          free = 0;

            for (int i = 0; i < d.Length; i++)
            {
                DoEvents();
                if (d[i].IsLFNEnt)
                {
                    Print("Entry {0} is a long filename entry.", i);
                }
                else if (d[i].IsDIREnt)
                {
                    string Name = d[i].DirEnt.Filename;
                    if ((Name == "." || Name == ".."))
                    {
                        Print("Entry {0} is a reference to itself or parent directory.");
                        continue;
                    }
                    Print("Entry {0} is a normal Directory Entry.", i);
                    DirectoryEntry de = new DirectoryEntry(d, i);
                    Print("{0}: Short Name: {1}", i, de.ShortFilename);
                    Print("{0}: Long  Name: {1}", i, de.LongFilename);
                    Print("{0}: Attributes: {1}", i, de.Attributes);
                    Print("{0}: Starts at Cluster: {1} and is {2} byte(s) long.", i, de.StartCluster, de.FileLength);
                    if ((de.Attributes & FATFileAttribute.SubDirectory) == FATFileAttribute.SubDirectory)
                    {
                        DumpDirectory(Path + "/" + de.LongFilename, BPB, de.StartCluster);
                    }
                }
                else if (d[i].IsDeletedFile)
                {
                    Print("Entry {0} contains a deleted file", i);
                    Print("{0}: {1}", i, d[i].DirEnt.EightDOTThreeName);
                }
                else
                {
                    free++;
                }
            }
        }
Exemple #13
0
        public void obtenerArchivo(BootSector BS, FileStream stream, FileAllocationTable FAT, String path)
        {
            List <byte[]> bytes = new List <byte[]>();
            MemoryStream  ms    = new MemoryStream();

            byte[] archivo = null;

            int Cluster = Entry.GetFirstCluster();

            while (Cluster != -1)
            {
                //Leer archivo
                byte[] tempByte = new byte[BS.GetBytesPerSector()];
                stream.Seek(BS.SectorOffsetForCluster(Cluster), SeekOrigin.Begin);
                stream.Read(tempByte, 0, BS.GetBytesPerSector());
                bytes.Add(tempByte);

                //Obtener el siguiente cluster
                Cluster = FAT.nextClusterInChain(Cluster);
            }

            if (bytes.Count > 0)
            {
                foreach (byte[] b in bytes)
                {
                    ms.Write(b, 0, b.Length);
                }

                ms.Seek(0, SeekOrigin.Begin);
                archivo = new byte[Entry.FileSize];
                ms.Read(archivo, 0, archivo.Length);

                Console.WriteLine(ms.Length);
            }

            if (archivo != null)
            {
                File.WriteAllBytes(path + Entry.NombreDeDir, archivo);
                MessageBox.Show("Archivo(s) extraido(s) exitosamente!", "Extraccion de Archivo(s)", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
            {
                MessageBox.Show("Archivo devuelto en cero!", "Error al extraer archivo", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        private static MftDetails GetMftDetails(RawDisk disk, BootSector boot)
        {
            byte[]     mftFirst = disk.ReadClusters((long)boot.MFTCluster, 1);
            FileRecord rec      = FileRecord.Parse(mftFirst, 0, (ushort)disk.SectorSize, (uint)(boot.MFTRecordSizeBytes / disk.SectorSize));

            // Get DATA attrib
            // TODO: Handle multiple DATA attributes
            AttributeGeneric dataAttrib = null;

            foreach (Attribute attribute in rec.Attributes)
            {
                if (attribute.Type == AttributeType.DATA && attribute.AttributeName.Length == 0)
                {
                    // Got it!
                    dataAttrib = attribute as AttributeGeneric;
                    break;
                }
            }

            Debug.Assert(dataAttrib != null);

            MftDetails res = new MftDetails();

            // Get attribute data
            // Parse out extents
            if (dataAttrib.NonResidentFlag == ResidentFlag.Resident)
            {
                byte[] dataAttribData = dataAttrib.Data;

                res.MftSize    = dataAttrib.ResidentHeader.ContentLength;
                res.MftExtents = DataFragment.ParseFragments(dataAttribData, dataAttribData.Length, 0, 0, 0);
            }
            else
            {
                res.MftSize    = dataAttrib.NonResidentHeader.ContentSize;
                res.MftExtents = dataAttrib.NonResidentHeader.Fragments;
            }

            Debug.Assert(res.MftExtents != null);

            return(res);
        }
Exemple #15
0
        private void Initialize()
        {
            byte[] data = new byte[512];
            DiskStream.Seek(0, SeekOrigin.Begin);
            DiskStream.Read(data, 0, data.Length);
            BootSector = BootSector.ParseData(data, 512, 0);

            BytesPerFileRecord = BootSector.MftRecordSizeBytes;
            SectorsPerRecord   = BytesPerFileRecord / BytesPerSector;

            MftFile   = ParseMftRecordData(ReadMftRecordData((uint)MetadataMftFiles.Mft));
            MftStream = OpenFileRecord(MftFile);

            AttributeData mftFileData = null;

            foreach (var att in MftFile.Attributes)
            {
                if (att is AttributeData attributeData)
                {
                    mftFileData = attributeData;
                }
            }

            if (mftFileData == null)
            {
                throw new Exception("ntfs error: unable to load mft data");
            }

            long clusterBytes = 0;

            foreach (var frag in mftFileData.DataFragments)
            {
                clusterBytes += frag.Clusters * BytesPerCluster;
            }

            FileRecordCount = (uint)(clusterBytes / BytesPerFileRecord);
            FileRecords     = new FileRecord[FileRecordCount];
            FileRecords[0]  = MftFile;

            Console.WriteLine("[NTFSDRV2] Initialized with " + FileRecordCount + " file records");
        }
Exemple #16
0
        void ParseChildren(ref FatDirectoryArea parent, BootSector bs)
        {
            if (!parent.IsThisEntryaDirectory())
            {
                return;
            }
            int dataAreaStartLoc = parent.GetDataLocation();
            List <FatDirectoryArea> longNames = new List <FatDirectoryArea>();

            while (true)
            {
                var directory = Common.Common.GetUnit <FatDirectoryArea>(fileName, ref aLogger, dataAreaStartLoc,
                                                                         "[Child]DirectoryArea-" + parent.Description, bs);

                dataAreaStartLoc += Common.Common.FatDirectoryAreaSizeBytes;
                if (directory.IsEmpty)
                {
                    break;
                }

                if (directory.IsThisEntryaLongFileName())
                {
                    longNames.Add(directory);
                }
                else
                {
                    if (longNames.Count > 0)
                    {
                        directory.LongFileNames = longNames;
                        longNames = new List <FatDirectoryArea>();
                    }
                    parent.ChildrenList.Add(directory);
                }

                //if (directory.IsThisEntryaDirectory())
                //{
                //    ParseChildren(ref directory,  bs);
                //}
            }
        }
        private void Formatear()
        {
            try
            {
                if (DiskStream != null)
                {
                    //Nulificar archivo
                    DiskStream.Seek(0, SeekOrigin.Begin);
                    DiskStream.SetLength(0);
                    DiskStream.Flush();
                    DiskStream.SetLength(DiskSize);
                    DiskStream.Flush();

                    //Escribir el BootSector
                    BootSector BootSector = new BootSector((int)DiskStream.Length, NewsectorPorCluster, NewVolumeLabel);
                    BootSector.WriteBootSector(DiskStream);

                    //Escribir FSInfoSector
                    FSInfoSector FSInfoSector = new FSInfoSector();
                    FSInfoSector.WriteInformationSector(DiskStream);

                    //Inicializar Tabla FAT - Offset 32 despues de los sectores reservados
                    FileAllocationTable NewFAT = new FileAllocationTable(BootSector);
                    NewFAT.WriteNewFAT(DiskStream);
                    FSInfoSector.UpdateFreeClusters(1, BootSector);
                    FSInfoSector.UpdateLastAllocatedCluster(2);
                    FSInfoSector.WriteInformationSector(DiskStream);

                    MessageBox.Show("La imagen de disco ha sido formateada!", "Formato Completo", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }
Exemple #18
0
 public FAT(BootSector bs, FileStream fstr)
 {
     BPB = bs;
     //Woops.
     FATStream = fstr;
 }
Exemple #19
0
        private void InitializeNTFS()
        {
            // Read $BOOT
            if (Provider.MftFileOnly)
            {
                Boot                  = new BootSector();
                Boot.OEMCode          = "NTFS";
                Boot.SectorsPrCluster = 2;                      // Small cluster
                Boot.BytesPrSector    = 512;                    // Smallest possible sector

                // Get FileRecord size (read first record's size)
                byte[] mft_data = new byte[512];
                Provider.ReadBytes(mft_data, 0, 0, mft_data.Length);

                Boot.MFTRecordSizeBytes = FileRecord.ParseAllocatedSize(mft_data, 0);

                mft_data = null;
            }
            else
            {
                byte[] drive_data = new byte[512];
                Provider.ReadBytes(drive_data, 0, 0, 512);
                Boot = BootSector.ParseData(drive_data, 512, 0);

                drive_data = null;

                Debug.Assert(Boot.OEMCode == "NTFS");
            }

            // Get FileRecord size
            BytesPrFileRecord = Boot.MFTRecordSizeBytes;
            _sectorsPrRecord  = BytesPrFileRecord / BytesPrSector;
            Debug.WriteLine($"Updated BytesPrFileRecord, now set to {BytesPrFileRecord}");

            // Prep cache
            MftRawCache = new RawDiskCache(0);

            // Read $MFT file record

            byte[] record_data = ReadMFTRecordData((uint)SpecialMFTFiles.MFT);
            FileMFT     = ParseMFTRecord(record_data);
            record_data = null;


            Debug.Assert(FileMFT != null);

            Debug.Assert(FileMFT.Attributes.Count(s => s.Type == AttributeType.DATA) == 1);
            AttributeData fileMftData = FileMFT.Attributes.OfType <AttributeData>().Single();

            Debug.Assert(fileMftData.NonResidentFlag == ResidentFlag.NonResident);
            Debug.Assert(fileMftData.DataFragments.Length >= 1);

            MftStream = OpenFileRecord(FileMFT);

            // Prep cache
            long maxLength          = MftStream.Length;
            long toAllocateForCache = Math.Min(maxLength, _rawDiskCacheSizeRecords * BytesPrFileRecord);

            MftRawCache = new RawDiskCache((int)toAllocateForCache);

            // Get number of FileRecords
            FileRecordCount = (uint)((fileMftData.DataFragments.Sum(s => (float)s.Clusters)) * (BytesPrCluster * 1f / BytesPrFileRecord));
            FileRecords     = new WeakReference[FileRecordCount];

            FileRecords[0] = new WeakReference(FileMFT);

            // Read $VOLUME file record
            FileRecord fileVolume = ReadMFTRecord(SpecialMFTFiles.Volume);

            // Get version
            Attribute versionAttrib = fileVolume.Attributes.SingleOrDefault(s => s.Type == AttributeType.VOLUME_INFORMATION);

            if (versionAttrib != null)
            {
                AttributeVolumeInformation attrib = (AttributeVolumeInformation)versionAttrib;
                NTFSVersion = new Version(attrib.MajorVersion, attrib.MinorVersion);
            }
        }
        private void Formatear(FileStream stream)
        {
            try
            {
                byte SectoresPorCluster = 0x00;

                //Obtener el numero de sectores por cluster
                switch (tamanoSectoresPorCluster.SelectedIndex)
                {
                case 0:
                    //1 sector por cluster = Clusters de 512 bytes
                    SectoresPorCluster = 0x01;
                    break;

                case 1:
                    //2 sectores por cluster = Clusters de 1 KiB
                    SectoresPorCluster = 0x02;
                    break;

                case 2:
                    //4 sectores por cluster = Clusters de 2 KiB
                    SectoresPorCluster = 0x04;
                    break;

                case 3:
                    //8 sectores por cluster = Clusters de 4 KiB
                    SectoresPorCluster = 0x08;
                    break;

                case 4:
                    //16 sectores por cluster = Clusters de 8 KiB
                    SectoresPorCluster = 0x10;
                    break;

                case 5:
                    //32 sectores por cluster = Clusters de 16KiB
                    SectoresPorCluster = 0x20;
                    break;

                default:
                    SectoresPorCluster = 0x01;
                    break;
                }

                //Escribir el BootSector
                BootSector BootSector = new BootSector((int)stream.Length, SectoresPorCluster, txtVolLabel.Text);
                BootSector.WriteBootSector(stream);

                //Escribir FSInfoSector
                FSInfoSector FSInfoSector = new FSInfoSector();
                FSInfoSector.WriteInformationSector(stream);

                //Inicializar Tabla FAT - Offset 32, despues de los sectores reservados
                FileAllocationTable NewFAT = new FileAllocationTable(BootSector);
                NewFAT.WriteNewFAT(stream);
                FSInfoSector.UpdateFreeClusters(1, BootSector);
                FSInfoSector.UpdateLastAllocatedCluster(2);
                FSInfoSector.WriteInformationSector(stream);

                MessageBox.Show("La imagen de disco ha sido creada y formateada!", "Formato Completo", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }
Exemple #21
0
 private void _read()
 {
     _bootSector = new BootSector(m_io, this, m_root);
 }