Exemplo n.º 1
0
 public static byte[] GetHiveBytes(string path)
 {
     // Get bytes for the specific record
     string volume = "\\\\.\\" + path.Split('\\')[0];
     IndexEntry entry = IndexEntry.Get(path);
     FileRecord record = new FileRecord(FileRecord.GetRecordBytes(volume, (int)entry.RecordNumber), volume, true);
     return record.GetBytes();
 }
        public static byte[] GetBytes(string path)
        {
            // Get bytes for the specific record
            string volume = "\\\\.\\" + path.Split('\\')[0];
            IndexEntry entry = IndexEntry.Get(path);
            FileRecord record = new FileRecord(FileRecord.GetRecordBytes(volume, (int)entry.RecordNumber), volume);
            byte[] bytes = record.GetBytes();

            // Registry Header
            return NativeMethods.GetSubArray(bytes, 0x00, 0x200);
        }
Exemplo n.º 3
0
 internal static NonResident GetDataAttr(FileRecord fileRecord)
 {
     foreach (Attr attr in fileRecord.Attribute)
     {
         if (attr.Name == Attr.ATTR_TYPE.DATA)
         {
             return attr as NonResident;
         }
     }
     throw new Exception("No DATA attribute found.");
 }
Exemplo n.º 4
0
 internal static VolumeName GetVolumeNameAttr(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.");
 }
Exemplo n.º 5
0
 internal static VolumeInformation GetVolumeInformationAttr(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.");
 }
Exemplo n.º 6
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();
        }
Exemplo n.º 7
0
        public static HiveBinHeader[] GetInstances(string path)
        {
            // Get bytes for the specific record
            string volume = "\\\\.\\" + path.Split('\\')[0];
            IndexEntry entry = IndexEntry.Get(path);
            FileRecord record = new FileRecord(FileRecord.GetRecordBytes(volume, (int)entry.RecordNumber), volume);
            byte[] bytes = record.GetBytes();

            // Registry Header
            RegistryHeader header = new RegistryHeader(NativeMethods.GetSubArray(bytes, 0x00, 0x200));

            // Hive Bin Headers
            HiveBinHeader[] headerArray = new HiveBinHeader[header.HiveBinsDataSize / 0x1000];
            byte[] hbinHeaderBytes = new byte[0x20];
            uint i = 0x1000;
            while (i < header.HiveBinsDataSize + 0x1000)
            {
                HiveBinHeader hbinHeader = new HiveBinHeader(NativeMethods.GetSubArray(bytes, i, 0x20));
                headerArray[((i / 0x1000) - 1)] = hbinHeader;
                i += hbinHeader.hBinSize;
            }

            return headerArray;
        }
Exemplo n.º 8
0
 internal static AttrDef[] GetInstances(string volume, int index)
 {
     return(AttrDef.GetInstances(new FileRecord(FileRecord.GetRecordBytes(volume, index), volume).GetBytes()));
 }
Exemplo n.º 9
0
 internal static ScheduledJob Get(string volume, int recordNumber)
 {
     FileRecord record = new FileRecord(FileRecord.GetRecordBytes(volume, recordNumber), volume, true);
     return new ScheduledJob(record.GetBytes());
 }
Exemplo n.º 10
0
 internal static ScheduledJob Get(string path)
 {
     string volume = "\\\\.\\" + path.Split('\\')[0];
     IndexEntry index = IndexEntry.Get(path);
     FileRecord record = new FileRecord(FileRecord.GetRecordBytes(volume, (int)index.RecordNumber), volume, true);
     return new ScheduledJob(record.GetBytes());
 }
Exemplo n.º 11
0
        public static Prefetch Get(string filePath)
        {
            // Get volume path from filePath
            string volume = @"\\.\" + filePath.Split('\\')[0];

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

            // Get MFT Index for specified file
            int index = (int)(IndexEntry.Get(filePath)).RecordNumber;

            // Get bytes for specific Prefetch file
            byte[] fileBytes = new FileRecord(FileRecord.GetRecordBytes(volume, index), volume, true).GetBytes();

            try
            {
                // Return a Prefetch object for the Prefetch file stored at filePath
                return new Prefetch(fileBytes);
            }
            catch
            {
                throw new Exception("Error parsing Prefetch file");
            }
        }
Exemplo n.º 12
0
        public FileRecord(byte[] recordBytes, 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);

                #region UpdateSequenceNumber
                byte[] usnBytes = new byte[2];
                Array.Copy(recordBytes, OffsetOfUS, usnBytes, 0, usnBytes.Length);
                UpdateSequenceNumber = BitConverter.ToUInt16(usnBytes, 0);
                #endregion UpdateSequenceNumber

                #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

                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);
                    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
            }
        }
