private static VolumeInformation Get(FileRecord fileRecord)
 {
     foreach (Attr attr in fileRecord.Attribute)
     {
         if (attr.Name == Attr.ATTR_TYPE.VOLUME_INFORMATION)
         {
             return attr as VolumeInformation;
         }
     }
     throw new Exception("No VOLUME_INFORMATION attribute found.");
 }
Пример #2
0
 internal static NonResident GetDataAttr(FileRecord fileRecord)
 {
     foreach (FileRecordAttribute attr in fileRecord.Attribute)
     {
         if (attr.Name == FileRecordAttribute.ATTR_TYPE.DATA)
         {
             return attr as NonResident;
         }
     }
     throw new Exception("No DATA attribute found.");
 }
Пример #3
0
 private static VolumeName Get(FileRecord fileRecord)
 {
     foreach (Attr attr in fileRecord.Attribute)
     {
         if (attr.Name == Attr.ATTR_TYPE.VOLUME_NAME)
         {
             return attr as VolumeName;
         }
     }
     throw new Exception("No VOLUME_NAME attribute found.");
 }
Пример #4
0
 internal static NonResident GetBadStream(FileRecord fileRecord)
 {
     foreach (Attr attr in fileRecord.Attribute)
     {
         if (attr.NameString == "$Bad")
         {
             return attr as NonResident;
         }
     }
     throw new Exception("No $Bad attribute found.");
 }
Пример #5
0
 private static VolumeInformation Get(FileRecord record)
 {
     foreach (FileRecordAttribute attr in record.Attribute)
     {
         VolumeInformation volInfo = attr as VolumeInformation;
         if(volInfo != null)
         {
             return volInfo;
         }
     }
     throw new Exception("No VOLUME_INFORMATION attribute found.");
 }
Пример #6
0
 private static VolumeName Get(FileRecord fileRecord)
 {
     foreach (FileRecordAttribute attr in fileRecord.Attribute)
     {
         VolumeName volName = attr as VolumeName;
         if(volName != null)
         {
             return volName;
         }
     }
     throw new Exception("No VOLUME_NAME attribute found.");
 }
Пример #7
0
        public static Mactime[] Get(FileRecord record)
        {
            #region DetermineTime

            Dictionary<DateTime, ACTIVITY_TYPE> dictionary = new Dictionary<DateTime, ACTIVITY_TYPE>();

            // Modified Time
            dictionary[record.ModifiedTime] = ACTIVITY_TYPE.m;

            // Access Time
            if (dictionary.ContainsKey(record.AccessedTime))
            {
                dictionary[record.AccessedTime] = dictionary[record.AccessedTime] | ACTIVITY_TYPE.a;
            }
            else
            {
                dictionary.Add(record.AccessedTime, ACTIVITY_TYPE.a);
            }

            // MFT Changed Time
            if (dictionary.ContainsKey(record.ChangedTime))
            {
                dictionary[record.ChangedTime] = dictionary[record.ChangedTime] | ACTIVITY_TYPE.c;
            }
            else
            {
                dictionary.Add(record.ChangedTime, ACTIVITY_TYPE.c);
            }

            // Born Time
            if (dictionary.ContainsKey(record.BornTime))
            {
                dictionary[record.BornTime] = dictionary[record.BornTime] | ACTIVITY_TYPE.b;
            }
            else
            {
                dictionary.Add(record.BornTime, ACTIVITY_TYPE.b);
            }

            #endregion DetermineTime

            List<Mactime> macs = new List<Mactime>();

            foreach (var time in dictionary)
            {
                //macs.Add(new Mactime(time.Key, record.Size, (ushort)time.Value, record.RecordNumber, record.FullPath, record.Deleted));
                macs.Add(new Mactime(time.Key, record.RealSize, (ushort)time.Value, record.RecordNumber, record.Name, record.Deleted));
            }

            return macs.ToArray();
        }
        private static AlternateDataStream[] GetInstances(FileRecord record)
        {
            List<AlternateDataStream> adsList = new List<AlternateDataStream>();

            if (record.Attribute != null)
            {
                foreach (FileRecordAttribute attr in record.Attribute)
                {
                    if (attr.Name == FileRecordAttribute.ATTR_TYPE.DATA)
                    {
                        if (attr.NameString.Length > 0)
                        {
                            adsList.Add(new AlternateDataStream(record.FullName, record.Name, attr.NameString));
                        }
                    }
                }
            }

            return adsList.ToArray();
        }
Пример #9
0
        internal static byte[] GetBytes(FileStream streamToRead, string volume)
        {
            FileRecord mftRecord = GetRecord(streamToRead, volume);

            return(mftRecord.GetContent());
        }
Пример #10
0
 public static ForensicTimeline[] GetInstances(FileRecord[] input)
 {
     List<ForensicTimeline> list = new List<ForensicTimeline>();
     foreach (FileRecord r in input)
     {
         foreach (ForensicTimeline t in Get(r))
         {
             list.Add(t);
         }
     }
     return list.ToArray();
 }
Пример #11
0
        public static VolumeInformation GetVolumeInformation(string volume)
        {
            FileRecord record = FileRecord.Get(volume, VOLUME_INDEX, true);

            return(GetVolumeInformation(record));
        }
Пример #12
0
        private static FileRecord[] GetInstances(byte[] bytes, string volume)
        {
            // Determine the size of an MFT File Record
            int bytesPerFileRecord = (int)(VolumeBootRecord.Get(volume)).BytesPerFileRecord;

            // Calulate the number of entries in the MFT
            int fileCount = bytes.Length / bytesPerFileRecord;

            // Instantiate an array of FileRecord objects
            FileRecord[] recordArray = new FileRecord[fileCount];

            // Instantiate a byte array large enough to store the bytes belonging to a file record
            byte[] recordBytes = new byte[bytesPerFileRecord];

            // Now we need to iterate through all possible index values
            for (int index = 0; index < fileCount; index++)
            {
                // Check if current record has been instantiated
                if (recordArray[index] == null)
                {
                    // Copy filerecord bytes into the recordBytes byte[]
                    Array.Copy(bytes, index * bytesPerFileRecord, recordBytes, 0, recordBytes.Length);

                    // Take UpdateSequence into account
                    ApplyFixup(ref recordBytes);

                    // Instantiate FileRecord object
                    recordArray[index] = new FileRecord(ref recordArray, bytes, recordBytes, bytesPerFileRecord, volume);
                }
            }
            return recordArray;
        }
Пример #13
0
 internal static Data GetMaxStream(FileRecord fileRecord)
 {
     foreach (Attr attr in fileRecord.Attribute)
     {
         if (attr.NameString == "$Max")
         {
             return attr as Data;
         }
     }
     throw new Exception("No $MAX attribute found.");
 }
Пример #14
0
        public static UsnJrnlDetail Get(string path)
        {
            FileRecord record = FileRecord.Get(path, true);

            return(new UsnJrnlDetail(GetMaxStream(record).RawData));
        }
