예제 #1
0
        private static byte[] GetRecordBytesPrivate(string volume, int index)
        {
            // Get filestream based on hVolume
            using (FileStream streamToRead = Helper.getFileStream(volume))
            {
                // Get Volume Boot Record
                NtfsVolumeBootRecord VBR = VolumeBootRecord.Get(streamToRead) as NtfsVolumeBootRecord;

                // Determine start of MFT
                long mftStartOffset = VBR.MftStartIndex * VBR.BytesPerCluster;

                // Get FileRecord for $MFT
                FileRecord mftRecord = MasterFileTable.GetRecord(streamToRead, volume);

                // Get $MFT Data Attribute
                NonResident data = null;

                foreach (FileRecordAttribute attr in mftRecord.Attribute)
                {
                    if (attr.Name == FileRecordAttribute.ATTR_TYPE.DATA)
                    {
                        data = attr as NonResident;
                        break;
                    }
                }

                // Iterate through fragments of the MFT
                foreach (DataRun dr in data.DataRun)
                {
                    long DataRunRecords = (dr.ClusterLength * VBR.BytesPerCluster) / VBR.BytesPerFileRecord;

                    // Check if index can be found in current DataRun
                    if (index < (int)DataRunRecords)
                    {
                        long   recordOffset   = (dr.StartCluster * VBR.BytesPerCluster) + (index * VBR.BytesPerFileRecord);
                        byte[] recordBytesRaw = Helper.readDrive(streamToRead, recordOffset, VBR.BytesPerFileRecord);

                        ApplyFixup(ref recordBytesRaw, (int)VBR.BytesPerFileRecord);

                        return(recordBytesRaw);
                    }

                    // Decrement index for the number of FileRecords in the current DataRun
                    else
                    {
                        index -= ((int)dr.ClusterLength * VBR.BytesPerCluster) / (int)VBR.BytesPerFileRecord;
                    }
                }
                throw new Exception("Could not find the FileRecord requested...");
            }
        }
예제 #2
0
        internal static FileRecord GetRecord(FileStream streamToRead, string volume)
        {
            // Instantiate VolumeBootRecord object
            NtfsVolumeBootRecord VBR = VolumeBootRecord.Get(streamToRead) as NtfsVolumeBootRecord;

            // Calculate byte offset to the Master File Table (MFT)
            long mftOffset = (VBR.BytesPerCluster * VBR.MftStartIndex);

            // Read bytes belonging to specified MFT Record
            byte[] recordBytes = Helper.readDrive(streamToRead, mftOffset, VBR.BytesPerFileRecord);

            // Instantiate a FileRecord object for the $MFT file
            return(FileRecord.Get(recordBytes, volume, (int)VBR.BytesPerFileRecord, true));
        }
        public static Prefetch[] GetInstances(string volume)
        {
            // Get current volume
            NativeMethods.getVolumeName(ref volume);

            // Get volume letter
            string volLetter = volume.Split('\\')[3];

            // Get a handle to the volume
            IntPtr hVolume = NativeMethods.getHandle(volume);

            // Create a FileStream to read from the volume handle
            using (FileStream streamToRead = NativeMethods.getFileStream(hVolume))
            {
                VolumeBootRecord VBR = VolumeBootRecord.Get(streamToRead);

                // Get a byte array representing the Master File Table
                byte[] MFT = MasterFileTable.GetBytes(streamToRead, volume);

                // Build Prefetch directory path
                string pfPath = volLetter + @"\Windows\Prefetch";

                if (Directory.Exists(pfPath))
                {
                    var        pfFiles = System.IO.Directory.GetFiles(pfPath, "*.pf");
                    Prefetch[] pfArray = new Prefetch[pfFiles.Length];

                    // Get IndexEntry
                    IndexEntry[] pfEntries = IndexEntry.GetInstances(pfPath);

                    int i = 0;

                    foreach (IndexEntry entry in pfEntries)
                    {
                        if (entry.Filename.Contains(".pf"))
                        {
                            pfArray[i] = new Prefetch(new FileRecord(NativeMethods.GetSubArray(MFT, (uint)entry.RecordNumber * 0x400, 0x400), volume, true).GetBytes(VBR));
                            i++;
                        }
                    }

                    return(pfArray);
                }
                else
                {
                    throw new Exception("Prefetch Directory does not exist. Check registry to ensure Prefetching is enabled.");
                }
            }
        }
