private static FileRecord[] GetInstances(byte[] bytes, string volume, bool fast) { NtfsVolumeBootRecord vbr = VolumeBootRecord.Get(volume) as NtfsVolumeBootRecord; // Determine the size of an MFT File Record int bytesPerFileRecord = (int)vbr.BytesPerFileRecord; // Calulate the number of entries in the MFT int fileCount = bytes.Length / bytesPerFileRecord; // Instantiate an array of FileRecord objects FileRecord[] recordArray = new FileRecord[fileCount]; // Apply fixup values across MFT Bytes ApplyFixup(ref bytes, bytesPerFileRecord); // Now we need to iterate through all possible index values for (int index = 0x00; index < fileCount; index++) { // Check if current record has been instantiated if (recordArray[index] == null) { // Instantiate FileRecord object recordArray[index] = new FileRecord(ref recordArray, bytes, index * bytesPerFileRecord, bytesPerFileRecord, volume, fast); } } return(recordArray); }
internal static FileRecord Get(string volume, int index, bool fast) { NtfsVolumeBootRecord vbr = VolumeBootRecord.Get(volume) as NtfsVolumeBootRecord; byte[] bytes = GetRecordBytes(volume, index); return(Get(bytes, volume, (int)vbr.BytesPerFileRecord, fast)); }
/// <summary> /// /// </summary> /// <param name="volume"></param> /// <param name="sector"></param> /// <returns></returns> public static FileAllocationTableEntry Get(string volume, int sector) { FatVolumeBootRecord vbr = VolumeBootRecord.Get(volume) as FatVolumeBootRecord; byte[] bytes = FileAllocationTable.GetBytes(volume, vbr); int endSector = 0; switch (vbr.FatType) { case "FAT12": endSector = parseFat12(bytes, sector); break; case "FAT16": endSector = parseFat16(bytes, sector); break; case "FAT32": endSector = parseFat32(bytes, sector); break; } return(new FileAllocationTableEntry(sector, endSector)); }
/// <summary> /// The ProcessRecord method instantiates a VolumeBootRecord object based /// on the volume name given as an argument. /// </summary> protected override void ProcessRecord() { switch (ParameterSetName) { case "ByVolume": if (asbytes) { WriteObject(VolumeBootRecord.GetBytes(volume)); } else { WriteObject(VolumeBootRecord.Get(volume)); } break; case "ByPath": if (asbytes) { WriteObject(VolumeBootRecord.GetBytesByPath(path)); } else { WriteObject(VolumeBootRecord.GetByPath(path)); } break; } }
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)); }
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 DirectoryEntry[] GetRootDirectory(string volume) { string volLetter = Helper.GetVolumeLetter(volume); FatVolumeBootRecord vbr = VolumeBootRecord.Get(volume) as FatVolumeBootRecord; byte[] bytes = DD.Get(volume, vbr.BytesPerSector * vbr.RootDirectorySector, vbr.BytesPerSector, 2); return(GetInstances(bytes, volume, volLetter)); }
private static DirectoryEntry[] GetRootDirectory(string volume) { string volLetter = Helper.GetVolumeLetter(volume); FatVolumeBootRecord vbr = VolumeBootRecord.Get(volume) as FatVolumeBootRecord; uint FirstRootDirSecNum = vbr.ReservedSectors + (vbr.BPB_NumberOfFATs * vbr.BPB_FatSize32); byte[] bytes = DD.Get(volume, vbr.BytesPerSector * FirstRootDirSecNum, vbr.BytesPerSector, 2); return(GetInstances(bytes, volume, volLetter)); }
protected override void ProcessRecord() { NativeMethods.getVolumeName(ref volume); if (asbytes) { WriteObject(VolumeBootRecord.GetBytes(volume)); } else { WriteObject(VolumeBootRecord.Get(volume)); } } // ProcessRecord
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..."); } }
internal static FileRecord GetRecord(FileStream streamToRead, string volume) { // Instantiate VolumeBootRecord object NtfsVolumeBootRecord VBR = VolumeBootRecord.Get(streamToRead) as NtfsVolumeBootRecord; // 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)); }
public static Prefetch[] GetInstances(string volume) { // Get current volume NativeMethods.getVolumeName(ref volume); // Get volume letter string volLetter = volume.Split('\\')[3]; // Get a handle to the volume IntPtr hVolume = NativeMethods.getHandle(volume); // Create a FileStream to read from the volume handle using (FileStream streamToRead = NativeMethods.getFileStream(hVolume)) { VolumeBootRecord VBR = VolumeBootRecord.Get(streamToRead); // Get a byte array representing the Master File Table byte[] MFT = MasterFileTable.GetBytes(streamToRead, volume); // Build Prefetch directory path string pfPath = volLetter + @"\Windows\Prefetch"; if (Directory.Exists(pfPath)) { var pfFiles = System.IO.Directory.GetFiles(pfPath, "*.pf"); Prefetch[] pfArray = new Prefetch[pfFiles.Length]; // Get IndexEntry IndexEntry[] pfEntries = IndexEntry.GetInstances(pfPath); int i = 0; foreach (IndexEntry entry in pfEntries) { if (entry.Filename.Contains(".pf")) { pfArray[i] = new Prefetch(new FileRecord(NativeMethods.GetSubArray(MFT, (uint)entry.RecordNumber * 0x400, 0x400), volume, true).GetBytes(VBR)); i++; } } return(pfArray); } else { throw new Exception("Prefetch Directory does not exist. Check registry to ensure Prefetching is enabled."); } } }
public static Prefetch[] GetInstances(string volume) { // Get current volume Util.getVolumeName(ref volume); // Get a handle to the volume IntPtr hVolume = Util.getHandle(volume); // Create a FileStream to read from the volume handle using (FileStream streamToRead = Util.getFileStream(hVolume)) { VolumeBootRecord VBR = VolumeBootRecord.Get(streamToRead); // Get a byte array representing the Master File Table byte[] MFT = MasterFileTable.GetBytes(streamToRead, volume); // Build Prefetch directory path string pfPath = volume.Split('\\')[3] + @"\Windows\Prefetch"; /*if(CheckStatus(volume.Split('\\')[3] + @"\Windows\system32\config\SAM") != PREFETCH_ENABLED.DISABLED) * {*/ // Get IndexEntry IndexEntry[] pfEntries = IndexEntry.GetInstances(pfPath); Prefetch[] pfArray = new Prefetch[pfEntries.Length]; int i = 0; foreach (IndexEntry entry in pfEntries) { if (entry.Filename.Contains(".pf")) { pfArray[i] = new Prefetch(new FileRecord(Util.GetSubArray(MFT, (uint)entry.RecordNumber * 0x400, 0x400), volume, true).GetContent(VBR)); i++; } } return(pfArray); /*} * else * { * throw new Exception("Prefetching is disabled. Check registry to ensure Prefetching is enabled."); * }*/ } }
/// <summary> /// /// </summary> /// <param name="volume"></param> /// <returns></returns> public static Prefetch[] GetInstances(string volume) { // Get current volume Helper.getVolumeName(ref volume); using (FileStream streamToRead = Helper.getFileStream(volume)) { NtfsVolumeBootRecord VBR = VolumeBootRecord.Get(streamToRead) as NtfsVolumeBootRecord; // Get a byte array representing the Master File Table byte[] MFT = MasterFileTable.GetBytes(streamToRead, volume); // Build Prefetch directory path string pfPath = Helper.GetVolumeLetter(volume) + @"\Windows\Prefetch"; /*if(CheckStatus(Helper.GetVolumeLetter(volume) + @"\Windows\system32\config\SAM") != PREFETCH_ENABLED.DISABLED) * {*/ // Get IndexEntry IndexEntry[] pfEntries = IndexEntry.GetInstances(pfPath); Prefetch[] pfArray = new Prefetch[pfEntries.Length]; int i = 0; foreach (IndexEntry entry in pfEntries) { if (entry.Filename.Contains(".pf")) { pfArray[i] = new Prefetch(FileRecord.Get(volume, (int)entry.RecordNumber, true).GetContent(VBR)); i++; } } return(pfArray); /*} * else * { * throw new Exception("Prefetching is disabled. Check registry to ensure Prefetching is enabled."); * }*/ } }
internal static int[] GetFatEntry(string volume, int startSector) { FatVolumeBootRecord vbr = VolumeBootRecord.Get(volume) as FatVolumeBootRecord; byte[] fatBytes = GetBytes(volume, vbr); switch (vbr.FatType) { case "FAT12": return(parseFat12(fatBytes, startSector)); case "FAT16": return(parseFat16(fatBytes, startSector)); case "FAT32": return(parseFat32(fatBytes, startSector)); default: throw new Exception("FAT Type could not be determined."); } }
/// <summary> /// /// </summary> /// <returns></returns> public byte[] GetContent() { FatVolumeBootRecord vbr = VolumeBootRecord.Get(this.Volume) as FatVolumeBootRecord; int RootDirSectors = ((vbr.BPB_RootEntryCount * 32) + (vbr.BytesPerSector - 1)) / vbr.BytesPerSector; uint FatSize = 0; if (vbr.BPB_FatSize16 != 0) { FatSize = vbr.BPB_FatSize16; } else { FatSize = vbr.BPB_FatSize32; } uint FirstDataSector = (uint)(vbr.ReservedSectors + (vbr.BPB_NumberOfFATs * FatSize) + RootDirSectors); uint FirstSectorofCluster = ((this.FirstCluster - 2) * vbr.SectorsPerCluster) + FirstDataSector; byte[] bytes = DD.Get(this.Volume, (long)FirstSectorofCluster * (long)vbr.BytesPerSector, vbr.BytesPerSector, 1); if (this.Directory) { return(bytes); } else { if (this.FileSize <= bytes.Length) { return(Helper.GetSubArray(bytes, 0, this.FileSize)); } else { // Need to do more... return(bytes); } } }
/// <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()); }
public static ShellLink[] GetInstances(string volume) { VolumeBootRecord VBR = VolumeBootRecord.Get(volume); List <ShellLink> slList = new List <ShellLink>(); foreach (FileRecord r in FileRecord.GetInstances(volume)) { try { if (r.Name.Contains(".lnk")) { slList.Add(new ShellLink(r.GetContent(VBR), r)); } } catch { } } return(slList.ToArray()); }
/// <summary> /// /// </summary> /// <returns></returns> public byte[] GetContent() { FatVolumeBootRecord vbr = VolumeBootRecord.Get(this.Volume) as FatVolumeBootRecord; int RootDirSectors = ((vbr.BPB_RootEntryCount * 32) + (vbr.BytesPerSector - 1)) / vbr.BytesPerSector; uint FirstDataSector = (uint)(vbr.ReservedSectors + (vbr.BPB_NumberOfFATs * vbr.BPB_FatSize) + RootDirSectors); uint FirstSectorofCluster = ((this.FirstCluster - 2) * vbr.SectorsPerCluster) + FirstDataSector; byte[] bytes = DD.Get(this.Volume, (long)FirstSectorofCluster * (long)vbr.BytesPerSector, vbr.BytesPerSector, 1); if (this.Directory) { return(bytes); } else { if (this.FileSize <= bytes.Length) { return(Helper.GetSubArray(bytes, 0, this.FileSize)); } else { List <byte> byteList = new List <byte>(); int[] clusters = FileAllocationTable.GetFatEntry(this.Volume, (int)this.FirstCluster); foreach (int cluster in clusters) { long targetCluster = ((cluster - 2) * vbr.SectorsPerCluster) + FirstDataSector; byteList.AddRange(DD.Get(this.Volume, targetCluster * vbr.BytesPerSector, vbr.BytesPerSector, 1)); } return(Helper.GetSubArray(byteList.ToArray(), 0, this.FileSize)); } } }
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); // Get VolumeBootRecord object for logical addressing VolumeBootRecord VBR = VolumeBootRecord.Get(streamToRead); // Get the $Max Data attribute (contains UsnJrnl details) Data Max = UsnJrnl.GetMaxStream(UsnJrnl.GetFileRecord(volume)); if (asBytes) { WriteObject(Max.RawData); } else { WriteObject(new UsnJrnlDetail(Max.RawData)); } } // ProcessRecord
/// <summary> /// /// </summary> /// <param name="volume"></param> /// <returns></returns> public static byte[] GetBytes(string volume) { return(GetBytes(volume, VolumeBootRecord.Get(volume) as FatVolumeBootRecord)); }
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"); } }
/// <summary> /// /// </summary> /// <param name="volume"></param> /// <returns></returns> public static FileSystemInformation Get(string volume) { FatVolumeBootRecord vbr = VolumeBootRecord.Get(volume) as FatVolumeBootRecord; return(new FileSystemInformation(DD.Get(volume, (vbr.BytesPerSector * vbr.BPB_FileSytemInfo), vbr.BytesPerSector, 1))); }