Exemplo n.º 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.");
 }
Exemplo n.º 14
0
 internal static NonResident GetJStream(FileRecord fileRecord)
 {
     foreach (Attr attr in fileRecord.Attribute)
     {
         if (attr.NameString == "$J")
         {
             return attr as NonResident;
         }
     }
     throw new Exception("No $J attribute found.");
 }
Exemplo n.º 15
0
        public FileRecord GetParentFileRecord()
        {
            FileRecord record = new FileRecord(FileRecord.GetRecordBytes(this.VolumePath, (int)this.ParentFileRecordNumber), this.VolumePath);

            if (record.SequenceNumber == this.ParentFileSequenceNumber)
            {
                return record;
            }
            else
            {
                throw new Exception("Desired FileRecord has been overwritten");
            }
        }
Exemplo n.º 16
0
        protected override void ProcessRecord()
        {
            int indexNo = 0;
            byte[] contentArray = null;

            #region Encoding

            System.Text.Encoding contentEncoding = System.Text.Encoding.Default;
            bool asBytes = false;

            if(this.MyInvocation.BoundParameters.ContainsKey("Encoding"))
            {
                if (encoding == Microsoft.PowerShell.Commands.FileSystemCmdletProviderEncoding.Ascii)
                {
                    contentEncoding = System.Text.Encoding.ASCII;
                }
                else if (encoding == Microsoft.PowerShell.Commands.FileSystemCmdletProviderEncoding.BigEndianUnicode)
                {
                    contentEncoding = System.Text.Encoding.BigEndianUnicode;
                }
                else if (encoding == Microsoft.PowerShell.Commands.FileSystemCmdletProviderEncoding.Byte)
                {
                    asBytes = true;
                }
                else if (encoding == Microsoft.PowerShell.Commands.FileSystemCmdletProviderEncoding.String)
                {
                    contentEncoding = System.Text.Encoding.Unicode;
                }
                else if (encoding == Microsoft.PowerShell.Commands.FileSystemCmdletProviderEncoding.Unicode)
                {
                    contentEncoding = System.Text.Encoding.Unicode;
                }
                else if (encoding == Microsoft.PowerShell.Commands.FileSystemCmdletProviderEncoding.Unknown)
                {
                    asBytes = true;
                }
                else if (encoding == Microsoft.PowerShell.Commands.FileSystemCmdletProviderEncoding.UTF7)
                {
                    contentEncoding = System.Text.Encoding.UTF7;
                }
                else if (encoding == Microsoft.PowerShell.Commands.FileSystemCmdletProviderEncoding.UTF8)
                {
                    contentEncoding = System.Text.Encoding.UTF8;
                }
            }

            #endregion Encoding

            if (this.MyInvocation.BoundParameters.ContainsKey("Path"))
            {
                string volLetter = filePath.Split('\\')[0];
                string volume = @"\\.\" + volLetter;
                indexNo = (int)IndexEntry.Get(filePath).RecordNumber;
                contentArray = new FileRecord(FileRecord.GetRecordBytes(volume, indexNo), volume, true).GetBytes();
            }

            else if(this.MyInvocation.BoundParameters.ContainsKey("IndexNumber"))
            {
                NativeMethods.getVolumeName(ref volume);
                contentArray = new FileRecord(FileRecord.GetRecordBytes(volume, index), volume, true).GetBytes();
            }

            if (asBytes)
            {
                WriteObject(contentArray);
            }
            else
            {
                string[] outputArray = contentEncoding.GetString(contentArray).Split('\n');

                if (this.MyInvocation.BoundParameters.ContainsKey("TotalCount") && this.MyInvocation.BoundParameters.ContainsKey("Tail"))
                {
                    throw new InvalidOperationException("The parameters TotalCount and Tail cannot be used together. Please specify only one parameter.");
                }
                else if (this.MyInvocation.BoundParameters.ContainsKey("TotalCount"))
                {
                    for (int i = 0; (i < totalCount) && (i < outputArray.Length); i++)
                    {
                        WriteObject(outputArray[i]);
                    }
                }
                else if (this.MyInvocation.BoundParameters.ContainsKey("Tail"))
                {
                    for (long i = tail; (i > 0); i--)
                    {
                        if (i > outputArray.Length)
                        {
                            i = outputArray.Length;
                        }

                        WriteObject(outputArray[outputArray.Length - i]);
                    }
                }
                else
                {
                    WriteObject(outputArray);
                }
            }
        }
