Пример #1
0
        internal static byte[] getFile(string volume, int index)
        {
            byte[] mftBytes = MasterFileTable.GetBytes(volume);

            // Get the FileRecord (MFT Record Entry) for the given inode on the specified volume
            MFTRecord MFTRecord = MFTRecord.Get(mftBytes, index, null, null);

            if (!(MFTRecord.Directory))
            {
                foreach (Attr attr in MFTRecord.Attribute)
                {
                    if (attr.Name == "DATA")
                    {
                        if (attr.NonResident == true)
                        {
                            NonResident nonResAttr = (NonResident)attr;
                            return(NonResident.GetContent(volume, nonResAttr).ToArray());
                        }
                        else
                        {
                            Data dataAttr = (Data)attr;
                            return(dataAttr.RawData);
                        }
                    }
                }
            }
            return(null);
        }
Пример #2
0
        // Get Master File Table Bytes for "Get" Methods
        // GetBytes will clean up IntPtr (Volume Handle) and FileStream objects
        public static byte[] GetBytes(string volume)
        {
            // Get a handle to the specified volume
            IntPtr hVolume = NativeMethods.getHandle(volume);

            // Instatiate null byte array
            byte[] mftBytes = null;

            // Create FileStream to read from the Volume file handle
            using (FileStream streamToRead = NativeMethods.getFileStream(hVolume))
            {
                // Instantiate VolumeData object
                VolumeData volData = new VolumeData(hVolume);

                // Calculate byte offset to the Master File Table (MFT)
                ulong mftOffset = ((ulong)volData.BytesPerCluster * volData.MFTStartCluster);

                // Read bytes belonging to specified MFT Record and store in byte array
                MFTRecord mftRecord = new MFTRecord(NativeMethods.readDrive(streamToRead, mftOffset, (ulong)volData.BytesPerMFTRecord));

                mftBytes = MFTRecord.getFile(streamToRead, mftRecord);
            }

            NativeMethods.CloseHandle(hVolume);

            // Return byte array representing the Master File Table
            return(mftBytes);
        }
Пример #3
0
        // I think these belong elsewhere
        #region getFile

        internal static List <byte> getFile(string volume, FileStream streamToRead, byte[] MFT, string fileName)
        {
            string volLetter = volume.TrimStart('\\').TrimStart('.').TrimStart('\\') + '\\';

            int inode = IndexNumber.Get(streamToRead, MFT, fileName);

            // Get the FileRecord (MFT Record Entry) for the given inode on the specified volume
            MFTRecord MFTRecord = MFTRecord.Get(MFT, inode, volLetter, fileName);

            if (!(MFTRecord.Directory))
            {
                foreach (Attr attr in MFTRecord.Attribute)
                {
                    if (attr.Name == "DATA")
                    {
                        if (attr.NonResident == true)
                        {
                            NonResident nonResAttr = (NonResident)attr;
                            return(NonResident.GetContent(volume, nonResAttr));
                        }

                        else
                        {
                            Data dataAttr = (Data)attr;
                            return(null);
                            //return dataAttr.RawData;
                        }
                    }
                }
            }

            return(null);
        }
Пример #4
0
        // Get Master File Table Bytes for "GetInstance" Functions
        // Caller is responsible for cleaning up streamToRead and hVolume
        public static byte[] GetBytes(IntPtr hVolume, FileStream streamToRead)
        {
            // Instantiate VolumeData object
            VolumeData volData = new VolumeData(hVolume);

            // Calculate byte offset to the Master File Table (MFT)
            ulong mftOffset = ((ulong)volData.BytesPerCluster * volData.MFTStartCluster);

            // Read bytes belonging to specified MFT Record and store in byte array
            MFTRecord mftRecord = new MFTRecord(NativeMethods.readDrive(streamToRead, mftOffset, (ulong)volData.BytesPerMFTRecord));

            // Return byte array representing the Master File Table
            return(MFTRecord.getFile(streamToRead, mftRecord));
        }
Пример #5
0
        public static byte[] getBytes(string volume)
        {
            byte[] mftBytes = MasterFileTable.GetBytes(volume);

            MFTRecord logFileRecord = MFTRecord.Get(mftBytes, 2, null, null);

            NonResident data = null;

            foreach (Attr attr in logFileRecord.Attribute)
            {
                if (attr.Name == "DATA")
                {
                    data = attr as NonResident;
                    break;
                }
            }

            return((NonResident.GetContent(volume, data)).ToArray());
        }
