public void SimpleFile()
        {
            byte[] randomData = new byte[65 * 4096];
            _random.NextBytes(randomData);

            using (TempFile tmpFile = new TempFile())
            {
                // Create a file
                File.WriteAllBytes(tmpFile.File.FullName, randomData);

                // Discover it via the NTFS lib
                char    driveLetter = tmpFile.File.FullName[0];
                RawDisk disk        = new RawDisk(driveLetter);

                NTFSDiskProvider provider = new NTFSDiskProvider(disk);

                NTFSWrapper ntfsWrapper = new NTFSWrapper(provider, 0);

                NtfsDirectory ntfsDir  = NTFSHelpers.OpenDir(ntfsWrapper, tmpFile.File.DirectoryName);
                NtfsFile      ntfsFile = NTFSHelpers.OpenFile(ntfsDir, tmpFile.File.Name);

                Assert.IsNotNull(ntfsFile);

                // Read it
                using (Stream actualStream = File.OpenRead(tmpFile.File.FullName))
                    using (Stream ntfsStream = ntfsFile.OpenRead())
                    {
                        bool equal = StreamUtils.CompareStreams(actualStream, ntfsStream);

                        Assert.IsTrue(equal);
                    }
            }
        }
        public void SparseFile()
        {
            byte[] randomData = new byte[35 * 4096];
            _random.NextBytes(randomData);

            // Clear the 16 * 4096 -> 32 * 4096 range
            Array.Clear(randomData, 16 * 4096, 16 * 4096);

            using (TempFile tmpFile = new TempFile())
            {
                // Create a file
                File.WriteAllBytes(tmpFile.File.FullName, randomData);

                using (FilesystemDeviceWrapper wrapper = Win32.GetFileWrapper(tmpFile.File.FullName))
                {
                    wrapper.FileSystemSetSparseFile(true);
                    wrapper.FileSystemSetZeroData(16 * 4096, 16 * 4096);

                    FILE_ALLOCATED_RANGE_BUFFER[] rangesData = wrapper.FileSystemQueryAllocatedRanges(0, randomData.Length);

                    // We should have 2 ranges on non-zero data
                    Assert.AreEqual(2, rangesData.Length);
                }

                // Discover it via the NTFS lib
                char    driveLetter = tmpFile.File.FullName[0];
                RawDisk disk        = new RawDisk(driveLetter);

                NTFSDiskProvider provider = new NTFSDiskProvider(disk);

                NTFSWrapper ntfsWrapper = new NTFSWrapper(provider, 0);

                NtfsDirectory ntfsDir  = NTFSHelpers.OpenDir(ntfsWrapper, tmpFile.File.DirectoryName);
                NtfsFile      ntfsFile = NTFSHelpers.OpenFile(ntfsDir, tmpFile.File.Name);

                Assert.IsNotNull(ntfsFile);
                Assert.IsTrue(tmpFile.File.Attributes.HasFlag(FileAttributes.SparseFile));
                AttributeData attributeData = ntfsFile.MFTRecord.Attributes.OfType <AttributeData>().Single();
                Assert.IsTrue(attributeData.DataFragments.Length > 1);
                Assert.IsTrue(attributeData.DataFragments.Any(s => s.IsSparseFragment));

                // Read it
                using (Stream actualStream = File.OpenRead(tmpFile.File.FullName))
                    using (Stream ntfsStream = ntfsFile.OpenRead())
                    {
                        bool equal = StreamUtils.CompareStreams(actualStream, ntfsStream);

                        Assert.IsTrue(equal);
                    }
            }
        }
        public void CompressedFile()
        {
            using (TempFile tmpFile = new TempFile())
            {
                // Create a file
                // Write file data
                using (FileStream fs = File.OpenWrite(tmpFile.File.FullName))
                {
                    byte[] data = Encoding.ASCII.GetBytes("The white bunny jumps over the brown dog in a carparking lot");

                    for (int i = 0; i < 20000; i++)
                    {
                        fs.Write(data, 0, data.Length);
                    }
                }

                using (FilesystemDeviceWrapper wrapper = Win32.GetFileWrapper(tmpFile.File.FullName))
                {
                    wrapper.FileSystemSetCompression(COMPRESSION_FORMAT.LZNT1);
                }

                // Discover it via the NTFS lib
                char    driveLetter = tmpFile.File.FullName[0];
                RawDisk disk        = new RawDisk(driveLetter);

                NTFSDiskProvider provider = new NTFSDiskProvider(disk);

                NTFSWrapper ntfsWrapper = new NTFSWrapper(provider, 0);

                NtfsDirectory ntfsDir  = NTFSHelpers.OpenDir(ntfsWrapper, tmpFile.File.DirectoryName);
                NtfsFile      ntfsFile = NTFSHelpers.OpenFile(ntfsDir, tmpFile.File.Name);

                Assert.IsNotNull(ntfsFile);
                Assert.IsTrue(tmpFile.File.Attributes.HasFlag(FileAttributes.Compressed));
                AttributeData attributeData = ntfsFile.MFTRecord.Attributes.OfType <AttributeData>().Single();
                Assert.IsTrue(attributeData.DataFragments.Any(s => s.IsCompressed));

                // Read it
                using (Stream actualStream = File.OpenRead(tmpFile.File.FullName))
                    using (Stream ntfsStream = ntfsFile.OpenRead())
                    {
                        bool equal = StreamUtils.CompareStreams(actualStream, ntfsStream);

                        Assert.IsTrue(equal);
                    }
            }
        }
