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 bool Identify(IMediaImage imagePlugin, Partition partition) { if (12 + partition.Start >= partition.End) { return(false); } byte[] vbrSector = imagePlugin.ReadSector(0 + partition.Start); if (vbrSector.Length < 512) { return(false); } VolumeBootRecord vbr = Marshal.ByteArrayToStructureLittleEndian <VolumeBootRecord>(vbrSector); return(signature.SequenceEqual(vbr.signature)); }
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); } } }
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> /// <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 bool Identify(IMediaImage imagePlugin, Partition partition) { if (12 + partition.Start >= partition.End) { return(false); } byte[] vbrSector = imagePlugin.ReadSector(0 + partition.Start); if (vbrSector.Length < 512) { return(false); } IntPtr vbrPtr = Marshal.AllocHGlobal(512); Marshal.Copy(vbrSector, 0, vbrPtr, 512); VolumeBootRecord vbr = (VolumeBootRecord)Marshal.PtrToStructure(vbrPtr, typeof(VolumeBootRecord)); Marshal.FreeHGlobal(vbrPtr); return(signature.SequenceEqual(vbr.signature)); }
/// <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 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))); }
internal static byte[] GetBytes(string volume, VolumeBootRecord vbr) { long DirectoryEntryOffset = vbr.ReservedSectors * vbr.BytesPerSector; return Helper.readDrive(volume, DirectoryEntryOffset, (vbr.SectorsPerFat * vbr.BytesPerSector)); }
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"); } }
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information, Encoding encoding) { Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15"); information = ""; StringBuilder sb = new StringBuilder(); XmlFsType = new FileSystemType(); byte[] vbrSector = imagePlugin.ReadSector(0 + partition.Start); IntPtr vbrPtr = Marshal.AllocHGlobal(512); Marshal.Copy(vbrSector, 0, vbrPtr, 512); VolumeBootRecord vbr = (VolumeBootRecord)Marshal.PtrToStructure(vbrPtr, typeof(VolumeBootRecord)); Marshal.FreeHGlobal(vbrPtr); byte[] parametersSector = imagePlugin.ReadSector(9 + partition.Start); IntPtr parametersPtr = Marshal.AllocHGlobal(512); Marshal.Copy(parametersSector, 0, parametersPtr, 512); OemParameterTable parametersTable = (OemParameterTable)Marshal.PtrToStructure(parametersPtr, typeof(OemParameterTable)); Marshal.FreeHGlobal(parametersPtr); byte[] chkSector = imagePlugin.ReadSector(11 + partition.Start); IntPtr chkPtr = Marshal.AllocHGlobal(512); Marshal.Copy(chkSector, 0, chkPtr, 512); ChecksumSector chksector = (ChecksumSector)Marshal.PtrToStructure(chkPtr, typeof(ChecksumSector)); Marshal.FreeHGlobal(chkPtr); sb.AppendLine("Microsoft exFAT"); sb.AppendFormat("Partition offset: {0}", vbr.offset).AppendLine(); sb.AppendFormat("Volume has {0} sectors of {1} bytes each for a total of {2} bytes", vbr.sectors, 1 << vbr.sectorShift, vbr.sectors * (ulong)(1 << vbr.sectorShift)).AppendLine(); sb.AppendFormat("Volume uses clusters of {0} sectors ({1} bytes) each", 1 << vbr.clusterShift, (1 << vbr.sectorShift) * (1 << vbr.clusterShift)).AppendLine(); sb.AppendFormat("First FAT starts at sector {0} and runs for {1} sectors", vbr.fatOffset, vbr.fatLength) .AppendLine(); sb.AppendFormat("Volume uses {0} FATs", vbr.fats).AppendLine(); sb.AppendFormat("Cluster heap starts at sector {0}, contains {1} clusters and is {2}% used", vbr.clusterHeapOffset, vbr.clusterHeapLength, vbr.heapUsage).AppendLine(); sb.AppendFormat("Root directory starts at cluster {0}", vbr.rootDirectoryCluster).AppendLine(); sb.AppendFormat("Filesystem revision is {0}.{1:D2}", (vbr.revision & 0xFF00) >> 8, vbr.revision & 0xFF) .AppendLine(); sb.AppendFormat("Volume serial number: {0:X8}", vbr.volumeSerial).AppendLine(); sb.AppendFormat("BIOS drive is {0:X2}h", vbr.drive).AppendLine(); if (vbr.flags.HasFlag(VolumeFlags.SecondFatActive)) { sb.AppendLine("2nd FAT is in use"); } if (vbr.flags.HasFlag(VolumeFlags.VolumeDirty)) { sb.AppendLine("Volume is dirty"); } if (vbr.flags.HasFlag(VolumeFlags.MediaFailure)) { sb.AppendLine("Underlying media presented errors"); } int count = 1; foreach (OemParameter parameter in parametersTable.parameters) { if (parameter.OemParameterType == OEM_FLASH_PARAMETER_GUID) { sb.AppendFormat("OEM Parameters {0}:", count).AppendLine(); sb.AppendFormat("\t{0} bytes in erase block", parameter.eraseBlockSize).AppendLine(); sb.AppendFormat("\t{0} bytes per page", parameter.pageSize).AppendLine(); sb.AppendFormat("\t{0} spare blocks", parameter.spareBlocks).AppendLine(); sb.AppendFormat("\t{0} nanoseconds random access time", parameter.randomAccessTime).AppendLine(); sb.AppendFormat("\t{0} nanoseconds program time", parameter.programTime).AppendLine(); sb.AppendFormat("\t{0} nanoseconds read cycle time", parameter.readCycleTime).AppendLine(); sb.AppendFormat("\t{0} nanoseconds write cycle time", parameter.writeCycleTime).AppendLine(); } else if (parameter.OemParameterType != Guid.Empty) { sb.AppendFormat("Found unknown parameter type {0}", parameter.OemParameterType).AppendLine(); } count++; } sb.AppendFormat("Checksum 0x{0:X8}", chksector.checksum[0]).AppendLine(); XmlFsType.ClusterSize = (1 << vbr.sectorShift) * (1 << vbr.clusterShift); XmlFsType.Clusters = vbr.clusterHeapLength; XmlFsType.Dirty = vbr.flags.HasFlag(VolumeFlags.VolumeDirty); XmlFsType.Type = "exFAT"; XmlFsType.VolumeSerial = $"{vbr.volumeSerial:X8}"; information = sb.ToString(); }
/// <summary> /// /// </summary> /// <param name="volume"></param> /// <returns></returns> public static byte[] GetBytes(string volume) { return(GetBytes(volume, VolumeBootRecord.Get(volume) as FatVolumeBootRecord)); }