예제 #4
0
        public bool Identify(IMediaImage imagePlugin, Partition partition)
        {
            if (12 + partition.Start >= partition.End)
            {
                return(false);
            }

            byte[] vbrSector = imagePlugin.ReadSector(0 + partition.Start);
            if (vbrSector.Length < 512)
            {
                return(false);
            }

            VolumeBootRecord vbr = Marshal.ByteArrayToStructureLittleEndian <VolumeBootRecord>(vbrSector);

            return(signature.SequenceEqual(vbr.signature));
        }
예제 #5
0
        public static Prefetch[] GetInstances(string volume)
        {
            // Get current volume
            Util.getVolumeName(ref volume);

            // Get a handle to the volume
            IntPtr hVolume = Util.getHandle(volume);

            // Create a FileStream to read from the volume handle
            using (FileStream streamToRead = Util.getFileStream(hVolume))
            {
                VolumeBootRecord VBR = VolumeBootRecord.Get(streamToRead);

                // Get a byte array representing the Master File Table
                byte[] MFT = MasterFileTable.GetBytes(streamToRead, volume);

                // Build Prefetch directory path
                string pfPath = volume.Split('\\')[3] + @"\Windows\Prefetch";

                /*if(CheckStatus(volume.Split('\\')[3] + @"\Windows\system32\config\SAM") != PREFETCH_ENABLED.DISABLED)
                 * {*/
                // Get IndexEntry
                IndexEntry[] pfEntries = IndexEntry.GetInstances(pfPath);
                Prefetch[]   pfArray   = new Prefetch[pfEntries.Length];

                int i = 0;

                foreach (IndexEntry entry in pfEntries)
                {
                    if (entry.Filename.Contains(".pf"))
                    {
                        pfArray[i] = new Prefetch(new FileRecord(Util.GetSubArray(MFT, (uint)entry.RecordNumber * 0x400, 0x400), volume, true).GetContent(VBR));
                        i++;
                    }
                }

                return(pfArray);

                /*}
                 * else
                 * {
                 *  throw new Exception("Prefetching is disabled. Check registry to ensure Prefetching is enabled.");
                 * }*/
            }
        }
예제 #6
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="volume"></param>
        /// <returns></returns>
        public static Prefetch[] GetInstances(string volume)
        {
            // Get current volume
            Helper.getVolumeName(ref volume);

            using (FileStream streamToRead = Helper.getFileStream(volume))
            {
                NtfsVolumeBootRecord VBR = VolumeBootRecord.Get(streamToRead) as NtfsVolumeBootRecord;

                // Get a byte array representing the Master File Table
                byte[] MFT = MasterFileTable.GetBytes(streamToRead, volume);

                // Build Prefetch directory path
                string pfPath = Helper.GetVolumeLetter(volume) + @"\Windows\Prefetch";

                /*if(CheckStatus(Helper.GetVolumeLetter(volume) + @"\Windows\system32\config\SAM") != PREFETCH_ENABLED.DISABLED)
                 * {*/
                // Get IndexEntry
                IndexEntry[] pfEntries = IndexEntry.GetInstances(pfPath);
                Prefetch[]   pfArray   = new Prefetch[pfEntries.Length];

                int i = 0;

                foreach (IndexEntry entry in pfEntries)
                {
                    if (entry.Filename.Contains(".pf"))
                    {
                        pfArray[i] = new Prefetch(FileRecord.Get(volume, (int)entry.RecordNumber, true).GetContent(VBR));
                        i++;
                    }
                }

                return(pfArray);

                /*}
                 * else
                 * {
                 *  throw new Exception("Prefetching is disabled. Check registry to ensure Prefetching is enabled.");
                 * }*/
            }
        }
