private static Bitmap Get(string volume, int recordNumber, long cluster) { long sectorOffset = cluster / 4096; // Check for valid Volume name Helper.getVolumeName(ref volume); // Set up FileStream to read volume FileStream streamToRead = Helper.getFileStream(volume); // Get VolumeBootRecord object for logical addressing VolumeBootRecord VBR = VolumeBootRecord.Get(streamToRead); // Get the Data attribute NonResident dataStream = Bitmap.GetDataStream(FileRecord.Get(volume, recordNumber, true)); // Calulate the offset of the Bitmap file's data long dataRunOffset = dataStream.DataRun[0].StartCluster * VBR.BytesPerCluster; // Calculate the offset of the sector that contains the entry for the specific cluster long offset = dataRunOffset + (VBR.BytesPerSector * sectorOffset); // Read appropriate sector byte[] bytes = Helper.readDrive(streamToRead, offset, VBR.BytesPerSector); return(Get(bytes, cluster)); }
/// <summary> /// /// </summary> /// <param name="volume"></param> /// <returns></returns> public static Bitmap[] GetInstances(string volume) { // Get the proper data stream from the FileRecord NonResident dataStream = Bitmap.GetDataStream(FileRecord.Get(volume, MftIndex.BITMAP_INDEX, true)); // Call GetInstances to return all associated Bitmap Values return(GetInstances(dataStream.GetBytes())); }
private static UsnJrnl[] GetInstances(string volume, int recordnumber) { // Get VolumeBootRecord object for logical addressing VolumeBootRecord VBR = VolumeBootRecord.Get(volume); // Get FileRecord for C:\$Extend\$UsnJrnl FileRecord record = FileRecord.Get(volume, recordnumber, true); // Get the $J Data attribute (contains UsnJrnl records) NonResident J = UsnJrnl.GetJStream(record); // Instatiate a List of UsnJrnl entries List <UsnJrnl> usnList = new List <UsnJrnl>(); for (int i = 0; i < J.DataRun.Length; i++) { if (!(J.DataRun[i].Sparse)) { long clusterCount = J.DataRun[i].ClusterLength; byte[] fragmentBytes = Helper.readDrive(volume, (J.DataRun[i].StartCluster * VBR.BytesPerCluster), (clusterCount * VBR.BytesPerCluster)); byte[] clusterBytes = new byte[VBR.BytesPerCluster]; for (int j = 0; j < clusterCount; j++) { Array.Copy(fragmentBytes, (int)(j * VBR.BytesPerCluster), clusterBytes, 0, clusterBytes.Length); int offset = 0; do { if (clusterBytes[offset] == 0) { break; } try { UsnJrnl usn = new UsnJrnl(clusterBytes, volume, ref offset); if (usn.Version > USN40Version) { break; } usnList.Add(usn); } catch { break; } } while (offset >= 0 && offset < clusterBytes.Length); } } } // Return usnList as a UsnJrnl[] return(usnList.ToArray()); }
private static byte[] GetRecordBytesPrivate(string volume, int index) { // Get filestream based on hVolume using (FileStream streamToRead = Helper.getFileStream(volume)) { // Get Volume Boot Record NtfsVolumeBootRecord VBR = VolumeBootRecord.Get(streamToRead) as NtfsVolumeBootRecord; // Determine start of MFT long mftStartOffset = VBR.MftStartIndex * VBR.BytesPerCluster; // Get FileRecord for $MFT FileRecord mftRecord = MasterFileTable.GetRecord(streamToRead, volume); // Get $MFT Data Attribute NonResident data = null; foreach (FileRecordAttribute attr in mftRecord.Attribute) { if (attr.Name == FileRecordAttribute.ATTR_TYPE.DATA) { data = attr as NonResident; break; } } // Iterate through fragments of the MFT foreach (DataRun dr in data.DataRun) { long DataRunRecords = (dr.ClusterLength * VBR.BytesPerCluster) / VBR.BytesPerFileRecord; // Check if index can be found in current DataRun if (index < (int)DataRunRecords) { long recordOffset = (dr.StartCluster * VBR.BytesPerCluster) + (index * VBR.BytesPerFileRecord); byte[] recordBytesRaw = Helper.readDrive(streamToRead, recordOffset, VBR.BytesPerFileRecord); ApplyFixup(ref recordBytesRaw, (int)VBR.BytesPerFileRecord); return(recordBytesRaw); } // Decrement index for the number of FileRecords in the current DataRun else { index -= ((int)dr.ClusterLength * VBR.BytesPerCluster) / (int)VBR.BytesPerFileRecord; } } throw new Exception("Could not find the FileRecord requested..."); } }
/// <summary> /// The ProcessRecord method calls ManagementClass.GetInstances() /// method to iterate through each BindingObject on each system specified. /// </summary> protected override void ProcessRecord() { Regex lettersOnly = new Regex("^[a-zA-Z]{1}$"); if (lettersOnly.IsMatch(volume)) { volume = @"\\.\" + volume + ":"; } IntPtr hVolume = NativeMethods.getHandle(volume); FileStream streamToRead = NativeMethods.getFileStream(hVolume); VolumeData volData = new VolumeData(hVolume); MFTRecord record = MFTRecord.Get(MasterFileTable.GetBytes(volume), 4, null, null); List <byte> bytes = new List <byte>(); foreach (Attr attr in record.Attribute) { if (attr.Name == "DATA") { if (attr.NonResident) { NonResident data = attr as NonResident; for (int i = 0; i < data.StartCluster.Length; i++) { ulong offset = data.StartCluster[i] * (ulong)volData.BytesPerCluster; ulong length = (data.EndCluster[i] - data.StartCluster[i]) * (ulong)volData.BytesPerCluster; byte[] byteRange = Win32.NativeMethods.readDrive(streamToRead, offset, length); bytes.AddRange(byteRange); } } else { Data data = attr as Data; bytes.AddRange(data.RawData); } } } for (int i = 0; (i < bytes.ToArray().Length) && (bytes.ToArray()[i] != 0); i += 160) { byte[] attrDefBytes = bytes.Skip(i).Take(160).ToArray(); WriteObject(new AttrDef(attrDefBytes)); } streamToRead.Close(); } // ProcessRecord
/// <summary> /// /// </summary> /// <param name="path"></param> /// <returns></returns> public static Bitmap[] GetInstancesByPath(string path) { // Get Volume string from specified path string volume = Helper.GetVolumeFromPath(path); // Determine Record Number for specified file IndexEntry entry = IndexEntry.Get(path); // Get the proper data stream from the FileRecord NonResident dataStream = Bitmap.GetDataStream(FileRecord.Get(volume, MftIndex.BITMAP_INDEX, true)); // Call GetInstances to return all associated Bitmap Values return(GetInstances(dataStream.GetBytes())); }
/// <summary> /// /// </summary> /// <returns></returns> public override string ToString() { if (this.Directory) { if (this.Deleted) { return(String.Format("[Directory] {0} (deleted)", this.FullName)); } else { return(String.Format("[Directory] {0}", this.FullName)); } } else { ulong size = 0; foreach (FileRecordAttribute a in this.Attribute) { if (a.Name == FileRecordAttribute.ATTR_TYPE.DATA) { if (a.NonResident) { NonResident d = a as NonResident; size = d.RealSize; break; } else { Data data = a as Data; size = (ulong)data.RawData.Length; break; } } } if (this.Deleted) { return(String.Format("[{0}] {1} (deleted)", size, this.FullName)); } else { return(String.Format("[{0}] {1}", size, this.FullName)); } } }
protected override void ProcessRecord() { // 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); NonResident Bad = BadClus.GetBadStream(BadClus.GetFileRecord(volume)); foreach (DataRun d in Bad.DataRun) { if (!(d.Sparse)) { WriteObject(new BadClus(d.StartCluster, true)); } } } // ProcessRecord
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"); } }