Exemplo n.º 1
0
        public static UsnJrnl[] GetInstances(string volume)
        {
            // Check for valid Volume name
            NativeMethods.getVolumeName(ref volume);

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

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

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

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

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

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

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

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

                        int offset = 0;

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

                            try
                            {
                                UsnJrnl usn = new UsnJrnl(clusterBytes, volume, ref offset);
                                if (usn.Version > USN40Version)
                                {
                                    break;
                                }
                                usnList.Add(usn);
                            }
                            catch
                            {
                                break;
                            }
                        } while (offset >= 0 && offset < clusterBytes.Length);
                    }
                }
            }
            return(usnList.ToArray());
        }
        public static FileRecord GetRecord(FileStream streamToRead, string volume)
        {
            // Instantiate VolumeBootRecord object
            VolumeBootRecord VBR = VolumeBootRecord.Get(streamToRead);

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

            // Read bytes belonging to specified MFT Record and store in byte array
            return(new FileRecord(NativeMethods.readDrive(streamToRead, mftOffset, (ulong)VBR.BytesPerFileRecord), volume, true));
        }
Exemplo n.º 3
0
        public static byte[] GetRecordBytes(string volume, int index)
        {
            // Get handle for volume
            IntPtr hVolume = NativeMethods.getHandle(volume);

            // Get filestream based on hVolume
            using (FileStream streamToRead = NativeMethods.getFileStream(hVolume))
            {
                // Get Volume Boot Record
                Ntfs.VolumeBootRecord VBR = VolumeBootRecord.Get(streamToRead);

                // Determine start of MFT
                ulong mftStartOffset = VBR.MFTStartIndex * VBR.BytesPerCluster;

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

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

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

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

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

                        ApplyFixup(ref recordBytesRaw);

                        return(recordBytesRaw);
                    }

                    // Decrement index for the number of FileRecords in the current DataRun
                    else
                    {
                        index -= ((int)dr.ClusterLength * (int)VBR.BytesPerCluster) / (int)VBR.BytesPerFileRecord;
                    }
                }
                throw new Exception("Could not find the FileRecord requested...");
            }
        }
Exemplo n.º 4
0
        public static byte[] getBytes(string volume)
        {
            // Get handle for volume
            IntPtr hVolume = NativeMethods.getHandle(volume);

            // Get filestream based on hVolume
            using (FileStream streamToRead = NativeMethods.getFileStream(hVolume))
            {
                VolumeBootRecord VBR = VolumeBootRecord.Get(streamToRead);

                FileRecord logFileRecord = GetFileRecord(volume);

                NonResident data = GetDataAttr(logFileRecord);

                return(data.GetBytes(volume));
            }
        }
Exemplo n.º 5
0
        public byte[] GetBytes(string volume)
        {
            byte[] fileBytes = new byte[this.RealSize];

            int offset = 0;

            NativeMethods.getVolumeName(ref volume);
            IntPtr hVolume = NativeMethods.getHandle(volume);

            using (FileStream streamToRead = NativeMethods.getFileStream(hVolume))
            {
                VolumeBootRecord VBR = VolumeBootRecord.Get(streamToRead);

                foreach (DataRun dr in this.DataRun)
                {
                    if (dr.Sparse)
                    {
                        // Figure out how to add Sparse Bytes
                    }
                    else
                    {
                        ulong  startOffset  = (ulong)VBR.BytesPerCluster * (ulong)dr.StartCluster;
                        ulong  count        = (ulong)VBR.BytesPerCluster * (ulong)dr.ClusterLength;
                        byte[] dataRunBytes = NativeMethods.readDrive(streamToRead, startOffset, count);

                        if (((ulong)offset + count) <= (ulong)fileBytes.Length)
                        {
                            // Save dataRunBytes to fileBytes
                            Array.Copy(dataRunBytes, 0, fileBytes, offset, dataRunBytes.Length);

                            // Increment Offset Value
                            offset += dataRunBytes.Length;
                        }
                        else
                        {
                            Array.Copy(dataRunBytes, 0, fileBytes, offset, (fileBytes.Length - offset));
                            break;
                        }
                    }
                }
                return(fileBytes);
            }
        }