예제 #7
0
        internal static int[] GetFatEntry(string volume, int startSector)
        {
            FatVolumeBootRecord vbr = VolumeBootRecord.Get(volume) as FatVolumeBootRecord;

            byte[] fatBytes = GetBytes(volume, vbr);

            switch (vbr.FatType)
            {
            case "FAT12":
                return(parseFat12(fatBytes, startSector));

            case "FAT16":
                return(parseFat16(fatBytes, startSector));

            case "FAT32":
                return(parseFat32(fatBytes, startSector));

            default:
                throw new Exception("FAT Type could not be determined.");
            }
        }
예제 #8
0
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        public byte[] GetContent()
        {
            FatVolumeBootRecord vbr = VolumeBootRecord.Get(this.Volume) as FatVolumeBootRecord;

            int RootDirSectors = ((vbr.BPB_RootEntryCount * 32) + (vbr.BytesPerSector - 1)) / vbr.BytesPerSector;

            uint FatSize = 0;

            if (vbr.BPB_FatSize16 != 0)
            {
                FatSize = vbr.BPB_FatSize16;
            }
            else
            {
                FatSize = vbr.BPB_FatSize32;
            }

            uint FirstDataSector = (uint)(vbr.ReservedSectors + (vbr.BPB_NumberOfFATs * FatSize) + RootDirSectors);

            uint FirstSectorofCluster = ((this.FirstCluster - 2) * vbr.SectorsPerCluster) + FirstDataSector;

            byte[] bytes = DD.Get(this.Volume, (long)FirstSectorofCluster * (long)vbr.BytesPerSector, vbr.BytesPerSector, 1);

            if (this.Directory)
            {
                return(bytes);
            }
            else
            {
                if (this.FileSize <= bytes.Length)
                {
                    return(Helper.GetSubArray(bytes, 0, this.FileSize));
                }
                else
                {
                    // Need to do more...
                    return(bytes);
                }
            }
        }
예제 #9
0
        public static ShellLink[] GetInstances(string volume)
        {
            VolumeBootRecord VBR = VolumeBootRecord.Get(volume);

            List <ShellLink> slList = new List <ShellLink>();

            foreach (FileRecord r in FileRecord.GetInstances(volume))
            {
                try
                {
                    if (r.Name.Contains(".lnk"))
                    {
                        slList.Add(new ShellLink(r.GetContent(VBR), r));
                    }
                }
                catch
                {
                }
            }

            return(slList.ToArray());
        }
예제 #10
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public static UsnJrnl[] GetTestInstances(string path)
        {
            byte[] bytes = FileRecord.GetContentBytes(path, "$J");

            string volume = Helper.GetVolumeFromPath(path);

            VolumeBootRecord VBR = VolumeBootRecord.Get(volume);

            List <UsnJrnl> usnList = new List <UsnJrnl>();

            for (int i = 0; i < bytes.Length; i += VBR.BytesPerCluster)
            {
                int clusteroffset = i;

                do
                {
                    // Break if there are no more UsnJrnl entries in cluster
                    if (bytes[clusteroffset] == 0)
                    {
                        break;
                    }

                    try
                    {
                        UsnJrnl usn = new UsnJrnl(bytes, volume, ref clusteroffset);
                        if (usn.Version > USN40Version)
                        {
                            break;
                        }
                        usnList.Add(usn);
                    }
                    catch
                    {
                        break;
                    }
                } while (clusteroffset >= 0 && clusteroffset < bytes.Length);
            }
            return(usnList.ToArray());
        }
예제 #11
0
        public bool Identify(IMediaImage imagePlugin, Partition partition)
        {
            if (12 + partition.Start >= partition.End)
            {
                return(false);
            }

            byte[] vbrSector = imagePlugin.ReadSector(0 + partition.Start);
            if (vbrSector.Length < 512)
            {
                return(false);
            }

            IntPtr vbrPtr = Marshal.AllocHGlobal(512);

            Marshal.Copy(vbrSector, 0, vbrPtr, 512);
            VolumeBootRecord vbr = (VolumeBootRecord)Marshal.PtrToStructure(vbrPtr, typeof(VolumeBootRecord));

            Marshal.FreeHGlobal(vbrPtr);

            return(signature.SequenceEqual(vbr.signature));
        }