Exemple #4
0
        private byte[] GetFileBytes(NtfsFile file)
        {
            byte[] result = new byte[] { };
            // If we made it this far, attempt to read the bytes
            using (MemoryStream ms = new MemoryStream((int)this.Length))
            {
                using (Stream ntfsStream = file.OpenRead())
                {
                    int    read;
                    byte[] buffer = new byte[16 * 1024];

                    while ((read = ntfsStream.Read(buffer, 0, buffer.Length)) > 0)
                    {
                        ms.Write(buffer, 0, read);
                        CancellationHelper.ThrowIfCancelled();
                    }
                    buffer = null;
                }
                result = ms.ToArray();
            }
            return(result);
        }
Exemple #5
0
        public void PopulateFileProperties(FileEnumeratorParameters parameters, char driveLetter, NtfsFile ntfsFile)
        {
            if (parameters == null)
            {
                return;
            }
            if (ntfsFile == null)
            {
                return;
            }

            CancellationHelper.SetCancellationToken(parameters.CancelToken);
            CancellationHelper.ThrowIfCancelled();

            MFTNumber      = ntfsFile.MFTRecord.MFTNumber;
            SequenceNumber = ntfsFile.MFTRecord.SequenceNumber;

            DriveLetter = driveLetter;
            FileName    = ntfsFile.Name;

            MftTimeAccessed    = ntfsFile.TimeAccessed;
            MftTimeCreation    = ntfsFile.TimeCreation;
            MftTimeModified    = ntfsFile.TimeModified;
            MftTimeMftModified = ntfsFile.TimeMftModified;

            DirectoryLocation = GetDirectory(ntfsFile);
            Extension         = Path.GetExtension(FileName);
            FullPath          = Path.Combine(DriveLetter.ToString() + DirectoryLocation, FileName);

            this.Length = ntfsFile.AllocatedSize;

            CancellationHelper.ThrowIfCancelled();

            if (this.Length != 0)
            {
                // Some entries in the MFT are greater than int.MaxValue !! That or the size is corrupt. Either way, we handle that here.
                if (this.Length >= (int.MaxValue - 1))
                {
                    using (Stream ntfsStream = ntfsFile.OpenRead())
                    {
                        this.Sha256Hash = GetSha256Hash_BigFile(ntfsStream);
                        this.Length     = ntfsStream.Length;
                    }

                    this.PeData = PeDataObject.TryGetPeDataObject(FileName, parameters.OnlineCertValidation);
                    CancellationHelper.ThrowIfCancelled();
                    this.Authenticode = AuthenticodeData.TryGetAuthenticodeData(FileName);
                    CancellationHelper.ThrowIfCancelled();
                }
                else
                {
                    byte[] fileBytes = GetFileBytes(ntfsFile);

                    CancellationHelper.ThrowIfCancelled();

                    this.PeData = PeDataObject.TryGetPeDataObject(fileBytes, parameters.OnlineCertValidation);
                    if (IsPeDataPopulated)
                    {
                        this.Sha256Hash = PeData.SHA256Hash;
                    }
                    else
                    {
                        this.Sha256Hash = GetSha256Hash(fileBytes);
                    }

                    CancellationHelper.ThrowIfCancelled();

                    if (parameters.CalculateEntropy)
                    {
                        this.Entropy = EntropyHelper.CalculateFileEntropy(fileBytes);
                        CancellationHelper.ThrowIfCancelled();
                    }

                    this.Authenticode = AuthenticodeData.TryGetAuthenticodeData(fileBytes);

                    CancellationHelper.ThrowIfCancelled();

                    if (!string.IsNullOrWhiteSpace(parameters.YaraRulesFilePath) && File.Exists(parameters.YaraRulesFilePath))
                    {
                        this.YaraRulesMatched = YaraRules.Scan(fileBytes, parameters.YaraRulesFilePath);
                        CancellationHelper.ThrowIfCancelled();
                    }

                    fileBytes = null;
                }
            }

            PopulateFileInfoProperties(FullPath);

            CancellationHelper.ThrowIfCancelled();

            this.Attributes = new Attributes(FullPath);

            CancellationHelper.ThrowIfCancelled();

            PopulateShellFileInfo(FullPath);

            CancellationHelper.ThrowIfCancelled();
        }