Пример #15
0
        private static UsnJrnl[] GetInstances(string volume, int recordnumber)
        {
            // Check for valid Volume name
            Util.getVolumeName(ref volume);

            // Set up FileStream to read volume
            IntPtr     hVolume      = Util.getHandle(volume);
            FileStream streamToRead = Util.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 = Util.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());
        }
Пример #16
0
        internal static IndexEntry Get(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, false);

                indexEntryList.Clear();

                if (i < paths.Length - 1)
                {
                    foreach (FileRecordAttribute attr in record.Attribute)
                    {
                        if (attr.Name == FileRecordAttribute.ATTR_TYPE.INDEX_ROOT)
                        {
                            foreach (IndexEntry entry in (attr as IndexRoot).Entries)
                            {
                                if (entry.Entry.Namespace != 0x02)
                                {
                                    indexEntryList.Add(entry);
                                }
                            }
                        }
                        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)
                                {
                                    indexEntryList.Add(entry);
                                }
                            }
                        }
                    }
                }
                else
                {
                    return(new IndexEntry(record));
                }
            }
            throw new Exception("The IndexEntry object for the specified path could not be found.");
        }
Пример #17
0
 private IndexEntry(FileRecord record)
 {
     RecordNumber = record.RecordNumber;
     Filename     = record.Name;
     FullName     = record.FullName;
 }
Пример #18
0
        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());
        }
Пример #19
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="path"></param>
 /// <returns></returns>
 public static VolumeInformation GetByPath(string path)
 {
     return(Get(FileRecord.Get(path, true)));
 }
Пример #20
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public static byte[] GetBytesByPath(string path)
        {
            FileRecord record = FileRecord.Get(path, true);

            return(record.GetContent());
        }
Пример #21
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="volume"></param>
        /// <param name="recordnumber"></param>
        /// <param name="usn"></param>
        /// <returns></returns>
        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");
            }
        }
Пример #22
0
        public static byte[] GetBytes(string path)
        {
            FileRecord record = FileRecord.Get(path, true);

            return(GetMaxStream(record).RawData);
        }
Пример #23
0
 private IndexEntry(FileRecord record)
 {
     RecordNumber = record.RecordNumber;
     Filename = record.Name;
     FullName = record.FullName;
 }
Пример #24
0
        public static UsnJrnlDetail GetByPath(string path)
        {
            FileRecord record = FileRecord.Get(path, true);

            return(new UsnJrnlDetail(record.GetContent(@"$Max")));
        }
Пример #25
0
 public static FileRecord[] GetInstances(string volume)
 {
     FileRecord record = new FileRecord(FileRecord.GetRecordBytes(volume, 0), volume, true);
     byte[] mftBytes = record.GetContent();
     return GetInstances(mftBytes, volume);
 }
Пример #26
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="volume"></param>
 /// <returns></returns>
 public static VolumeName Get(string volume)
 {
     Helper.getVolumeName(ref volume);
     return(Get(FileRecord.Get(volume, MftIndex.VOLUME_INDEX, true)));
 }
Пример #27
0
        public byte[] GetTestContent(string streamName)
        {
            foreach (Attr attr in this.Attribute)
            {
                if (attr.Name == Attr.ATTR_TYPE.DATA)
                {
                    if (attr.NameString.ToUpper() == streamName.ToUpper())
                    {
                        if (attr.NonResident)
                        {
                            return (attr as NonResident).GetBytes(this.VolumePath);
                        }
                        else
                        {
                            return (attr as Data).RawData;
                        }
                    }
                }

                AttributeList attrList = attr as AttributeList;
                if (attrList != null)
                {
                    foreach (AttrRef ar in attrList.AttributeReference)
                    {
                        if (ar.Name == "DATA")
                        {
                            FileRecord record = new FileRecord(FileRecord.GetRecordBytes(this.VolumePath, (int)ar.RecordNumber), this.VolumePath, true);
                            return record.GetTestContent(streamName);
                        }
                    }
                }
            }
            throw new Exception("Could not locate desired stream");
        }
Пример #28
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="path"></param>
 /// <returns></returns>
 public static VolumeName GetByPath(string path)
 {
     return(Get(FileRecord.Get(path, true)));
 }
Пример #29
0
 public byte[] GetMftSlack()
 {
     byte[] bytes = FileRecord.GetRecordBytes(this.VolumePath, (int)this.RecordNumber);
     return(NativeMethods.GetSubArray(bytes, this.RealSize - 1, this.AllocatedSize - this.RealSize));
 }
Пример #30
0
        // GetInstances Constructor
        private FileRecord(ref FileRecord[] recordArray, byte[] bytes, int offset, int bytesPerFileRecord, string volume, bool fast)
        {
            if (Encoding.ASCII.GetString(bytes, 0x00 + offset, 0x04) == "FILE")
            {
                OffsetOfUS            = BitConverter.ToUInt16(bytes, 0x04 + offset);
                SizeOfUS              = BitConverter.ToUInt16(bytes, 0x06 + offset);
                LogFileSequenceNumber = BitConverter.ToUInt64(bytes, 0x08 + offset);
                SequenceNumber        = BitConverter.ToUInt16(bytes, 0x10 + offset);
                Hardlinks             = BitConverter.ToUInt16(bytes, 0x12 + offset);
                OffsetOfAttribute     = BitConverter.ToUInt16(bytes, 0x14 + offset);
                Flags           = (FILE_RECORD_FLAG)BitConverter.ToUInt16(bytes, 0x16 + offset);
                Deleted         = isDeleted(Flags);
                Directory       = isDirectory(Flags);
                RealSize        = BitConverter.ToInt32(bytes, 0x18 + offset);
                AllocatedSize   = BitConverter.ToInt32(bytes, 0x1C + offset);
                ReferenceToBase = BitConverter.ToUInt64(bytes, 0x20 + offset);
                NextAttrId      = BitConverter.ToUInt16(bytes, 0x28 + offset);
                RecordNumber    = BitConverter.ToUInt32(bytes, 0x2C + offset);
                Attribute       = FileRecordAttribute.GetInstances(bytes, OffsetOfAttribute + offset, 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 = null;

                                    // Test if we have already parse the record
                                    if (recordArray[attribute.RecordNumber] != null)
                                    {
                                        record = recordArray[attribute.RecordNumber];
                                    }
                                    else
                                    {
                                        // If not parse it and add it to the array
                                        record = new FileRecord(ref recordArray, bytes, bytesPerFileRecord * (int)attribute.RecordNumber, bytesPerFileRecord, volume, fast);
                                        recordArray[attribute.RecordNumber] = record;
                                    }

                                    // Add the attributes to the attribute array
                                    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 = null;

                        if (recordArray[this.ParentRecordNumber] != null)
                        {
                            parent = recordArray[this.ParentRecordNumber];
                        }
                        else
                        {
                            parent = new FileRecord(ref recordArray, bytes, bytesPerFileRecord * (int)this.ParentRecordNumber, bytesPerFileRecord, volume, fast);
                            recordArray[this.ParentRecordNumber] = parent;
                        }

                        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
            }
        }
Пример #31
0
        public static ForensicTimeline[] Get(FileRecord input)
        {
            List<ForensicTimeline> macs = new List<ForensicTimeline>();
            if (input.SequenceNumber != 0)
            {
                #region DetermineTime

                Dictionary<DateTime, ACTIVITY_TYPE> dictionary = new Dictionary<DateTime, ACTIVITY_TYPE>();

                // Modified Time
                dictionary[input.ModifiedTime] = ACTIVITY_TYPE.m;

                // Access Time
                if (dictionary.ContainsKey(input.AccessedTime))
                {
                    dictionary[input.AccessedTime] = dictionary[input.AccessedTime] | ACTIVITY_TYPE.a;
                }
                else
                {
                    dictionary.Add(input.AccessedTime, ACTIVITY_TYPE.a);
                }

                // MFT Changed Time
                if (dictionary.ContainsKey(input.ChangedTime))
                {
                    dictionary[input.ChangedTime] = dictionary[input.ChangedTime] | ACTIVITY_TYPE.c;
                }
                else
                {
                    dictionary.Add(input.ChangedTime, ACTIVITY_TYPE.c);
                }

                // Born Time
                if (dictionary.ContainsKey(input.BornTime))
                {
                    dictionary[input.BornTime] = dictionary[input.BornTime] | ACTIVITY_TYPE.b;
                }
                else
                {
                    dictionary.Add(input.BornTime, ACTIVITY_TYPE.b);
                }

                #endregion DetermineTime

                foreach (var time in dictionary)
                {
                    string activity = ToFriendlyString(time.Value);
                    macs.Add(new ForensicTimeline(time.Key, activity, "MFT", "", input.FullName, input.ToString()));
                }

                return macs.ToArray();
            }
            else
            {
                macs.Add(new ForensicTimeline(new DateTime(1), "MACB", "MFT", "", "", ""));
                return macs.ToArray();
            }
        }
Пример #32
0
        // Get Constructor
        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
            }
        }