예제 #12
0
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        public byte[] GetContent()
        {
            FatVolumeBootRecord vbr = VolumeBootRecord.Get(this.Volume) as FatVolumeBootRecord;

            int RootDirSectors = ((vbr.BPB_RootEntryCount * 32) + (vbr.BytesPerSector - 1)) / vbr.BytesPerSector;

            uint FirstDataSector = (uint)(vbr.ReservedSectors + (vbr.BPB_NumberOfFATs * vbr.BPB_FatSize) + RootDirSectors);

            uint FirstSectorofCluster = ((this.FirstCluster - 2) * vbr.SectorsPerCluster) + FirstDataSector;

            byte[] bytes = DD.Get(this.Volume, (long)FirstSectorofCluster * (long)vbr.BytesPerSector, vbr.BytesPerSector, 1);

            if (this.Directory)
            {
                return(bytes);
            }
            else
            {
                if (this.FileSize <= bytes.Length)
                {
                    return(Helper.GetSubArray(bytes, 0, this.FileSize));
                }
                else
                {
                    List <byte> byteList = new List <byte>();

                    int[] clusters = FileAllocationTable.GetFatEntry(this.Volume, (int)this.FirstCluster);

                    foreach (int cluster in clusters)
                    {
                        long targetCluster = ((cluster - 2) * vbr.SectorsPerCluster) + FirstDataSector;
                        byteList.AddRange(DD.Get(this.Volume, targetCluster * vbr.BytesPerSector, vbr.BytesPerSector, 1));
                    }

                    return(Helper.GetSubArray(byteList.ToArray(), 0, this.FileSize));
                }
            }
        }
        protected override void ProcessRecord()
        {
            // Check for valid Volume name
            NativeMethods.getVolumeName(ref volume);

            // Set up FileStream to read volume
            IntPtr     hVolume      = NativeMethods.getHandle(volume);
            FileStream streamToRead = NativeMethods.getFileStream(hVolume);

            // Get VolumeBootRecord object for logical addressing
            VolumeBootRecord VBR = VolumeBootRecord.Get(streamToRead);

            // Get the $Max Data attribute (contains UsnJrnl details)
            Data Max = UsnJrnl.GetMaxStream(UsnJrnl.GetFileRecord(volume));

            if (asBytes)
            {
                WriteObject(Max.RawData);
            }
            else
            {
                WriteObject(new UsnJrnlDetail(Max.RawData));
            }
        } // ProcessRecord
        /// <summary>
        ///
        /// </summary>
        /// <param name="volume"></param>
        /// <returns></returns>
        public static FileSystemInformation Get(string volume)
        {
            FatVolumeBootRecord vbr = VolumeBootRecord.Get(volume) as FatVolumeBootRecord;

            return(new FileSystemInformation(DD.Get(volume, (vbr.BytesPerSector * vbr.BPB_FileSytemInfo), vbr.BytesPerSector, 1)));
        }
예제 #15
0
 internal static byte[] GetBytes(string volume, VolumeBootRecord vbr)
 {
     long DirectoryEntryOffset = vbr.ReservedSectors * vbr.BytesPerSector;
     return Helper.readDrive(volume, DirectoryEntryOffset, (vbr.SectorsPerFat * vbr.BytesPerSector));
 }
