示例#1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public static FileRecord[] GetInstancesByPath(string path)
        {
            FileRecord record = FileRecord.Get(path, true);

            byte[] mftBytes = record.GetContent();
            return(GetInstances(mftBytes, Helper.GetVolumeFromPath(path), false));
        }
示例#2
0
        public static FileRecord[] GetInstancesTest(string volume)
        {
            FileRecord record = FileRecord.Get(volume, MftIndex.MFT_INDEX, true);

            byte[] mftBytes = record.GetContent();
            return(GetInstancesTest(mftBytes, volume));
        }
示例#3
0
        public static byte[] GetSlackByPath(string path)
        {
            FileRecord record = FileRecord.Get(path, true);

            byte[] bytes = record.GetContent();
            return(GetSlack(bytes));
        }
示例#4
0
        internal static FileRecord[] GetInstances(string volume, bool fast)
        {
            FileRecord record = FileRecord.Get(volume, MftIndex.MFT_INDEX, true);

            byte[] mftBytes = record.GetContent();
            return(GetInstances(mftBytes, volume, fast));
        }
示例#5
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="volume"></param>
        /// <returns></returns>
        public static AttrDef[] GetInstances(string volume)
        {
            Helper.getVolumeName(ref volume);
            FileRecord record = FileRecord.Get(volume, MftIndex.ATTRDEF_INDEX, true);

            return(AttrDef.GetInstances(record.GetContent()));
        }
示例#6
0
        private static Bitmap Get(string volume, int recordNumber, ulong cluster)
        {
            ulong sectorOffset = cluster / 4096;

            // 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);

            // Get the Data attribute
            NonResident dataStream = Bitmap.GetDataStream(FileRecord.Get(volume, recordNumber, true));

            // Calulate the offset of the Bitmap file's data
            ulong dataRunOffset = (ulong)dataStream.DataRun[0].StartCluster * VBR.BytesPerCluster;

            // Calculate the offset of the sector that contains the entry for the specific cluster
            ulong offset = dataRunOffset + (VBR.BytesPerSector * sectorOffset);

            // Read appropriate sector
            byte[] bytes = Helper.readDrive(streamToRead, offset, VBR.BytesPerSector);

            return(Get(bytes, cluster));
        }
示例#7
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="volume"></param>
        /// <returns></returns>
        public static Bitmap[] GetInstances(string volume)
        {
            // Get the proper data stream from the FileRecord
            NonResident dataStream = Bitmap.GetDataStream(FileRecord.Get(volume, MftIndex.BITMAP_INDEX, true));

            // Call GetInstances to return all associated Bitmap Values
            return(GetInstances(dataStream.GetBytes()));
        }
示例#8
0
        private static UsnJrnl[] GetInstances(string volume, int recordnumber)
        {
            // Get VolumeBootRecord object for logical addressing
            VolumeBootRecord VBR = VolumeBootRecord.Get(volume);

            // Get FileRecord for C:\$Extend\$UsnJrnl
            FileRecord record = FileRecord.Get(volume, recordnumber, true);

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

            // Instatiate a List of UsnJrnl entries
            List <UsnJrnl> usnList = new List <UsnJrnl>();

            for (int i = 0; i < J.DataRun.Length; i++)
            {
                if (!(J.DataRun[i].Sparse))
                {
                    long clusterCount = J.DataRun[i].ClusterLength;

                    byte[] fragmentBytes = Helper.readDrive(volume, (J.DataRun[i].StartCluster * VBR.BytesPerCluster), (clusterCount * VBR.BytesPerCluster));

                    byte[] clusterBytes = new byte[VBR.BytesPerCluster];

                    for (int j = 0; j < clusterCount; j++)
                    {
                        Array.Copy(fragmentBytes, (int)(j * VBR.BytesPerCluster), clusterBytes, 0, clusterBytes.Length);

                        int offset = 0;

                        do
                        {
                            if (clusterBytes[offset] == 0)
                            {
                                break;
                            }

                            try
                            {
                                UsnJrnl usn = new UsnJrnl(clusterBytes, volume, ref offset);
                                if (usn.Version > USN40Version)
                                {
                                    break;
                                }
                                usnList.Add(usn);
                            }
                            catch
                            {
                                break;
                            }
                        } while (offset >= 0 && offset < clusterBytes.Length);
                    }
                }
            }

            // Return usnList as a UsnJrnl[]
            return(usnList.ToArray());
        }
