public NtfsFileSystem() { Name = "NTFS"; Structure = new NtfsStructureFileSystem(); MasterFileTable = new MasterFileTable(this); Initialize(); }
/// <summary> /// The ProcessRecord instantiates a NTFSVolumeData objects that /// corresponds to the VolumeName that is specified. /// </summary> protected override void ProcessRecord() { Regex lettersOnly = new Regex("^[a-zA-Z]{1}$"); if (lettersOnly.IsMatch(volume)) { volume = @"\\.\" + volume + ":"; } string volLetter = volume.TrimStart('\\').TrimStart('.').TrimStart('\\') + '\\'; WriteDebug("VolumeName: " + volume); byte[] mftBytes = MasterFileTable.GetBytes(volume); if (this.MyInvocation.BoundParameters.ContainsKey("Path")) { int index = IndexNumber.Get(volume, filePath); if (asbytes) { WriteObject(MFTRecord.getMFTRecordBytes(mftBytes, index)); } else { WriteObject(MFTRecord.Get(mftBytes, index, volLetter, filePath)); } } else if (this.MyInvocation.BoundParameters.ContainsKey("Index")) { if (asbytes) { WriteObject(MFTRecord.getMFTRecordBytes(mftBytes, indexNumber)); } else { WriteObject(MFTRecord.Get(mftBytes, indexNumber, volLetter, null)); } } else { MFTRecord[] records = MFTRecord.GetInstances(mftBytes, volLetter); foreach (MFTRecord record in records) { WriteObject(record); } } } // ProcessRecord
/// <summary> /// The ProcessRecord outputs the raw bytes of the specified File /// </summary> protected override void ProcessRecord() { string volume = @"\\.\" + directory.Split('\\')[0]; string volLetter = directory.Split('\\')[0] + '\\'; byte[] mftBytes = MasterFileTable.GetBytes(volume); string[] files = System.IO.Directory.GetFiles(directory); foreach (string file in files) { WriteObject(MFTRecord.Get(mftBytes, IndexNumber.Get(volume, file), volLetter, file)); } } // ProcessRecord
/// <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> /// The ProcessRecord method returns a Prefetch object for the File specified /// by the Path property, or iterates through all .pf files in the /// C:\Windows\Prefetch directory to output an array of Prefetch objects. /// </summary> protected override void ProcessRecord() { // Get current volume string volLetter = Directory.GetCurrentDirectory().Split('\\')[0]; string volume = @"\\.\" + volLetter; // Get a handle to the volume IntPtr hVolume = NativeMethods.getHandle(volume); // Create a FileStream to read from the volume handle FileStream streamToRead = NativeMethods.getFileStream(hVolume); // Get a byte array representing the Master File Table byte[] MFT = MasterFileTable.GetBytes(hVolume, streamToRead); // If the FilePath parameter is used if (this.MyInvocation.BoundParameters.ContainsKey("Path")) { //Test that FilePath exists if (File.Exists(filePath)) { // Output the Prefetch object for the corresponding file WriteObject(Prefetch.Get(volume, streamToRead, MFT, filePath)); } // If file doesnt exist, throw error else { throw new FileNotFoundException((filePath + " does not exist. Please enter a valid file path.")); } } // If no FilePath is provided, return all Prefetch files else { // Build Prefetch directory path string prefetchPath = volLetter + @"\\Windows\\Prefetch"; // Get list of file in the Prefetch directory that end in the .pf extension var pfFiles = System.IO.Directory.GetFiles(prefetchPath, "*.pf"); // Iterate through Prefetch Files foreach (var file in pfFiles) { // Output the Prefetch object for the corresponding file WriteObject(Prefetch.Get(volume, streamToRead, MFT, file)); } } } // ProcessRecord
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() { // Get current volume string volLetter = Directory.GetCurrentDirectory().Split('\\')[0]; string volume = @"\\.\" + volLetter; // 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)) { // Get a byte array representing the Master File Table byte[] MFT = MasterFileTable.GetBytes(hVolume, streamToRead); // Build Prefetch directory path string prefetchPath = volLetter + @"\\Windows\\Prefetch"; // Check prefetchPath exists if (Directory.Exists(prefetchPath)) { // Get list of file in the Prefetch directory that end in the .pf extension var pfFiles = System.IO.Directory.GetFiles(prefetchPath, "*.pf"); // Instantiate an array of Prefetch objects Prefetch[] pfArray = new Prefetch[pfFiles.Length]; // Iterate through Prefetch Files for (int i = 0; i < pfFiles.Length; i++) { // Get bytes for specific Prefetch file byte[] fileBytes = MFTRecord.getFile(volume, streamToRead, MFT, pfFiles[i]).ToArray(); // Output the Prefetch object for the corresponding file pfArray[i] = (new Prefetch(fileBytes)); } // Return array or Prefetch objects return(pfArray); } else { return(null); } } }
/// <summary> /// The ProcessRecord instantiates a NTFSVolumeData objects that /// corresponds to the VolumeName that is specified. /// </summary> protected override void ProcessRecord() { NativeMethods.getVolumeName(ref volume); string volLetter = volume.TrimStart('\\').TrimStart('.').TrimStart('\\') + '\\'; byte[] mftBytes = MasterFileTable.GetBytes(volume); if (this.MyInvocation.BoundParameters.ContainsKey("Path")) { int index = IndexNumber.Get(volume, filePath); if (asbytes) { WriteObject(MFTRecord.getMFTRecordBytes(mftBytes, index)); } else { WriteObject(MFTRecord.Get(mftBytes, index, volLetter, filePath)); } } else if (this.MyInvocation.BoundParameters.ContainsKey("Index")) { if (asbytes) { WriteObject(MFTRecord.getMFTRecordBytes(mftBytes, indexNumber)); } else { WriteObject(MFTRecord.Get(mftBytes, indexNumber, volLetter, null)); } } else { MFTRecord[] records = MFTRecord.GetInstances(mftBytes, volLetter); foreach (MFTRecord record in records) { WriteObject(record); } } } // ProcessRecord
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."); * }*/ } }
public static Prefetch Get(string filePath) { // Get volume path from filePath string volume = @"\\.\" + filePath.Split('\\')[0]; // 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)) { // Get a byte array representing the Master File Table byte[] MFT = MasterFileTable.GetBytes(hVolume, streamToRead); // Get bytes for specific Prefetch file byte[] fileBytes = MFTRecord.getFile(volume, streamToRead, MFT, filePath).ToArray(); // Return a Prefetch object for the Prefetch file stored at filePath return(new Prefetch(fileBytes)); } }
static string GetPath(MasterFileTable mft, MasterFileTableEntry entry) { if (entry.SequenceNumber == MasterFileTable.RootDirectoryIndex) { return("<root>"); } FileNameAttribute fna = null; foreach (var attr in entry.Attributes) { FileNameAttribute thisFna = attr as FileNameAttribute; if (thisFna != null) { if (fna == null || thisFna.FileNameNamespace == NtfsNamespace.Win32 || thisFna.FileNameNamespace == NtfsNamespace.Win32AndDos) { fna = thisFna; } } } if (fna == null) { return("<unknown>"); } string parentPath = "<unknown>"; MasterFileTableEntry parentEntry = mft[fna.ParentDirectory.RecordIndex]; if (parentEntry != null) { if (parentEntry.SequenceNumber == fna.ParentDirectory.RecordSequenceNumber || parentEntry.SequenceNumber == fna.ParentDirectory.RecordSequenceNumber + 1) { parentPath = GetPath(mft, parentEntry); } } return(parentPath + "\\" + fna.FileName); }
/// <summary> /// The ProcessRecord instantiates a FileRecord objects that /// corresponds to the file(s) that is/are specified. /// </summary> protected override void ProcessRecord() { switch (ParameterSetName) { case "ByIndex": if (MyInvocation.BoundParameters.ContainsKey("Index")) { WriteObject(FileRecord.Get(volume, indexNumber, true).GetMftSlack()); } else { WriteObject(MasterFileTable.GetSlack(volume)); } break; case "ByPath": WriteObject(FileRecord.Get(path, true).GetMftSlack()); break; case "MFTPath": WriteObject(MasterFileTable.GetSlackByPath(mftpath)); break; } }
protected override void DoRun() { VolumeManager volMgr = new VolumeManager(); foreach (string disk in _diskFiles.Values) { volMgr.AddDisk(VirtualDisk.OpenDisk(disk, FileAccess.Read, UserName, Password)); } VolumeInfo volInfo = null; if (!string.IsNullOrEmpty(VolumeId)) { volInfo = volMgr.GetVolume(VolumeId); } else if (Partition >= 0) { volInfo = volMgr.GetPhysicalVolumes()[Partition]; } else { volInfo = volMgr.GetLogicalVolumes()[0]; } using (NtfsFileSystem fs = new NtfsFileSystem(volInfo.Open())) { MasterFileTable mft = fs.GetMasterFileTable(); if (_recoverFile.IsPresent) { MasterFileTableEntry entry = mft[long.Parse(_recoverFile.Value)]; IBuffer content = GetContent(entry); if (content == null) { Console.WriteLine("Sorry, unable to recover content"); Environment.Exit(1); } string outFile = _recoverFile.Value + "__recovered.bin"; if (File.Exists(outFile)) { Console.WriteLine("Sorry, the file already exists: " + outFile); Environment.Exit(1); } using (FileStream outFileStream = new FileStream(outFile, FileMode.CreateNew, FileAccess.Write)) { Pump(content, outFileStream); } Console.WriteLine("Possible file contents saved as: " + outFile); Console.WriteLine(); Console.WriteLine("Caution! It is rare for the file contents of deleted files to be intact - most"); Console.WriteLine("likely the contents recovered are corrupt as the space has been reused."); } else { foreach (var entry in mft.GetEntries(EntryStates.NotInUse)) { // Skip entries with no attributes, they've probably never been used. We're certainly // not going to manage to recover any useful data from them. if (entry.Attributes.Count == 0) { continue; } // Skip directories - any useful files inside will be found separately if ((entry.Flags & MasterFileTableEntryFlags.IsDirectory) != 0) { continue; } long size = GetSize(entry); string path = GetPath(mft, entry); if (!_showMeta.IsPresent && path.StartsWith(@"<root>\$Extend")) { continue; } if (!_showZeroSize.IsPresent && size == 0) { continue; } Console.WriteLine("Index: {0,-4} Size: {1,-8} Path: {2}", entry.Index, Utilities.ApproximateDiskSize(size), path); } } } }
static string GetPath(MasterFileTable mft, MasterFileTableEntry entry) { if (entry.SequenceNumber == MasterFileTable.RootDirectoryIndex) { return "<root>"; } FileNameAttribute fna = null; foreach (var attr in entry.Attributes) { FileNameAttribute thisFna = attr as FileNameAttribute; if (thisFna != null) { if (fna == null || thisFna.FileNameNamespace == NtfsNamespace.Win32 || thisFna.FileNameNamespace == NtfsNamespace.Win32AndDos) { fna = thisFna; } } } if (fna == null) { return "<unknown>"; } string parentPath = "<unknown>"; MasterFileTableEntry parentEntry = mft[fna.ParentDirectory.RecordIndex]; if (parentEntry != null) { if (parentEntry.SequenceNumber == fna.ParentDirectory.RecordSequenceNumber || parentEntry.SequenceNumber == fna.ParentDirectory.RecordSequenceNumber + 1) { parentPath = GetPath(mft, parentEntry); } } return parentPath + "\\" + fna.FileName; }