예제 #16
0
        private static UsnJrnl Get(string volume, int recordnumber, long usn)
        {
            // Check for valid Volume name
            Helper.getVolumeName(ref volume);

            // Set up FileStream to read volume
            FileStream streamToRead = Helper.getFileStream(volume);

            // Get VolumeBootRecord object for logical addressing
            VolumeBootRecord VBR = VolumeBootRecord.Get(streamToRead);

            FileRecord record = FileRecord.Get(volume, recordnumber, true);

            // Get the $J Data attribute (contains UsnJrnl details
            NonResident J = UsnJrnl.GetJStream(record);

            // Determine the length of the initial sparse pages
            long SparseLength = J.DataRun[0].ClusterLength * VBR.BytesPerCluster;

            if (usn > SparseLength)
            {
                // Subtract length of sparse data from desired usn offset
                long usnOffset = usn - SparseLength;

                // Iterate through each data run
                for (int i = 1; i < J.DataRun.Length; i++)
                {
                    // Determine length of current DataRun
                    long dataRunLength = J.DataRun[i].ClusterLength * VBR.BytesPerCluster;

                    // Check if usnOffset resides in current DataRun
                    if (dataRunLength <= usnOffset)
                    {
                        // If not, subtract length of DataRun from usnOffset
                        usnOffset -= dataRunLength;
                    }

                    // If usnOffset resides within DataRun, parse associated UsnJrnl Entry
                    else
                    {
                        // Read DataRun from disk
                        byte[] fragmentBytes = Helper.readDrive(streamToRead, (J.DataRun[i].StartCluster * VBR.BytesPerCluster), (J.DataRun[i].ClusterLength * VBR.BytesPerCluster));

                        // Instatiate a byte array that is the size of a single cluster
                        byte[] clusterBytes = new byte[VBR.BytesPerCluster];

                        // Iterate through the clusters in the DataRun
                        for (int j = 0; j < J.DataRun[i].ClusterLength; j++)
                        {
                            // If usnOffset is not in current cluster, then subtract cluster size from offset and iterate
                            if (VBR.BytesPerCluster <= usnOffset)
                            {
                                usnOffset -= VBR.BytesPerCluster;
                            }
                            // Else if usnOffset is in current cluster
                            else
                            {
                                // Copy current cluster bytes to clusterBytes variable
                                Array.Copy(fragmentBytes, (int)(j * VBR.BytesPerCluster), clusterBytes, 0, clusterBytes.Length);

                                // Parse desired UsnJrnl entry from cluster
                                int offset = (int)usnOffset;
                                return(new UsnJrnl(clusterBytes, volume, ref offset));
                            }
                        }
                    }
                }
                return(null);
            }
            else
            {
                throw new Exception("UsnJrnl entry has has been overwritten");
            }
        }
