/// <summary> /// /// </summary> /// <param name="volume"></param> /// <param name="index"></param> /// <returns></returns> private static byte[] GetRecordBytesPrivate(string volume, int index) { // Get filestream based on hVolume using (FileStream streamToRead = Helper.getFileStream(volume)) { // Get Volume Boot Record VolumeBootRecord VBR = VolumeBootRecord.Get(streamToRead); // 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..."); } }
internal static FileRecord GetRecord(FileStream streamToRead, string volume) { // Instantiate VolumeBootRecord object VolumeBootRecord VBR = VolumeBootRecord.Get(streamToRead); // Calculate byte offset to the Master File Table (MFT) long mftOffset = (VBR.BytesPerCluster * VBR.MftStartIndex); // Read bytes belonging to specified MFT Record byte[] recordBytes = Helper.readDrive(streamToRead, mftOffset, VBR.BytesPerFileRecord); // Instantiate a FileRecord object for the $MFT file return(FileRecord.Get(recordBytes, volume, (int)VBR.BytesPerFileRecord, true)); }
/// <summary> /// /// </summary> /// <param name="volume"></param> /// <returns></returns> public static byte[] getBytes(string volume) { // Get filestream based on hVolume using (FileStream streamToRead = Helper.getFileStream(volume)) { VolumeBootRecord VBR = VolumeBootRecord.Get(streamToRead); FileRecord logFileRecord = GetFileRecord(volume); NonResident data = GetDataAttr(logFileRecord); return(data.GetBytes()); } }
public static byte[] getBytes(string volume) { // Get handle for volume IntPtr hVolume = Util.getHandle(volume); // Get filestream based on hVolume using (FileStream streamToRead = Util.getFileStream(hVolume)) { VolumeBootRecord VBR = VolumeBootRecord.Get(streamToRead); FileRecord logFileRecord = GetFileRecord(volume); NonResident data = GetDataAttr(logFileRecord); return(data.GetBytes(volume)); } }
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); } }
/// <summary> /// /// </summary> /// <param name="volume"></param> /// <returns></returns> public byte[] GetBytes() { byte[] fileBytes = new byte[this.RealSize]; int offset = 0; Helper.getVolumeName(ref this.Volume); using (FileStream streamToRead = Helper.getFileStream(this.Volume)) { VolumeBootRecord VBR = VolumeBootRecord.Get(streamToRead); foreach (DataRun dr in this.DataRun) { if (dr.Sparse) { // Figure out how to add Sparse Bytes } else { long startOffset = VBR.BytesPerCluster * dr.StartCluster; long count = VBR.BytesPerCluster * dr.ClusterLength; byte[] dataRunBytes = Helper.readDrive(streamToRead, startOffset, count); if ((offset + count) <= fileBytes.Length) { // Save dataRunBytes to fileBytes Array.Copy(dataRunBytes, 0x00, fileBytes, offset, dataRunBytes.Length); // Increment Offset Value offset += dataRunBytes.Length; } else { Array.Copy(dataRunBytes, 0x00, fileBytes, offset, (fileBytes.Length - offset)); break; } } } return(fileBytes); } }
/// <summary> /// /// </summary> /// <param name="path"></param> /// <returns></returns> public static UsnJrnl[] GetTestInstances(string path) { byte[] bytes = FileRecord.GetContentBytes(path, "$J"); string volume = Helper.GetVolumeFromPath(path); VolumeBootRecord VBR = VolumeBootRecord.Get(volume); List <UsnJrnl> usnList = new List <UsnJrnl>(); for (int i = 0; i < bytes.Length; i += VBR.BytesPerCluster) { int clusteroffset = i; do { // Break if there are no more UsnJrnl entries in cluster if (bytes[clusteroffset] == 0) { break; } try { UsnJrnl usn = new UsnJrnl(bytes, volume, ref clusteroffset); if (usn.Version > USN40Version) { break; } usnList.Add(usn); } catch { break; } } while (clusteroffset >= 0 && clusteroffset < bytes.Length); } return(usnList.ToArray()); }
// TODO: Add Encoding parameter // TODO: Add DataStream parameter #region GetContentMethods public byte[] GetContent() { foreach (FileRecordAttribute attr in this.Attribute) { if (attr.Name == FileRecordAttribute.ATTR_TYPE.DATA) { if (attr.NameString == "") { if (attr.NonResident) { return((attr as NonResident).GetBytes(this.VolumePath)); } else { return((attr as Data).RawData); } } } else if (attr.Name == FileRecordAttribute.ATTR_TYPE.ATTRIBUTE_LIST) { VolumeBootRecord vbr = VolumeBootRecord.Get(this.VolumePath); AttributeList attrlist = attr as AttributeList; foreach (AttrRef ar in attrlist.AttributeReference) { if (ar.Name == "DATA") { if (ar.NameString == "") { FileRecord record = new FileRecord(FileRecord.GetRecordBytes(this.VolumePath, (int)ar.RecordNumber), this.VolumePath, (int)vbr.BytesPerFileRecord, true); return(record.GetContent()); } } } } } throw new Exception("Could not locate file contents"); }
public byte[] GetTestContent(string streamName) { foreach (FileRecordAttribute attr in this.Attribute) { if (attr.Name == FileRecordAttribute.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) { VolumeBootRecord vbr = VolumeBootRecord.Get(this.VolumePath); foreach (AttrRef ar in attrList.AttributeReference) { if (ar.Name == "DATA") { FileRecord record = new FileRecord(FileRecord.GetRecordBytes(this.VolumePath, (int)ar.RecordNumber), this.VolumePath, (int)vbr.BytesPerFileRecord, true); return(record.GetTestContent(streamName)); } } } } throw new Exception("Could not locate desired stream"); }
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"); }
private static UsnJrnl[] GetInstances(string volume, int recordnumber) { // 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); 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 = 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()); }
private static UsnJrnl Get(string volume, int recordnumber, 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); 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 ulong SparseLength = (ulong)J.DataRun[0].ClusterLength * VBR.BytesPerCluster; if (usn > SparseLength) { // 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); } else { throw new Exception("UsnJrnl entry has has been overwritten"); } }
/// <summary> /// /// </summary> /// <returns></returns> public byte[] GetBytes() { VolumeBootRecord vbr = VolumeBootRecord.Get(this.Volume); return(Helper.readDrive(this.Volume, this.StartCluster * vbr.BytesPerCluster, this.ClusterLength * vbr.BytesPerCluster)); }
internal byte[] GetBytes(string volume, VolumeBootRecord VBR) { byte[] fileBytes = new byte[this.RealSize]; int offset = 0; NativeMethods.getVolumeName(ref volume); IntPtr hVolume = NativeMethods.getHandle(volume); using (FileStream streamToRead = NativeMethods.getFileStream(hVolume)) { 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; } }
public byte[] GetBytes(string volume) { VolumeBootRecord vbr = VolumeBootRecord.Get(volume); return(Helper.readDrive(volume, (ulong)this.StartCluster * vbr.BytesPerCluster, (ulong)this.ClusterLength * vbr.BytesPerCluster)); }