Пример #33
0
        private ShellLink(byte[] bytes, FileRecord record)
        {
            Path = record.FullName;

            HeaderSize = BitConverter.ToInt32(bytes, 0x00);

            if (HeaderSize == 0x4C)
            {
                #region SHELL_LINK_HEADER

                LinkCLSID = new Guid(NativeMethods.GetSubArray(bytes, 0x04, 0x10));
                LinkFlags = (LINK_FLAGS)BitConverter.ToUInt32(bytes, 0x14);
                FileAttributes = (FILEATTRIBUTE_FLAGS)BitConverter.ToUInt32(bytes, 0x18);
                CreationTime = DateTime.FromFileTimeUtc(BitConverter.ToInt64(bytes, 0x1C));
                AccessTime = DateTime.FromFileTimeUtc(BitConverter.ToInt64(bytes, 0x24));
                WriteTime = DateTime.FromFileTimeUtc(BitConverter.ToInt64(bytes, 0x2C));
                FileSize = BitConverter.ToUInt32(bytes, 0x34);
                IconIndex = BitConverter.ToInt32(bytes, 0x38);
                ShowCommand = (SHOWCOMMAND)BitConverter.ToUInt32(bytes, 0x3C);
                #region HotKey
                HotKey = new HOTKEY_FLAGS[2];
                HotKey[0] = (HOTKEY_FLAGS)bytes[0x40];
                HotKey[1] = (HOTKEY_FLAGS)bytes[0x41];
                #endregion HotKey

                int offset = 0x4C;

                #endregion SHELL_LINK_HEADER

                // I want to remove one layer of objects
                #region LINKTARGET_IDLIST

                if ((LinkFlags & LINK_FLAGS.HasLinkTargetIdList) == LINK_FLAGS.HasLinkTargetIdList)
                {
                    IdListSize = BitConverter.ToUInt16(bytes, offset);
                    IdList = new IdList(bytes, offset + 0x02, IdListSize);

                    offset += IdListSize + 0x02;
                }

                #endregion LINKTARGET_IDLIST

                #region LINKINFO

                if ((LinkFlags & LINK_FLAGS.HasLinkInfo) == LINK_FLAGS.HasLinkInfo)
                {
                    LinkInfoSize = BitConverter.ToUInt32(bytes, offset);
                    LinkInfoHeaderSize = BitConverter.ToUInt32(bytes, offset + 0x04);
                    LinkInfoFlags = (LINKINFO_FLAGS)BitConverter.ToUInt32(bytes, offset + 0x08);

                    if ((LinkInfoFlags & LINKINFO_FLAGS.VolumeIDAndLocalBasePath) == LINKINFO_FLAGS.VolumeIDAndLocalBasePath)
                    {
                        VolumeIdOffset = BitConverter.ToUInt32(bytes, offset + 0x0C);
                        VolumeId = new VolumeId(bytes, offset + (int)VolumeIdOffset);

                        LocalBasePathOffset = BitConverter.ToUInt32(bytes, offset + 0x10);
                        LocalBasePath = Encoding.Default.GetString(bytes, offset + (int)LocalBasePathOffset, (int)LinkInfoSize - (int)LocalBasePathOffset).Split('\0')[0];
                    }

                    if ((LinkInfoFlags & LINKINFO_FLAGS.CommonNetworkRelativeLinkAndPathSuffix) == LINKINFO_FLAGS.CommonNetworkRelativeLinkAndPathSuffix)
                    {
                        CommonNetworkRelativeLinkOffset = BitConverter.ToUInt32(bytes, offset + 0x14);
                        CommonNetworkRelativeLink = new CommonNetworkRelativeLink(bytes, offset + (int)CommonNetworkRelativeLinkOffset);

                        CommonPathSuffixOffset = BitConverter.ToUInt32(bytes, offset + 0x18);
                        CommonPathSuffix = Encoding.Default.GetString(bytes, offset + (int)CommonPathSuffixOffset, (int)LinkInfoSize - (int)CommonPathSuffixOffset).Split('\0')[0];
                    }

                    if (LinkInfoHeaderSize >= 0x24)
                    {
                        LocalBasePathOffsetUnicode = BitConverter.ToUInt32(bytes, offset + 0x1C);
                        LocalBasePathUnicode = Encoding.Unicode.GetString(bytes, offset + (int)LocalBasePathOffsetUnicode, (int)LinkInfoSize - (int)LocalBasePathOffsetUnicode).Split('\0')[0];

                        CommonPathSuffixOffsetUnicode = BitConverter.ToUInt32(bytes, offset + 0x20);
                        CommonPathSuffixUnicode = Encoding.Unicode.GetString(bytes, offset + (int)CommonPathSuffixOffsetUnicode, (int)LinkInfoSize - (int)CommonPathSuffixOffsetUnicode).Split('\0')[0];
                    }

                    offset += (int)LinkInfoSize;
                }

                #endregion LINKINFO

                #region STRING_DATA

                if ((LinkFlags & LINK_FLAGS.HasName) == LINK_FLAGS.HasName)
                {
                    NameSize = BitConverter.ToUInt16(bytes, offset);
                    Name = Encoding.Unicode.GetString(bytes, offset + 0x02, NameSize * 2);

                    offset += 2 + (NameSize * 2);
                }
                if ((LinkFlags & LINK_FLAGS.HasRelativePath) == LINK_FLAGS.HasRelativePath)
                {
                    RelativePathSize = BitConverter.ToUInt16(bytes, offset);
                    RelativePath = Encoding.Unicode.GetString(bytes, offset + 0x02, RelativePathSize * 2);

                    offset += 2 + (RelativePathSize * 2);
                }
                if ((LinkFlags & LINK_FLAGS.HasWorkingDir) == LINK_FLAGS.HasWorkingDir)
                {
                    WorkingDirectorySize = BitConverter.ToUInt16(bytes, offset);
                    WorkingDirectory = Encoding.Unicode.GetString(bytes, offset + 0x02, WorkingDirectorySize * 2);

                    offset += 2 + (WorkingDirectorySize * 2);
                }
                if ((LinkFlags & LINK_FLAGS.HasArguments) == LINK_FLAGS.HasArguments)
                {
                    CommandLineArgumentsSize = BitConverter.ToUInt16(bytes, offset);
                    CommandLineArguments = Encoding.Unicode.GetString(bytes, offset + 0x02, CommandLineArgumentsSize * 2);

                    offset += 2 + (CommandLineArgumentsSize * 2);
                }
                if ((LinkFlags & LINK_FLAGS.HasIconLocation) == LINK_FLAGS.HasIconLocation)
                {
                    IconLocationSize = BitConverter.ToUInt16(bytes, offset);
                    IconLocation = Encoding.Unicode.GetString(bytes, offset + 0x02, IconLocationSize * 2);

                    offset += 2 + (IconLocationSize * 2);
                }

                #endregion STRING_DATA

                #region EXTRA_DATA

                List<ExtraData> edList = new List<ExtraData>();

                int datalength = 0;

                do
                {
                    datalength = BitConverter.ToInt32(bytes, offset);

                    switch (BitConverter.ToUInt32(bytes, offset + 0x04))
                    {
                        case 0xA0000001:
                            edList.Add(new EnvironmentVariableDataBlock(bytes, offset));
                            break;
                        case 0xA0000002:
                            edList.Add(new ConsoleDataBlock(bytes, offset));
                            break;
                        case 0xA0000003:
                            edList.Add(new TrackerDataBlock(bytes, offset));
                            break;
                        case 0xA0000004:
                            edList.Add(new ConsoleFeDataBlock(bytes, offset));
                            break;
                        case 0xA0000005:
                            edList.Add(new SpecialFolderDataBlock(bytes, offset));
                            break;
                        case 0xA0000006:
                            edList.Add(new DarwinDataBlock(bytes, offset));
                            break;
                        case 0xA0000007:
                            edList.Add(new IconEnvironmentDataBlock(bytes, offset));
                            break;
                        case 0xA0000008:
                            edList.Add(new ShimDataBlock(bytes, offset));
                            break;
                        case 0xA0000009:
                            edList.Add(new PropertyStoreDataBlock(bytes, offset));
                            break;
                        case 0xA000000B:
                            edList.Add(new KnownFolderDataBlock(bytes, offset));
                            break;
                        case 0xA000000C:
                            edList.Add(new VistaAndAboveIDListDataBlock(bytes, offset));
                            break;
                    }

                    offset += datalength;

                } while (offset < bytes.Length - 0x04);

                ExtraData = edList.ToArray();

                #endregion EXTRA_DATA
            }
            else
            {
                throw new Exception("Invalid ShellLink Header.");
            }
        }