예제 #17
0
        public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
                                   Encoding encoding)
        {
            Encoding    = encoding ?? Encoding.GetEncoding("iso-8859-15");
            information = "";

            StringBuilder sb = new StringBuilder();

            XmlFsType = new FileSystemType();

            byte[] vbrSector = imagePlugin.ReadSector(0 + partition.Start);
            IntPtr vbrPtr    = Marshal.AllocHGlobal(512);

            Marshal.Copy(vbrSector, 0, vbrPtr, 512);
            VolumeBootRecord vbr = (VolumeBootRecord)Marshal.PtrToStructure(vbrPtr, typeof(VolumeBootRecord));

            Marshal.FreeHGlobal(vbrPtr);

            byte[] parametersSector = imagePlugin.ReadSector(9 + partition.Start);
            IntPtr parametersPtr    = Marshal.AllocHGlobal(512);

            Marshal.Copy(parametersSector, 0, parametersPtr, 512);
            OemParameterTable parametersTable =
                (OemParameterTable)Marshal.PtrToStructure(parametersPtr, typeof(OemParameterTable));

            Marshal.FreeHGlobal(parametersPtr);

            byte[] chkSector = imagePlugin.ReadSector(11 + partition.Start);
            IntPtr chkPtr    = Marshal.AllocHGlobal(512);

            Marshal.Copy(chkSector, 0, chkPtr, 512);
            ChecksumSector chksector = (ChecksumSector)Marshal.PtrToStructure(chkPtr, typeof(ChecksumSector));

            Marshal.FreeHGlobal(chkPtr);

            sb.AppendLine("Microsoft exFAT");
            sb.AppendFormat("Partition offset: {0}", vbr.offset).AppendLine();
            sb.AppendFormat("Volume has {0} sectors of {1} bytes each for a total of {2} bytes", vbr.sectors,
                            1 << vbr.sectorShift, vbr.sectors * (ulong)(1 << vbr.sectorShift)).AppendLine();
            sb.AppendFormat("Volume uses clusters of {0} sectors ({1} bytes) each", 1 << vbr.clusterShift,
                            (1 << vbr.sectorShift) * (1 << vbr.clusterShift)).AppendLine();
            sb.AppendFormat("First FAT starts at sector {0} and runs for {1} sectors", vbr.fatOffset, vbr.fatLength)
            .AppendLine();
            sb.AppendFormat("Volume uses {0} FATs", vbr.fats).AppendLine();
            sb.AppendFormat("Cluster heap starts at sector {0}, contains {1} clusters and is {2}% used",
                            vbr.clusterHeapOffset, vbr.clusterHeapLength, vbr.heapUsage).AppendLine();
            sb.AppendFormat("Root directory starts at cluster {0}", vbr.rootDirectoryCluster).AppendLine();
            sb.AppendFormat("Filesystem revision is {0}.{1:D2}", (vbr.revision & 0xFF00) >> 8, vbr.revision & 0xFF)
            .AppendLine();
            sb.AppendFormat("Volume serial number: {0:X8}", vbr.volumeSerial).AppendLine();
            sb.AppendFormat("BIOS drive is {0:X2}h", vbr.drive).AppendLine();
            if (vbr.flags.HasFlag(VolumeFlags.SecondFatActive))
            {
                sb.AppendLine("2nd FAT is in use");
            }
            if (vbr.flags.HasFlag(VolumeFlags.VolumeDirty))
            {
                sb.AppendLine("Volume is dirty");
            }
            if (vbr.flags.HasFlag(VolumeFlags.MediaFailure))
            {
                sb.AppendLine("Underlying media presented errors");
            }

            int count = 1;

            foreach (OemParameter parameter in parametersTable.parameters)
            {
                if (parameter.OemParameterType == OEM_FLASH_PARAMETER_GUID)
                {
                    sb.AppendFormat("OEM Parameters {0}:", count).AppendLine();
                    sb.AppendFormat("\t{0} bytes in erase block", parameter.eraseBlockSize).AppendLine();
                    sb.AppendFormat("\t{0} bytes per page", parameter.pageSize).AppendLine();
                    sb.AppendFormat("\t{0} spare blocks", parameter.spareBlocks).AppendLine();
                    sb.AppendFormat("\t{0} nanoseconds random access time", parameter.randomAccessTime).AppendLine();
                    sb.AppendFormat("\t{0} nanoseconds program time", parameter.programTime).AppendLine();
                    sb.AppendFormat("\t{0} nanoseconds read cycle time", parameter.readCycleTime).AppendLine();
                    sb.AppendFormat("\t{0} nanoseconds write cycle time", parameter.writeCycleTime).AppendLine();
                }
                else if (parameter.OemParameterType != Guid.Empty)
                {
                    sb.AppendFormat("Found unknown parameter type {0}", parameter.OemParameterType).AppendLine();
                }

                count++;
            }

            sb.AppendFormat("Checksum 0x{0:X8}", chksector.checksum[0]).AppendLine();

            XmlFsType.ClusterSize  = (1 << vbr.sectorShift) * (1 << vbr.clusterShift);
            XmlFsType.Clusters     = vbr.clusterHeapLength;
            XmlFsType.Dirty        = vbr.flags.HasFlag(VolumeFlags.VolumeDirty);
            XmlFsType.Type         = "exFAT";
            XmlFsType.VolumeSerial = $"{vbr.volumeSerial:X8}";

            information = sb.ToString();
        }
예제 #18
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="volume"></param>
 /// <returns></returns>
 public static byte[] GetBytes(string volume)
 {
     return(GetBytes(volume, VolumeBootRecord.Get(volume) as FatVolumeBootRecord));
 }