Exemplo n.º 6
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.º 7
0
        public static UsnJrnl Get(string volume, ulong usn)
        {
            // Check for valid Volume name
            NativeMethods.getVolumeName(ref volume);

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

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

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

            // Determine the length of the initial sparse pages
            ulong SparseLength = (ulong)J.DataRun[0].ClusterLength * VBR.BytesPerCluster;
            // Subtract length of sparse data from desired usn offset
            ulong usnOffset = usn - SparseLength;

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

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

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

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

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

                            // Parse desired UsnJrnl entry from cluster
                            int offset = (int)usnOffset;
                            return(new UsnJrnl(clusterBytes, volume, ref offset));
                        }
                    }
                }
            }
            return(null);
        }
Exemplo n.º 8
0
        internal static Bitmap Get(string volume, ulong cluster)
        {
            ulong sectorOffset = cluster / 4096;
            ulong byteOffset   = (cluster % 4096) / 8;

            // Check for valid Volume name
            NativeMethods.getVolumeName(ref volume);

            IntPtr hVolume = NativeMethods.getHandle(volume);

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

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

            // Get the Data attribute
            NonResident dataStream = Bitmap.GetDataStream(Bitmap.GetFileRecord(volume));

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

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

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

            byte b = bytes[byteOffset];

            bool inUse = false;

            switch (cluster % 8)
            {
            case 0:
                if ((b & 0x01) > 0)
                {
                    inUse = true;
                }
                break;

            case 1:
                if ((b & 0x02) > 0)
                {
                    inUse = true;
                }
                break;

            case 2:
                if ((b & 0x04) > 0)
                {
                    inUse = true;
                }
                break;

            case 3:
                if ((b & 0x08) > 0)
                {
                    inUse = true;
                }
                break;

            case 4:
                if ((b & 0x10) > 0)
                {
                    inUse = true;
                }
                break;

            case 5:
                if ((b & 0x20) > 0)
                {
                    inUse = true;
                }
                break;

            case 6:
                if ((b & 0x40) > 0)
                {
                    inUse = true;
                }
                break;

            case 7:
                if ((b & 0x80) > 0)
                {
                    inUse = true;
                }
                break;
            }
            return(new Bitmap(cluster, inUse));
        }
Exemplo n.º 9
0
        internal static Bitmap[] GetInstances(string volume)
        {
            // Check for valid Volume name
            NativeMethods.getVolumeName(ref volume);

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

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

            // Get the Data attribute
            NonResident dataStream = Bitmap.GetDataStream(Bitmap.GetFileRecord(volume));

            byte[] bytes = NativeMethods.readDrive(streamToRead, ((ulong)dataStream.DataRun[0].StartCluster * VBR.BytesPerCluster), ((ulong)dataStream.DataRun[0].ClusterLength * VBR.BytesPerCluster));

            Bitmap[] bitmapArray = new Bitmap[bytes.Length * 8];

            for (int j = 0; j < bytes.Length; j++)
            {
                for (int k = 0; k < 8; k++)
                {
                    bool inUse = false;
                    int  index = ((j * 8) + k);

                    switch (k)
                    {
                    case 0:
                        if ((bytes[j] & 0x01) > 0)
                        {
                            inUse = true;
                        }
                        break;

                    case 1:
                        if ((bytes[j] & 0x02) > 0)
                        {
                            inUse = true;
                        }
                        break;

                    case 2:
                        if ((bytes[j] & 0x04) > 0)
                        {
                            inUse = true;
                        }
                        break;

                    case 3:
                        if ((bytes[j] & 0x08) > 0)
                        {
                            inUse = true;
                        }
                        break;

                    case 4:
                        if ((bytes[j] & 0x10) > 0)
                        {
                            inUse = true;
                        }
                        break;

                    case 5:
                        if ((bytes[j] & 0x20) > 0)
                        {
                            inUse = true;
                        }
                        break;

                    case 6:
                        if ((bytes[j] & 0x40) > 0)
                        {
                            inUse = true;
                        }
                        break;

                    case 7:
                        if ((bytes[j] & 0x80) > 0)
                        {
                            inUse = true;
                        }
                        break;
                    }
                    bitmapArray[index] = new Bitmap((ulong)index, inUse);
                }
            }

            return(bitmapArray);
        }