Пример #6
0
        internal static AttrDef[] GetInstances(string volumeName)
        {
            // Get correct volume name from user input
            NativeMethods.getVolumeName(ref volumeName);

            // Get handle to Logical Volume
            IntPtr hVolume = NativeMethods.getHandle(volumeName);

            // Instantiate a List of AttrDef objects for output
            List <AttrDef> adList = new List <AttrDef>();

            // Create a FileStream object for the Volume
            using (FileStream streamToRead = NativeMethods.getFileStream(hVolume))
            {
                // Instantiate a VolumeData object
                VolumeData volData = new VolumeData(hVolume);

                ulong attrDefOffset = ((volData.MFTStartCluster * (ulong)volData.BytesPerCluster) + ((ulong)volData.BytesPerMFTRecord * 4));

                // Get the MFTRecord for the file with a record index of 4 ($AttrDef)
                MFTRecord record = new MFTRecord(NativeMethods.readDrive(streamToRead, attrDefOffset, (ulong)volData.BytesPerMFTRecord));

                // Get the content of the $AttrDef file in a byte array
                byte[] bytes = MFTRecord.getFile(streamToRead, record);

                // Iterate through 160 byte chunks (representing an AttrDef object)
                for (int i = 0; (i < bytes.Length) && (bytes[i] != 0); i += 160)
                {
                    byte[] attrDefBytes = new byte[160];

                    Array.Copy(bytes, i, attrDefBytes, 0, attrDefBytes.Length);

                    // Intantiate a new AttrDef object and add it to the adList List of AttrDef objects
                    adList.Add(new AttrDef(attrDefBytes));
                }
            }

            NativeMethods.CloseHandle(hVolume);

            // Return an array of AttrDef objects
            return(adList.ToArray());
        }
Пример #7
0
        // Get all MFT Records from the MFT byte array
        internal static MFTRecord[] GetInstances(byte[] mftBytes, string volLetter)
        {
            // Determine number of MFT Records (each record is 1024 bytes)
            // Create an array large enough to hold each MFT Record
            int recordCount = mftBytes.Length / 1024;

            MFTRecord[] recordArray = new MFTRecord[recordCount];

            // Iterate through each index number and add MFTRecord to MFTRecord[]
            for (int i = 0; i < mftBytes.Length; i += 1024)
            {
                int index = i / 1024;
                if (recordArray[index] == null)
                {
                    recordArray[index] = new MFTRecord(mftBytes, index, ref recordArray, volLetter);
                }
            }

            // Return MFTRecord[]
            return(recordArray);
        }
Пример #8
0
 internal static byte[] getFile(FileStream streamToRead, MFTRecord mftRecord)
 {
     if (!(mftRecord.Directory))
     {
         foreach (Attr attr in mftRecord.Attribute)
         {
             if (attr.Name == "DATA")
             {
                 if (attr.NonResident == true)
                 {
                     NonResident nonResAttr = attr as NonResident;
                     return(NonResident.GetContent(streamToRead, nonResAttr));
                 }
                 else
                 {
                     Data dataAttr = attr as Data;
                     return(dataAttr.RawData);
                 }
             }
         }
     }
     return(null);
 }