Пример #34
0
        public static byte[] GetContentBytes(string path, string streamName)
        {
            FileRecord record = Get(path, true);

            return(record.GetTestContent(streamName));
        }
Пример #35
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()));
        }
Пример #36
0
 public byte[] GetMftSlack()
 {
     byte[] bytes = FileRecord.GetRecordBytes(this.VolumePath, (int)this.RecordNumber);
     return(Helper.GetSubArray(bytes, (int)this.RealSize - 1, (int)this.AllocatedSize - (int)this.RealSize));
 }
Пример #37
0
 internal static FileRecord GetFileRecord(string volume)
 {
     return(FileRecord.Get(volume, MftIndex.LOGFILE_INDEX, true));
 }
Пример #38
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

                //bool hasAttributeList = false;
                //List<FileRecordAttribute> ListOfAttributes = new List<FileRecordAttribute>();

                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 (!(attr.NonResident))
                        {
                            AttributeList attributeList = attr as AttributeList;
                            hasAttributeList = true;

                            List<ulong> numList = new List<ulong>();

                            foreach (AttrRef attrRef in attributeList.AttributeReference)
                            {
                                if (!(numList.Contains(attrRef.RecordNumber)))
                                {
                                    numList.Add(attrRef.RecordNumber);
                                }
                            }

                            foreach (ulong i in numList)
                            {
                                if (recordArray[i] == null)
                                {
                                    recordArray[i] = new FileRecordTest(ref recordArray, bytes, bytesPerFileRecord * (int)i, bytesPerFileRecord, volume, false);
                                }

                                ListOfAttributes.AddRange(recordArray[i].Attribute);
                            }
                        }
                    }*/
                    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
            }
        }
Пример #39
0
        private static FileRecord[] GetInstances(byte[] bytes, string volume, bool fast)
        {
            VolumeBootRecord vbr = VolumeBootRecord.Get(volume);

            // Determine the size of an MFT File Record
            int bytesPerFileRecord = (int)vbr.BytesPerFileRecord;

            // Calulate the number of entries in the MFT
            int fileCount = bytes.Length / bytesPerFileRecord;

            // Instantiate an array of FileRecord objects
            FileRecord[] recordArray = new FileRecord[fileCount];

            // Apply fixup values across MFT Bytes
            ApplyFixup(ref bytes, (int)vbr.BytesPerFileRecord);

            // Now we need to iterate through all possible index values
            for (int index = 0x00; index < fileCount; index++)
            {
                // Check if current record has been instantiated
                if (recordArray[index] == null)
                {
                    // Instantiate FileRecord object
                    recordArray[index] = new FileRecord(ref recordArray, bytes, index * bytesPerFileRecord, bytesPerFileRecord, volume, fast);
                }
            }

            return recordArray;
        }