Exemplo n.º 17
0
 internal static FileRecord GetFileRecord(string volume)
 {
     return(new FileRecord(FileRecord.GetRecordBytes(volume, VOLUME_INDEX), volume, true));
 }
Exemplo n.º 18
0
        internal static IndexEntry Get(string path)
        {
            string[] paths = path.TrimEnd('\\').Split('\\');

            // Determine Volume Name
            string volume = @"\\.\" + paths[0];

            // Test volume path
            NativeMethods.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);

                indexEntryList.Clear();

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

                            foreach (IndexEntry entry in IA.Entries)
                            {
                                if (entry.Entry.Namespace != 0x02)
                                {
                                    indexEntryList.Add(entry);
                                }
                            }
                        }
                    }
                }
                else
                {
                    return new IndexEntry(record);
                }
            }
            throw new Exception("The IndexEntry object for the specified path could not be found.");
        }
Exemplo n.º 19
0
        public static IndexEntry[] GetInstances(string path)
        {
            string[] paths = path.TrimEnd('\\').Split('\\');

            // Determine Volume Name
            string volume = @"\\.\" + paths[0];

            // Test volume path
            NativeMethods.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);

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

                            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();

                            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();
        }
Exemplo n.º 20
0
        public FileRecord(ref FileRecord[] array, byte[] recordBytes, 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);

                #region UpdateSequenceNumber

                byte[] usnBytes = new byte[2];
                Array.Copy(recordBytes, OffsetOfUS, usnBytes, 0, usnBytes.Length);
                UpdateSequenceNumber = BitConverter.ToUInt16(usnBytes, 0);

                #endregion UpdateSequenceNumber

                #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

                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)
                    {
                        sb.Append(array[(int)ParentRecordNumber].FullName);
                    }
                    // If record for Parent does not already exist then instantiate it and add it to the array
                    else
                    {
                        //Console.WriteLine("RecordIndex: {0}, ParentIndex: {1}", RecordNumber, ParentRecordNumber);
                        // This is where the recursive call should live...
                        //array[(int)ParentRecordNumber] = new FileRecord(ref array, FileRecord.GetRecordBytes(volume, (int)ParentRecordNumber), volume);
                        //sb.Append(array[(int)ParentRecordNumber].FullName);
                    }
                    // 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
            }
        }
Exemplo n.º 21
0
        public FileRecord(byte[] recordBytes, 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);

                #region UpdateSequenceNumber
                byte[] usnBytes = new byte[2];
                Array.Copy(recordBytes, OffsetOfUS, usnBytes, 0, usnBytes.Length);
                UpdateSequenceNumber = BitConverter.ToUInt16(usnBytes, 0);
                #endregion UpdateSequenceNumber

                #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

                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);
                    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
            }
        }
Exemplo n.º 22
0
 private IndexEntry(FileRecord record)
 {
     RecordNumber = record.RecordNumber;
     Filename = record.Name;
     FullName = record.FullName;
 }
Exemplo n.º 23
0
        public static FileRecord[] GetInstances(string volume)
        {
            IntPtr hVolume = NativeMethods.getHandle(volume);

            using (FileStream streamToRead = NativeMethods.getFileStream(hVolume))
            {
                // Get the FileRecord for the $MFT file
                //FileRecord mftRecord = new FileRecord(FileRecord.GetRecordBytes(volume, 0), volume);

                byte[] mftBytes = MasterFileTable.GetBytes(streamToRead, volume);

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

                // Calulate the number of entries in the MFT
                int fileCount = mftBytes.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(mftBytes, index * bytesPerFileRecord, recordBytes, 0, recordBytes.Length);

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

                        // Instantiate FileRecord object
                        recordArray[index] = new FileRecord(ref recordArray, recordBytes, volume);
                    }
                }
                return recordArray;
            }
        }
Exemplo n.º 24
0
 public byte[] GetBytes()
 {
     foreach (Attr attr in this.Attribute)
     {
         if (attr.Name == Attr.ATTR_TYPE.DATA)
         {
             if (attr.NonResident)
             {
                 return (attr as NonResident).GetBytes(this.VolumePath);
             }
             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);
                     return record.GetBytes();
                 }
             }
         }
     }
     throw new Exception("Could not locate file contents");
 }
Exemplo n.º 25
0
 internal static FileRecord GetFileRecord(string volume)
 {
     return new FileRecord(FileRecord.GetRecordBytes(volume, BADCLUS_INDEX), volume, true);
 }