Пример #9
0
        internal MFTRecord(byte[] mftBytes, int index, ref MFTRecord[] recordArray, string volLetter)
        {
            // Get byte array representing current record
            byte[] recordBytes = getMFTRecordBytes(mftBytes, index);

            // Instantiate a FILE_RECORD_HEADER struct from raw MFT Record bytes
            FILE_RECORD_HEADER RecordHeader = new FILE_RECORD_HEADER(recordBytes);

            // Check MFT Signature (FILE) to ensure bytes actually represent an MFT Record
            if (checkMFTRecord(RecordHeader.Magic))
            {
                RecordNumber          = RecordHeader.RecordNo;
                Size                  = RecordHeader.RealSize;
                SequenceNumber        = RecordHeader.SeqNo;
                LogFileSequenceNumber = RecordHeader.LSN;
                Links                 = RecordHeader.Hardlinks;

                // Unmask Header Flags
                #region HeaderFlags

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

                #endregion HeaderFlags

                List <Attr> AttributeList = new List <Attr>();
                int         offsetToATTR  = RecordHeader.OffsetOfAttr;

                while (offsetToATTR < (RecordHeader.RealSize - 8))
                {
                    //sw.Start();
                    int  offset = offsetToATTR;
                    Attr attr   = AttributeFactory.Get(recordBytes, offset, out offsetToATTR);
                    if (attr != null)
                    {
                        if (attr.Name == "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 == "FILE_NAME")
                        {
                            FileName fN = attr as FileName;
                            if (!(fN.Filename.Contains("~")))
                            {
                                Name        = fN.Filename;
                                ParentIndex = fN.ParentIndex;
                            }
                        }
                        AttributeList.Add(attr);
                    }
                }
                // Check if MFT Record is for the root directory (should be Record Index 5)
                // If index and ParentIndex are not the same then get FullPath
                if ((ulong)index != ParentIndex)
                {
                    // Check if ParentIndex Record has already been constructed and added to array
                    if (recordArray[ParentIndex] == null)
                    {
                        recordArray[ParentIndex] = new MFTRecord(mftBytes, (int)ParentIndex, ref recordArray, volLetter);
                    }
                    // FullPath equals the ParentIndex FullPath + the current Index Name
                    // Make more efficient with String Builder
                    FullPath = recordArray[ParentIndex].FullPath + Name;
                    if (Directory)
                    {
                        FullPath += "\\";
                    }
                }
                else
                {
                    FullPath = volLetter;
                }
                Attribute = AttributeList.ToArray();
            }
            else
            {
            }
        }
Пример #10
0
        internal MFTRecord(byte[] mftBytes, int index, string volLetter, string fileName)
        {
            byte[] recordBytes = getMFTRecordBytes(mftBytes, index);

            // Instantiate a FILE_RECORD_HEADER struct from raw MFT Record bytes
            FILE_RECORD_HEADER RecordHeader = new FILE_RECORD_HEADER(recordBytes);

            // Check MFT Signature (FILE) to ensure bytes actually represent an MFT Record
            if (checkMFTRecord(RecordHeader.Magic))
            {
                RecordNumber          = RecordHeader.RecordNo;
                Size                  = RecordHeader.RealSize;
                SequenceNumber        = RecordHeader.SeqNo;
                LogFileSequenceNumber = RecordHeader.LSN;
                Links                 = RecordHeader.Hardlinks;

                // Unmask Header Flags
                #region HeaderFlags

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

                #endregion HeaderFlags

                List <Attr> AttributeList = new List <Attr>();
                int         offsetToATTR  = RecordHeader.OffsetOfAttr;

                while (offsetToATTR < (RecordHeader.RealSize - 8))
                {
                    int  offset = offsetToATTR;
                    Attr attr   = AttributeFactory.Get(recordBytes, offset, out offsetToATTR);
                    if (attr != null)
                    {
                        if (attr.Name == "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 == "FILE_NAME")
                        {
                            FileName fN = attr as FileName;
                            if (!(fN.Filename.Contains("~")))
                            {
                                Name        = fN.Filename;
                                ParentIndex = fN.ParentIndex;
                            }
                        }
                        AttributeList.Add(attr);
                    }
                }

                Attribute = AttributeList.ToArray();

                if (RecordNumber == ParentIndex)
                {
                    FullPath = volLetter;
                }
                else
                {
                    if (fileName != null)
                    {
                        FullPath = fileName;
                    }
                    else
                    {
                        MFTRecord parent = new MFTRecord(mftBytes, (int)ParentIndex, volLetter, fileName);
                        FullPath = parent.FullPath + Name;
                    }
                    if (Directory)
                    {
                        FullPath += '\\';
                    }
                }
            }
        }
Пример #11
0
        internal static List<IndexEntry> Get(FileStream streamToRead, byte[] MFT, int index)
        {

            MFTRecord fileRecord = MFTRecord.Get(MFT, index, null, null);

            NonResident INDX = null;

            Console.WriteLine("Count: {0}", fileRecord.Attribute.Length);

            foreach (Attr attr in fileRecord.Attribute)
            {

                if (attr.Name == "INDEX_ALLOCATION")
                {

                    if (attr.NonResident)
                    {

                        INDX = (NonResident)attr;

                    }

                }

            }

            byte[] nonResBytes = NonResident.GetContent(streamToRead, INDX);

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

            for (int offset = 0; offset < nonResBytes.Length; offset += 4096)
            {

                byte[] indxBytes = nonResBytes.Skip(offset).Take(4096).ToArray();

                INDEX_BLOCK indxBlock = new INDEX_BLOCK(indxBytes.Take(40).ToArray());

                byte[] IndexAllocEntryBytes = indxBytes.Skip(64).ToArray();

                int offsetIndx = 0;
                int offsetIndxPrev = 1;

                while ((offsetIndx < IndexAllocEntryBytes.Length) && (offsetIndx != offsetIndxPrev))
                {

                    INDEX_ENTRY indxEntryStruct = new INDEX_ENTRY(IndexAllocEntryBytes.Skip(offsetIndx).ToArray());

                    offsetIndxPrev = offsetIndx;
                    offsetIndx += indxEntryStruct.Size;
                    if (indxEntryStruct.Stream.Length > 66)
                    {

                        FileName.ATTR_FILE_NAME fileNameStruct = new FileName.ATTR_FILE_NAME(indxEntryStruct.Stream);

                        #region indxFlags

                        StringBuilder indxFlags = new StringBuilder();
                        if (indxEntryStruct.Flags != 0)
                        {
                            if ((indxEntryStruct.Flags & (int)INDEX_ENTRY_FLAG.SUBNODE) == (int)INDEX_ENTRY_FLAG.SUBNODE)
                            {
                                indxFlags.Append("Subnode, ");
                            }
                            if ((indxEntryStruct.Flags & (int)INDEX_ENTRY_FLAG.LAST) == (int)INDEX_ENTRY_FLAG.LAST)
                            {
                                indxFlags.Append("Last Entry, ");
                            }
                            indxFlags.Length -= 2;
                        }

                        #endregion indxFlags

                        string Name = System.Text.Encoding.Unicode.GetString(fileNameStruct.Name);
                        IndexEntry indxEntry = new IndexEntry(indxEntryStruct, indxFlags.ToString(), Name);
                        indxEntryList.Add(indxEntry);

                    }

                }

            }

            return indxEntryList;
        }