Пример #40
0
 internal static FileRecord GetFileRecord(string volume)
 {
     return(FileRecord.Get(volume, BADCLUS_INDEX, true));
 }
Пример #41
0
        public static VolumeName Get(string volume)
        {
            FileRecord record = FileRecord.Get(volume, MftIndex.VOLUME_INDEX, true);

            return(Get(record));
        }
Пример #42
0
        public static VolumeInformation GetVolumeInformationByPath(string path)
        {
            FileRecord record = FileRecord.Get(path, true);

            return(GetVolumeInformation(record));
        }
Пример #43
0
        public static IndexEntry[] GetInstances(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 = new FileRecord(FileRecord.GetRecordBytes(volume, index), volume, true);

                indexEntryList.Clear();

                if (record.Directory)
                {
                    foreach (Attr attr in record.Attribute)
                    {
                        if (attr.Name == Attr.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 == 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)
                                {
                                    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();
        }
Пример #44
0
        public static VolumeName GetByPath(string path)
        {
            FileRecord record = FileRecord.Get(path, true);

            return(Get(record));
        }
Пример #45
0
        private static FileRecord[] GetInstancesTest(byte[] bytes, string volume)
        {
            // Determine the size of an MFT File Record
            int bytesPerFileRecord = (int)(VolumeBootRecord.Get(volume)).BytesPerFileRecord;

            // Calulate the number of entries in the MFT
            int fileCount = bytes.Length / bytesPerFileRecord;

            // Instantiate an array of FileRecord objects
            FileRecord[] recordArray = new FileRecord[fileCount];

            // Now we need to iterate through all possible index values
            for (int index = 0; index < fileCount; index++)
            {
                // Check if current record has been instantiated
                if (recordArray[index] == null)
                {
                    int offset = index * bytesPerFileRecord;

                    // Take UpdateSequence into account
                    ApplyFixupTest(ref bytes, offset);

                    // Instantiate FileRecord object
                    recordArray[index] = new FileRecord(ref recordArray, bytes, offset, volume, (uint)bytesPerFileRecord);
                }
            }
            return recordArray;
        }
Пример #46
0
        private FileRecord(ref FileRecord[] array, byte[] bytes, int offset, string volume, uint bytesPerFileRecord)
        {
            Signature = Encoding.ASCII.GetString(bytes, 0x00 + offset, 0x04);

            if (Signature == "FILE")
            {
                OffsetOfUS = BitConverter.ToUInt16(bytes, 0x04 + offset);
                SizeOfUS = BitConverter.ToUInt16(bytes, 0x06 + offset);
                LogFileSequenceNumber = BitConverter.ToUInt64(bytes, 0x08 + offset);
                SequenceNumber = BitConverter.ToUInt16(bytes, 0x10 + offset);
                Hardlinks = BitConverter.ToUInt16(bytes, 0x12 + offset);
                OffsetOfAttribute = BitConverter.ToUInt16(bytes, 0x14 + offset);
                Flags = BitConverter.ToUInt16(bytes, 0x16 + offset);
                Deleted = IsDeleted(Flags);
                Directory = IsDirectory(Flags);
                RealSize = BitConverter.ToUInt32(bytes, 0x18 + offset);
                AllocatedSize = BitConverter.ToUInt32(bytes, 0x1C + offset);
                ReferenceToBase = BitConverter.ToUInt64(bytes, 0x20 + offset);
                NextAttrId = BitConverter.ToUInt16(bytes, 0x28 + offset);
                RecordNumber = BitConverter.ToUInt32(bytes, 0x2C + offset);
                
                #region Attribute

                // Instantiate an empty list of Attr Objects (We don't know how many attributes the record contains)
                List<FileRecordAttribute> AttributeList = new List<FileRecordAttribute>();
                int currentOffset = offset + OffsetOfAttribute;

                do
                {
                    FileRecordAttribute attr = FileRecordAttribute.GetTest(bytes, currentOffset, volume);

                    if (attr != null)
                    {
                        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.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;
                            }
                        }

                        AttributeList.Add(attr);
                    }

                    // Get attribute size
                    int attrSizeOffset = currentOffset + 0x04;
                    int attrSize = BitConverter.ToInt32(bytes, attrSizeOffset);

                    if (attrSize == 0)
                    {
                        break;
                    }

                    // Increment currentOffset
                    currentOffset += attrSize;

                } while ((currentOffset - offset) < bytesPerFileRecord);

                Attribute = AttributeList.ToArray();

                #endregion Attribute
                
                /*#region FullName

                StringBuilder sb = new StringBuilder();

                // Record 5 is the root of the drive
                if (RecordNumber == 5)
                {
                    sb.Append(Helper.GetVolumeLetter(volume));
                }
                else
                {
                    // Derive Path by looking at ParentRecord's FullName
                    if (array[(int)ParentRecordNumber] != null)
                    {
                        if (ParentSequenceNumber == array[(int)ParentRecordNumber].SequenceNumber)
                        {
                            sb.Append(array[(int)ParentRecordNumber].FullName);
                        }
                        else
                        {
                            sb.Append(@"$OrphanFiles\");
                        }
                    }

                    // If record for Parent does not already exist then instantiate it and add it to the array
                    else
                    {
                        int parentOffset = (int)bytesPerFileRecord * (int)ParentRecordNumber;

                        array[(int)ParentRecordNumber] = new FileRecord(ref array, bytes, parentOffset, volume, bytesPerFileRecord);

                        if (ParentSequenceNumber == array[(int)ParentRecordNumber].SequenceNumber)
                        {
                            sb.Append(array[(int)ParentRecordNumber].FullName);
                        }
                        else
                        {
                            sb.Append(@"$OrphanFiles\");
                        }
                    }

                    // Add file name to end of path
                    sb.Append(Name);
                }

                // Add trailing \ to any file that is a directory
                if (Directory)
                {
                    sb.Append('\\');
                }

                // Figure out a way to have record 15 not have a name of $MFT...

                FullName = sb.ToString();

                #endregion FullName*/
            }
        }
Пример #47
0
        internal static NonResident GetJStream(FileRecord fileRecord)
        {
            foreach (Attr 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 = new FileRecord(FileRecord.GetRecordBytes(fileRecord.VolumePath, (int)ar.RecordNumber), fileRecord.VolumePath, true);
                            return GetJStream(record);
                        }
                    }
                }
            }
            throw new Exception("No $J attribute found.");
        }