示例#9
0
        public FileRecord GetParentFileRecord()
        {
            FileRecord record = FileRecord.Get(this.VolumePath, (int)this.ParentFileRecordNumber, false);

            if (record.SequenceNumber == this.ParentFileSequenceNumber)
            {
                return(record);
            }
            else
            {
                throw new Exception("Desired FileRecord has been overwritten");
            }
        }
示例#10
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public static Bitmap[] GetInstancesByPath(string path)
        {
            // Get Volume string from specified path
            string volume = Helper.GetVolumeFromPath(path);

            // Determine Record Number for specified file
            IndexEntry entry = IndexEntry.Get(path);

            // Get the proper data stream from the FileRecord
            NonResident dataStream = Bitmap.GetDataStream(FileRecord.Get(volume, MftIndex.BITMAP_INDEX, true));

            // Call GetInstances to return all associated Bitmap Values
            return(GetInstances(dataStream.GetBytes()));
        }
示例#11
0
        internal static FileRecord GetRecord(FileStream streamToRead, string volume)
        {
            // Instantiate VolumeBootRecord object
            VolumeBootRecord VBR = VolumeBootRecord.Get(streamToRead);

            // 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));
        }
示例#12
0
        internal static NonResident GetJStream(FileRecord fileRecord)
        {
            foreach (FileRecordAttribute attr in fileRecord.Attribute)
            {
                if (attr.NameString == "$J")
                {
                    return(attr as NonResident);
                }

                AttributeList attrList = attr as AttributeList;
                if (attrList != null)
                {
                    foreach (AttrRef ar in attrList.AttributeReference)
                    {
                        if (ar.NameString == "$J")
                        {
                            FileRecord record = FileRecord.Get(fileRecord.VolumePath, (int)ar.RecordNumber, true);
                            return(GetJStream(record));
                        }
                    }
                }
            }
            throw new Exception("No $J attribute found.");
        }
示例#13
0
 public static VolumeInformation Get(string volume)
 {
     Helper.getVolumeName(ref volume);
     return(Get(FileRecord.Get(volume, MftIndex.VOLUME_INDEX, true)));
 }
 public FileRecord GetParent()
 {
     return(FileRecord.Get(this.VolumePath, (int)this.ParentRecordNumber, false));
 }
示例#15
0
        public static byte[] GetBytes(string path)
        {
            FileRecord record = FileRecord.Get(path, true);

            return(GetMaxStream(record).RawData);
        }
示例#16
0
        public static UsnJrnlDetail Get(string path)
        {
            FileRecord record = FileRecord.Get(path, true);

            return(new UsnJrnlDetail(GetMaxStream(record).RawData));
        }
示例#17
0
        private static UsnJrnl[] GetInstances(string volume, int recordnumber)
        {
            // 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);

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

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

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

            for (int i = 0; i < J.DataRun.Length; i++)
            {
                if (!(J.DataRun[i].Sparse))
                {
                    long clusterCount = J.DataRun[i].ClusterLength;

                    byte[] fragmentBytes = NativeMethods.readDrive(streamToRead, ((ulong)J.DataRun[i].StartCluster * VBR.BytesPerCluster), ((ulong)clusterCount * VBR.BytesPerCluster));

                    byte[] clusterBytes = new byte[VBR.BytesPerCluster];

                    for (long j = 0; j < clusterCount; j++)
                    {
                        Array.Copy(fragmentBytes, ((long)j * VBR.BytesPerCluster), clusterBytes, 0, clusterBytes.Length);

                        int offset = 0;

                        do
                        {
                            if (clusterBytes[offset] == 0)
                            {
                                break;
                            }

                            try
                            {
                                UsnJrnl usn = new UsnJrnl(clusterBytes, volume, ref offset);
                                if (usn.Version > USN40Version)
                                {
                                    break;
                                }
                                usnList.Add(usn);
                            }
                            catch
                            {
                                break;
                            }
                        } while (offset >= 0 && offset < clusterBytes.Length);
                    }
                }
            }
            return(usnList.ToArray());
        }