Пример #48
0
        private FileRecord(ref FileRecord[] array, byte[] mftBytes, byte[] recordBytes, int bytesPerFileRecord, string volume)
        {
            VolumePath = volume;

            Signature = Encoding.ASCII.GetString(recordBytes, 0x00, 0x04);

            if (Signature == "FILE")
            {
                // Parse File Record Header
                OffsetOfUS           = BitConverter.ToUInt16(recordBytes, 4);
                SizeOfUS             = BitConverter.ToUInt16(recordBytes, 6);
                UpdateSequenceNumber = BitConverter.ToUInt16(recordBytes, OffsetOfUS);
                #region UpdateSequenceArray

                UpdateSequenceArray = new byte[(2 * SizeOfUS) - 2];
                Array.Copy(recordBytes, (OffsetOfUS + 2), UpdateSequenceArray, 0, UpdateSequenceArray.Length);

                #endregion UpdateSequenceArray
                LogFileSequenceNumber = BitConverter.ToUInt64(recordBytes, 8);
                SequenceNumber        = BitConverter.ToUInt16(recordBytes, 16);
                Hardlinks             = BitConverter.ToUInt16(recordBytes, 18);
                OffsetOfAttribute     = BitConverter.ToUInt16(recordBytes, 20);
                Flags = BitConverter.ToUInt16(recordBytes, 22);
                #region Deleted
                if ((Flags & (ushort)FILE_RECORD_FLAG.INUSE) == (ushort)FILE_RECORD_FLAG.INUSE)
                {
                    Deleted = false;
                }
                else
                {
                    Deleted = true;
                }
                #endregion Deleted
                #region Directory
                if ((Flags & (ushort)FILE_RECORD_FLAG.DIR) == (ushort)FILE_RECORD_FLAG.DIR)
                {
                    Directory = true;
                }
                else
                {
                    Directory = false;
                }
                #endregion Directory
                RealSize        = BitConverter.ToUInt32(recordBytes, 24);
                AllocatedSize   = BitConverter.ToUInt32(recordBytes, 28);
                ReferenceToBase = BitConverter.ToUInt64(recordBytes, 32);
                NextAttrId      = BitConverter.ToUInt16(recordBytes, 40);
                RecordNumber    = BitConverter.ToUInt32(recordBytes, 44);
                #region Attribute

                // Create a byte array representing the attribute array
                byte[] attrArrayBytes = new byte[RealSize - OffsetOfAttribute];

                ApplyFixup(ref recordBytes);

                Array.Copy(recordBytes, OffsetOfAttribute, attrArrayBytes, 0, attrArrayBytes.Length);

                // Instantiate an empty list of Attr Objects (We don't know how many attributes the record contains)
                List <Attr> AttributeList = new List <Attr>();

                // Initialize the offset value to 0
                int currentOffset = 0;

                if (currentOffset < (attrArrayBytes.Length - 8))
                {
                    do
                    {
                        // Get attribute size
                        int attrSizeOffset = currentOffset + 4;
                        int attrSize       = BitConverter.ToInt32(attrArrayBytes, attrSizeOffset);

                        // Create new byte array with just current attribute's bytes
                        byte[] currentAttrBytes = new byte[attrSize];
                        Array.Copy(attrArrayBytes, currentOffset, currentAttrBytes, 0, currentAttrBytes.Length);

                        // Increment currentOffset
                        currentOffset += attrSize;

                        Attr attr = AttributeFactory.Get(currentAttrBytes, volume);

                        if (attr != null)
                        {
                            if (attr.Name == Attr.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 == Attr.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;
                                }
                            }

                            AttributeList.Add(attr);
                        }
                    } while (currentOffset < (attrArrayBytes.Length - 8));
                }

                Attribute = AttributeList.ToArray();

                #endregion Attribute
                #region FullName

                StringBuilder sb = new StringBuilder();

                // Record 5 is the root of the drive
                if (RecordNumber == 5)
                {
                    sb.Append(volume.Split('\\')[3]);
                }
                else
                {
                    // Derive Path by looking at ParentRecord's FullName
                    if (array[(int)ParentRecordNumber] != null)
                    {
                        if (ParentSequenceNumber == array[(int)ParentRecordNumber].SequenceNumber)
                        {
                            sb.Append(array[(int)ParentRecordNumber].FullName);
                        }
                        else
                        {
                            sb.Append(@"$OrphanFiles\");
                        }
                    }

                    // If record for Parent does not already exist then instantiate it and add it to the array
                    else
                    {
                        byte[] parentBytes = NativeMethods.GetSubArray(mftBytes, (uint)bytesPerFileRecord * (uint)ParentRecordNumber, (uint)bytesPerFileRecord);
                        array[(int)ParentRecordNumber] = new FileRecord(ref array, mftBytes, parentBytes, bytesPerFileRecord, volume);

                        if (ParentSequenceNumber == array[(int)ParentRecordNumber].SequenceNumber)
                        {
                            sb.Append(array[(int)ParentRecordNumber].FullName);
                        }
                        else
                        {
                            sb.Append(@"$OrphanFiles\");
                        }
                    }

                    // Add file name to end of path
                    sb.Append(Name);
                }

                // Add trailing \ to any file that is a directory
                if (Directory)
                {
                    sb.Append('\\');
                }

                // Figure out a way to have record 15 not have a name of $MFT...

                FullName = sb.ToString();

                #endregion FullName
            }
        }
Пример #49
0
        private FileRecord(ref FileRecord[] array, byte[] mftBytes, byte[] recordBytes, int bytesPerFileRecord, string volume)
        {
            VolumePath = volume;

            Signature = Encoding.ASCII.GetString(recordBytes, 0x00, 0x04);

            if (Signature == "FILE")
            {
                // Parse File Record Header
                OffsetOfUS = BitConverter.ToUInt16(recordBytes, 4);
                SizeOfUS = BitConverter.ToUInt16(recordBytes, 6);
                UpdateSequenceNumber = BitConverter.ToUInt16(recordBytes, OffsetOfUS);
                #region UpdateSequenceArray
                
                UpdateSequenceArray = new byte[(2 * SizeOfUS) - 2];
                Array.Copy(recordBytes, (OffsetOfUS + 2), UpdateSequenceArray, 0, UpdateSequenceArray.Length);
                
                #endregion UpdateSequenceArray
                LogFileSequenceNumber = BitConverter.ToUInt64(recordBytes, 8);
                SequenceNumber = BitConverter.ToUInt16(recordBytes, 16);
                Hardlinks = BitConverter.ToUInt16(recordBytes, 18);
                OffsetOfAttribute = BitConverter.ToUInt16(recordBytes, 20);
                Flags = BitConverter.ToUInt16(recordBytes, 22);
                #region Deleted
                if ((Flags & (ushort)FILE_RECORD_FLAG.INUSE) == (ushort)FILE_RECORD_FLAG.INUSE)
                {
                    Deleted = false;
                }
                else
                {
                    Deleted = true;
                }
                #endregion Deleted
                #region Directory
                if ((Flags & (ushort)FILE_RECORD_FLAG.DIR) == (ushort)FILE_RECORD_FLAG.DIR)
                {
                    Directory = true;
                }
                else
                {
                    Directory = false;
                }
                #endregion Directory
                RealSize = BitConverter.ToUInt32(recordBytes, 24);
                AllocatedSize = BitConverter.ToUInt32(recordBytes, 28);
                ReferenceToBase = BitConverter.ToUInt64(recordBytes, 32);
                NextAttrId = BitConverter.ToUInt16(recordBytes, 40);
                RecordNumber = BitConverter.ToUInt32(recordBytes, 44);
                #region Attribute

                // Create a byte array representing the attribute array
                byte[] attrArrayBytes = new byte[RealSize - OffsetOfAttribute];

                ApplyFixup(ref recordBytes);

                Array.Copy(recordBytes, OffsetOfAttribute, attrArrayBytes, 0, attrArrayBytes.Length);

                // Instantiate an empty list of Attr Objects (We don't know how many attributes the record contains)
                List<Attr> AttributeList = new List<Attr>();

                // Initialize the offset value to 0
                int currentOffset = 0;

                if (currentOffset < (attrArrayBytes.Length - 8))
                {
                    do
                    {
                        // Get attribute size
                        int attrSizeOffset = currentOffset + 4;
                        int attrSize = BitConverter.ToInt32(attrArrayBytes, attrSizeOffset);

                        // Create new byte array with just current attribute's bytes
                        byte[] currentAttrBytes = new byte[attrSize];
                        Array.Copy(attrArrayBytes, currentOffset, currentAttrBytes, 0, currentAttrBytes.Length);

                        // Increment currentOffset
                        currentOffset += attrSize;

                        Attr attr = AttributeFactory.Get(currentAttrBytes, volume);

                        if (attr != null)
                        {
                            if (attr.Name == Attr.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 == Attr.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;
                                }
                            }

                            AttributeList.Add(attr);
                        }
                    } while (currentOffset < (attrArrayBytes.Length - 8));
                }

                Attribute = AttributeList.ToArray();

                #endregion Attribute
                #region FullName

                StringBuilder sb = new StringBuilder();

                // Record 5 is the root of the drive
                if (RecordNumber == 5)
                {
                    sb.Append(volume.Split('\\')[3]);
                }
                else
                {
                    // Derive Path by looking at ParentRecord's FullName
                    if (array[(int)ParentRecordNumber] != null)
                    {
                        if (ParentSequenceNumber == array[(int)ParentRecordNumber].SequenceNumber)
                        {
                            sb.Append(array[(int)ParentRecordNumber].FullName);
                        }
                        else
                        {
                            sb.Append(@"$OrphanFiles\");
                        }
                    }

                    // If record for Parent does not already exist then instantiate it and add it to the array
                    else
                    {
                        byte[] parentBytes = Util.GetSubArray(mftBytes, (uint)bytesPerFileRecord * (uint)ParentRecordNumber, (uint)bytesPerFileRecord);
                        array[(int)ParentRecordNumber] = new FileRecord(ref array, mftBytes, parentBytes, bytesPerFileRecord, volume);

                        if (ParentSequenceNumber == array[(int)ParentRecordNumber].SequenceNumber)
                        {
                            sb.Append(array[(int)ParentRecordNumber].FullName);
                        }
                        else
                        {
                            sb.Append(@"$OrphanFiles\");
                        }
                    }

                    // Add file name to end of path
                    sb.Append(Name);
                }

                // Add trailing \ to any file that is a directory
                if (Directory)
                {
                    sb.Append('\\');
                }

                // Figure out a way to have record 15 not have a name of $MFT...

                FullName = sb.ToString();

                #endregion FullName
            }
        }
Пример #50
0
 public static FileRecord Get(string volume, int index, bool fast)
 {
     return(new FileRecord(FileRecord.GetRecordBytes(volume, index), volume, fast));
 }
Пример #51
0
 public static FileRecord[] GetInstancesByPath(string path)
 {
     string volume = Util.GetVolumeFromPath(path);
     FileRecord record = new FileRecord(FileRecord.GetRecordBytes(path), volume, true);
     byte[] mftBytes = record.GetContent();
     return GetInstances(mftBytes, volume);
 }
Пример #52
0
        internal FileRecord(byte[] recordBytes, string volume, bool fast)
        {
            VolumePath = volume;

            Signature = Encoding.ASCII.GetString(recordBytes, 0x00, 0x04);

            if (Signature == "FILE")
            {
                // Parse File Record Header
                OffsetOfUS           = BitConverter.ToUInt16(recordBytes, 4);
                SizeOfUS             = BitConverter.ToUInt16(recordBytes, 6);
                UpdateSequenceNumber = BitConverter.ToUInt16(recordBytes, OffsetOfUS);
                #region UpdateSequenceArray

                UpdateSequenceArray = new byte[(2 * SizeOfUS) - 2];
                Array.Copy(recordBytes, (OffsetOfUS + 2), UpdateSequenceArray, 0, UpdateSequenceArray.Length);

                #endregion UpdateSequenceArray
                LogFileSequenceNumber = BitConverter.ToUInt64(recordBytes, 8);
                SequenceNumber        = BitConverter.ToUInt16(recordBytes, 16);
                Hardlinks             = BitConverter.ToUInt16(recordBytes, 18);
                OffsetOfAttribute     = BitConverter.ToUInt16(recordBytes, 20);
                Flags = BitConverter.ToUInt16(recordBytes, 22);
                #region Deleted

                if ((Flags & (ushort)FILE_RECORD_FLAG.INUSE) == (ushort)FILE_RECORD_FLAG.INUSE)
                {
                    Deleted = false;
                }
                else
                {
                    Deleted = true;
                }

                #endregion Deleted
                #region Directory

                if ((Flags & (ushort)FILE_RECORD_FLAG.DIR) == (ushort)FILE_RECORD_FLAG.DIR)
                {
                    Directory = true;
                }
                else
                {
                    Directory = false;
                }

                #endregion Directory
                RealSize        = BitConverter.ToUInt32(recordBytes, 24);
                AllocatedSize   = BitConverter.ToUInt32(recordBytes, 28);
                ReferenceToBase = BitConverter.ToUInt64(recordBytes, 32);
                NextAttrId      = BitConverter.ToUInt16(recordBytes, 40);
                RecordNumber    = BitConverter.ToUInt32(recordBytes, 44);
                #region Attribute

                // Create a byte array representing the attribute array
                byte[] attrArrayBytes = new byte[RealSize - OffsetOfAttribute];
                Array.Copy(recordBytes, OffsetOfAttribute, attrArrayBytes, 0, attrArrayBytes.Length);

                // Instantiate an empty list of Attr Objects (We don't know how many attributes the record contains)
                List <Attr> AttributeList = new List <Attr>();

                // Initialize the offset value to 0
                int currentOffset = 0;

                if (currentOffset < (attrArrayBytes.Length - 8))
                {
                    do
                    {
                        // Get attribute size
                        int attrSizeOffset = currentOffset + 4;
                        int attrSize       = BitConverter.ToInt32(attrArrayBytes, attrSizeOffset);

                        // Create new byte array with just current attribute's bytes
                        byte[] currentAttrBytes = new byte[attrSize];
                        Array.Copy(attrArrayBytes, currentOffset, currentAttrBytes, 0, currentAttrBytes.Length);

                        // Increment currentOffset
                        currentOffset += attrSize;

                        Attr attr = AttributeFactory.Get(currentAttrBytes, volume);

                        if (attr != null)
                        {
                            if (attr.Name == Attr.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 == Attr.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;
                                }
                            }

                            AttributeList.Add(attr);
                        }
                    } while (currentOffset < (attrArrayBytes.Length - 8));
                }

                Attribute = AttributeList.ToArray();

                #endregion Attribute
                #region FullName

                if (fast)
                {
                    FullName = Name;
                }
                else
                {
                    StringBuilder sb = new StringBuilder();

                    if (RecordNumber == 0)
                    {
                        sb.Append(volume.Split('\\')[3]);
                        sb.Append('\\');
                        sb.Append(Name);
                        FullName = sb.ToString();
                    }
                    else if (RecordNumber == 5)
                    {
                        FullName = volume.Split('\\')[3];
                    }
                    else
                    {
                        FileRecord parent = new FileRecord(FileRecord.GetRecordBytes(volume, (int)ParentRecordNumber), volume, 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
            }
        }
Пример #53
0
 internal byte[] GetContent(VolumeBootRecord VBR)
 {
     foreach (Attr attr in this.Attribute)
     {
         if (attr.Name == Attr.ATTR_TYPE.DATA)
         {
             if (attr.NonResident)
             {
                 return (attr as NonResident).GetBytes(this.VolumePath, VBR);
             }
             else
             {
                 return (attr as Data).RawData;
             }
         }
         else if (attr.Name == Attr.ATTR_TYPE.ATTRIBUTE_LIST)
         {
             AttributeList attrlist = attr as AttributeList;
             foreach (AttrRef ar in attrlist.AttributeReference)
             {
                 if (ar.Name == "DATA")
                 {
                     FileRecord record = new FileRecord(FileRecord.GetRecordBytes(this.VolumePath, (int)ar.RecordNumber), this.VolumePath, true);
                     return record.GetContent();
                 }
             }
         }
     }
     throw new Exception("Could not locate file contents");
 }
Пример #54
0
 public FileRecord GetParent()
 {
     return(FileRecord.Get(this.VolumePath, (int)this.ParentRecordNumber, false));
 }
Пример #55
0
        internal FileRecord(byte[] recordBytes, string volume, bool fast)
        {
            VolumePath = volume;

            Signature = Encoding.ASCII.GetString(recordBytes, 0x00, 0x04);

            if (Signature == "FILE")
            {
                // Parse File Record Header
                OffsetOfUS = BitConverter.ToUInt16(recordBytes, 4);
                SizeOfUS = BitConverter.ToUInt16(recordBytes, 6);
                UpdateSequenceNumber = BitConverter.ToUInt16(recordBytes, OffsetOfUS);
                #region UpdateSequenceArray

                UpdateSequenceArray = new byte[(2 * SizeOfUS) - 2];
                Array.Copy(recordBytes, (OffsetOfUS + 2), UpdateSequenceArray, 0, UpdateSequenceArray.Length);
                
                #endregion UpdateSequenceArray
                LogFileSequenceNumber = BitConverter.ToUInt64(recordBytes, 8);
                SequenceNumber = BitConverter.ToUInt16(recordBytes, 16);
                Hardlinks = BitConverter.ToUInt16(recordBytes, 18);
                OffsetOfAttribute = BitConverter.ToUInt16(recordBytes, 20);
                Flags = BitConverter.ToUInt16(recordBytes, 22);
                #region Deleted

                if ((Flags & (ushort)FILE_RECORD_FLAG.INUSE) == (ushort)FILE_RECORD_FLAG.INUSE)
                {
                    Deleted = false;
                }
                else
                {
                    Deleted = true;
                }

                #endregion Deleted
                #region Directory

                if ((Flags & (ushort)FILE_RECORD_FLAG.DIR) == (ushort)FILE_RECORD_FLAG.DIR)
                {
                    Directory = true;
                }
                else
                {
                    Directory = false;
                }

                #endregion Directory
                RealSize = BitConverter.ToUInt32(recordBytes, 24);
                AllocatedSize = BitConverter.ToUInt32(recordBytes, 28);
                ReferenceToBase = BitConverter.ToUInt64(recordBytes, 32);
                NextAttrId = BitConverter.ToUInt16(recordBytes, 40);
                RecordNumber = BitConverter.ToUInt32(recordBytes, 44);
                #region Attribute

                // Create a byte array representing the attribute array
                byte[] attrArrayBytes = new byte[RealSize - OffsetOfAttribute];
                Array.Copy(recordBytes, OffsetOfAttribute, attrArrayBytes, 0, attrArrayBytes.Length);

                // Instantiate an empty list of Attr Objects (We don't know how many attributes the record contains)
                List<Attr> AttributeList = new List<Attr>();

                // Initialize the offset value to 0
                int currentOffset = 0;

                if (currentOffset < (attrArrayBytes.Length - 8))
                {
                    do
                    {
                        // Get attribute size
                        int attrSizeOffset = currentOffset + 4;
                        int attrSize = BitConverter.ToInt32(attrArrayBytes, attrSizeOffset);

                        // Create new byte array with just current attribute's bytes
                        byte[] currentAttrBytes = new byte[attrSize];
                        Array.Copy(attrArrayBytes, currentOffset, currentAttrBytes, 0, currentAttrBytes.Length);

                        // Increment currentOffset
                        currentOffset += attrSize;

                        Attr attr = AttributeFactory.Get(currentAttrBytes, volume);

                        if (attr != null)
                        {
                            if (attr.Name == Attr.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 == Attr.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;
                                }
                            }

                            AttributeList.Add(attr);
                        }
                    } while (currentOffset < (attrArrayBytes.Length - 8));
                }

                Attribute = AttributeList.ToArray();

                #endregion Attribute
                #region FullName

                if (fast)
                {
                    FullName = Name;
                }
                else
                {
                    StringBuilder sb = new StringBuilder();

                    if (RecordNumber == 0)
                    {
                        sb.Append(volume.Split('\\')[3]);
                        sb.Append('\\');
                        sb.Append(Name);
                        FullName = sb.ToString();
                    }
                    else if (RecordNumber == 5)
                    {
                        FullName = volume.Split('\\')[3];
                    }
                    else
                    {
                        FileRecord parent = new FileRecord(FileRecord.GetRecordBytes(volume, (int)ParentRecordNumber), volume, 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
            }
        }
Пример #56
0
        public static AttrDef[] GetInstances(string volume)
        {
            FileRecord record = FileRecord.Get(volume, ATTRDEF_INDEX, true);

            return(AttrDef.GetInstances(record.GetContent()));
        }