示例#18
0
        private static UsnJrnl Get(string volume, int recordnumber, ulong usn)
        {
            // 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);

            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
            ulong SparseLength = (ulong)J.DataRun[0].ClusterLength * VBR.BytesPerCluster;

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

                // Iterate through each data run
                for (int i = 1; i < J.DataRun.Length; i++)
                {
                    // Determine length of current DataRun
                    ulong dataRunLength = (ulong)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 = NativeMethods.readDrive(streamToRead, ((ulong)J.DataRun[i].StartCluster * VBR.BytesPerCluster), ((ulong)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 (long 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, ((long)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");
            }
        }
示例#19
0
        public static VolumeInformation Get(string volume)
        {
            FileRecord record = FileRecord.Get(volume, MftIndex.VOLUME_INDEX, true);

            return(Get(record));
        }
示例#20
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public static UsnJrnlInformation GetByPath(string path)
        {
            FileRecord record = FileRecord.Get(path, true);

            return(new UsnJrnlInformation(record.GetContent(@"$Max")));
        }
        public static byte[] GetBytesByPath(string path)
        {
            FileRecord record = FileRecord.Get(path, true);

            return(record.GetContent());
        }
示例#22
0
        internal static IndexEntry Get(string path)
        {
            string[] paths = path.TrimEnd('\\').Split('\\');

            // Determine Volume Name
            string volume = Util.GetVolumeFromPath(path);

            // Test volume path
            Util.getVolumeName(ref volume);

            int index = -1;

            List <IndexEntry> indexEntryList = new List <IndexEntry>();

            for (int i = 0; i < paths.Length; i++)
            {
                if (index == -1)
                {
                    index = 5;
                }
                else
                {
                    bool match = false;

                    foreach (IndexEntry entry in indexEntryList)
                    {
                        if (entry.Entry.Filename.ToUpper() == paths[i].ToUpper())
                        {
                            index = (int)entry.RecordNumber;
                            match = true;
                        }
                    }
                    if (!(match))
                    {
                        throw new Exception("Path " + path + " not found.");
                    }
                }

                FileRecord record = FileRecord.Get(volume, index, false);

                indexEntryList.Clear();

                if (i < paths.Length - 1)
                {
                    foreach (Attr attr in record.Attribute)
                    {
                        if (attr.Name == Attr.ATTR_TYPE.INDEX_ROOT)
                        {
                            foreach (IndexEntry entry in (attr as IndexRoot).Entries)
                            {
                                if (entry.Entry.Namespace != 0x02)
                                {
                                    indexEntryList.Add(entry);
                                }
                            }
                        }
                        else if (attr.Name == Attr.ATTR_TYPE.INDEX_ALLOCATION)
                        {
                            // Get INDEX_ALLOCATION bytes
                            IndexAllocation IA = new IndexAllocation(attr as NonResident, volume);

                            foreach (IndexEntry entry in IA.Entries)
                            {
                                if (entry.Entry.Namespace != 0x02)
                                {
                                    indexEntryList.Add(entry);
                                }
                            }
                        }
                    }
                }
                else
                {
                    return(new IndexEntry(record));
                }
            }
            throw new Exception("The IndexEntry object for the specified path could not be found.");
        }
        public static AttrDef[] GetInstances(string volume)
        {
            FileRecord record = FileRecord.Get(volume, ATTRDEF_INDEX, true);

            return(AttrDef.GetInstances(record.GetBytes()));
        }
示例#24
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="volume"></param>
 /// <returns></returns>
 internal static FileRecord GetFileRecord(string volume)
 {
     Helper.getVolumeName(ref volume);
     return(FileRecord.Get(volume, MftIndex.BADCLUS_INDEX, true));
 }
示例#25
0
        private FileRecord(byte[] recordBytes, string volume, int bytesPerFileRecord, bool fast)
        {
            if (Encoding.ASCII.GetString(recordBytes, 0x00, 0x04) == "FILE")
            {
                VolumePath            = volume;
                OffsetOfUS            = BitConverter.ToUInt16(recordBytes, 0x04);
                SizeOfUS              = BitConverter.ToUInt16(recordBytes, 0x06);
                LogFileSequenceNumber = BitConverter.ToUInt64(recordBytes, 0x08);
                SequenceNumber        = BitConverter.ToUInt16(recordBytes, 0x10);
                Hardlinks             = BitConverter.ToUInt16(recordBytes, 0x12);
                OffsetOfAttribute     = BitConverter.ToUInt16(recordBytes, 0x14);
                Flags           = (FILE_RECORD_FLAG)BitConverter.ToUInt16(recordBytes, 0x16);
                Deleted         = isDeleted(Flags);
                Directory       = isDirectory(Flags);
                RealSize        = BitConverter.ToInt32(recordBytes, 0x18);
                AllocatedSize   = BitConverter.ToInt32(recordBytes, 0x1C);
                ReferenceToBase = BitConverter.ToUInt64(recordBytes, 0x20);
                NextAttrId      = BitConverter.ToUInt16(recordBytes, 40);
                RecordNumber    = BitConverter.ToUInt32(recordBytes, 44);
                Attribute       = FileRecordAttribute.GetInstances(recordBytes, OffsetOfAttribute, bytesPerFileRecord, volume);

                #region AttributeProperties

                foreach (FileRecordAttribute attr in Attribute)
                {
                    if (attr.Name == FileRecordAttribute.ATTR_TYPE.STANDARD_INFORMATION)
                    {
                        StandardInformation stdInfo = attr as StandardInformation;
                        ModifiedTime = stdInfo.ModifiedTime;
                        AccessedTime = stdInfo.AccessedTime;
                        ChangedTime  = stdInfo.ChangedTime;
                        BornTime     = stdInfo.BornTime;
                        Permission   = stdInfo.Permission;
                    }
                    else if (attr.Name == FileRecordAttribute.ATTR_TYPE.ATTRIBUTE_LIST)
                    {
                        if (!(Deleted))
                        {
                            AttributeList attrList          = null;
                            List <FileRecordAttribute> list = new List <FileRecordAttribute>();
                            list.AddRange(Attribute);

                            if (attr.NonResident)
                            {
                                attrList = new AttributeList(attr as NonResident);
                            }
                            else
                            {
                                attrList = attr as AttributeList;
                            }

                            foreach (AttrRef attribute in attrList.AttributeReference)
                            {
                                if (attribute.RecordNumber != RecordNumber)
                                {
                                    FileRecord record = FileRecord.Get(volume, (int)attribute.RecordNumber);
                                    list.AddRange(record.Attribute);
                                    list.Remove(attr);
                                }
                            }

                            Attribute = list.ToArray();
                        }
                    }
                    else if (attr.Name == FileRecordAttribute.ATTR_TYPE.FILE_NAME)
                    {
                        FileName fN = attr as FileName;
                        if (!(fN.Namespace == 2))
                        {
                            Name = fN.Filename;
                            ParentSequenceNumber = fN.ParentSequenceNumber;
                            ParentRecordNumber   = fN.ParentRecordNumber;
                            FNModifiedTime       = fN.ModifiedTime;
                            FNAccessedTime       = fN.AccessedTime;
                            FNChangedTime        = fN.ChangedTime;
                            FNBornTime           = fN.BornTime;
                        }
                    }
                }

                #endregion AttributeProperties

                #region FullName

                if (fast)
                {
                    FullName = Name;
                }
                else
                {
                    StringBuilder sb        = new StringBuilder();
                    string        volLetter = Helper.GetVolumeLetter(volume);

                    if (RecordNumber == 0)
                    {
                        sb.Append(volLetter);
                        sb.Append('\\');
                        sb.Append(Name);
                        FullName = sb.ToString();
                    }
                    else if (RecordNumber == 5)
                    {
                        FullName = volLetter;
                    }
                    else
                    {
                        FileRecord parent = new FileRecord(GetRecordBytes(volume, (int)ParentRecordNumber), volume, bytesPerFileRecord, false);
                        if (parent.SequenceNumber == this.ParentSequenceNumber)
                        {
                            sb.Append(parent.FullName);
                        }
                        else
                        {
                            sb.Append(@"$OrphanFiles");
                        }

                        if (Name != null)
                        {
                            sb.Append('\\');
                            FullName = sb.Append(Name).ToString();
                        }
                        else
                        {
                            FullName = sb.ToString();
                        }
                    }
                }

                #endregion FullName
            }
        }
示例#26
0
        public static VolumeInformation GetByPath(string path)
        {
            FileRecord record = FileRecord.Get(path, true);

            return(Get(record));
        }
示例#27
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public static AttrDef[] GetInstancesByPath(string path)
        {
            FileRecord record = FileRecord.Get(path, true);

            return(AttrDef.GetInstances(record.GetContent()));
        }
示例#28
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="volume"></param>
 /// <returns></returns>
 internal static FileRecord GetFileRecord(string volume)
 {
     return(FileRecord.Get(volume, MftIndex.LOGFILE_INDEX, true));
 }
示例#29
0
 public static VolumeInformation GetByPath(string path)
 {
     return(Get(FileRecord.Get(path, true)));
 }
示例#30
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public static IndexEntry[] GetInstances(string path)
        {
            string[] paths = path.TrimEnd('\\').Split('\\');

            // Determine Volume Name
            string volume = Helper.GetVolumeFromPath(path);

            // Test volume path
            Helper.getVolumeName(ref volume);

            int index = -1;

            List <IndexEntry> indexEntryList = new List <IndexEntry>();

            for (int i = 0; i < paths.Length; i++)
            {
                if (index == -1)
                {
                    index = 5;
                }
                else
                {
                    bool match = false;

                    foreach (IndexEntry entry in indexEntryList)
                    {
                        if (entry.Entry.Filename.ToUpper() == paths[i].ToUpper())
                        {
                            index = (int)entry.RecordNumber;
                            match = true;
                        }
                    }
                    if (!(match))
                    {
                        throw new Exception("Path " + path + " not found.");
                    }
                }

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

                indexEntryList.Clear();

                if (record.Directory)
                {
                    foreach (FileRecordAttribute attr in record.Attribute)
                    {
                        if (attr.Name == FileRecordAttribute.ATTR_TYPE.INDEX_ROOT)
                        {
                            try
                            {
                                foreach (IndexEntry entry in (attr as IndexRoot).Entries)
                                {
                                    if (entry.Entry.Namespace != 0x02)
                                    {
                                        StringBuilder sb = new StringBuilder();
                                        sb.Append(path.TrimEnd('\\'));
                                        sb.Append("\\");
                                        sb.Append(entry.Filename);
                                        entry.FullName = sb.ToString();
                                        indexEntryList.Add(entry);
                                    }
                                }
                            }
                            catch
                            {
                                return(null);
                            }
                        }
                        else if (attr.Name == FileRecordAttribute.ATTR_TYPE.INDEX_ALLOCATION)
                        {
                            // Get INDEX_ALLOCATION bytes
                            IndexAllocation IA = new IndexAllocation(attr as NonResident, volume);

                            foreach (IndexEntry entry in IA.Entries)
                            {
                                if (entry.Entry.Namespace != 0x02)
                                {
                                    StringBuilder sb = new StringBuilder();
                                    sb.Append(path.TrimEnd('\\'));
                                    sb.Append("\\");
                                    sb.Append(entry.Filename);
                                    entry.FullName = sb.ToString();
                                    indexEntryList.Add(entry);
                                }
                            }
                        }
                    }
                }
                else
                {
                    IndexEntry[] indexArray = new IndexEntry[1];
                    indexArray[0] = new IndexEntry(record);
                    return(indexArray);
                }
            }

            return(indexEntryList.ToArray());
        }