public void PopulateFileProperties(FileEnumeratorParameters parameters, char driveLetter, INode node)
        {
            if (parameters == null)
            {
                return;
            }
            if (node == null)
            {
                return;
            }

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

            MFTNumber      = node.MFTRecordNumber;
            SequenceNumber = node.SequenceNumber;

            DriveLetter = driveLetter;
            FileName    = node.Name;

            MftTimeAccessed    = node.LastAccessTime;
            MftTimeCreation    = node.CreationTime;
            MftTimeModified    = node.LastChangeTime;
            MftTimeMftModified = node.TimeMftModified;

            DirectoryLocation = Path.GetDirectoryName(node.FullName);
            Extension         = Path.GetExtension(FileName);
            FullPath          = node.FullName;

            this.Length = node.Size;

            CancellationHelper.ThrowIfCancelled();

            if (this.Length == 0)             //Workaround for hard links
            {
                if (System.IO.File.Exists(FullPath))
                {
                    long length = new System.IO.FileInfo(FullPath).Length;
                    if (length > 0)
                    {
                        this.Length = (ulong)length;
                        node.Size   = this.Length;
                    }
                }
            }

            bool haveFileReadPermission = true;
            var  fileIOPermission       = new FileIOPermission(FileIOPermissionAccess.Read, AccessControlActions.View, FullPath);

            if (fileIOPermission.AllFiles == FileIOPermissionAccess.Read)
            {
                haveFileReadPermission = true;
            }

            if (this.Length != 0)
            {
                var maxLength = ((ulong)NtfsReader.MaxClustersToRead * (ulong)4096);
                // 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 > maxLength)                 //(int.MaxValue - 1))
                {
                    IEnumerable <byte[]> fileChunks = node.GetBytes();
                    CancellationHelper.ThrowIfCancelled();

                    this.Sha256Hash = GetSha256Hash_IEnumerable(fileChunks, this.Length);
                    CancellationHelper.ThrowIfCancelled();

                    if (haveFileReadPermission)
                    {
                        this.PeData = PeDataObject.TryGetPeDataObject(FullPath, parameters.OnlineCertValidation);
                        CancellationHelper.ThrowIfCancelled();

                        this.Authenticode = AuthenticodeData.TryGetAuthenticodeData(FullPath);
                        CancellationHelper.ThrowIfCancelled();
                    }

                    /*
                     * if (parameters.CalculateEntropy)
                     * {
                     *      this.Entropy = EntropyHelper.CalculateFileEntropy(fileChunks, this.Length);
                     *      CancellationHelper.ThrowIfCancelled();
                     * }
                     */

                    if (haveFileReadPermission)
                    {
                        if (!string.IsNullOrWhiteSpace(parameters.YaraRulesFilePath) && File.Exists(parameters.YaraRulesFilePath))
                        {
                            this.YaraRulesMatched = YaraRules.ScanFile(FullPath, parameters.YaraRulesFilePath);
                            CancellationHelper.ThrowIfCancelled();
                        }
                    }
                }
                else
                {
                    byte[] fileBytes = new byte[0];
                    if (!node.Streams.Any())                     //workaround for no file stream such as with hard links
                    {
                        try
                        {
                            using (FileStream fsSource = new FileStream(FullPath,
                                                                        FileMode.Open, FileAccess.Read))
                            {
                                // Read the source file into a byte array.
                                fileBytes = new byte[fsSource.Length];
                                int numBytesToRead = (int)fsSource.Length;
                                int numBytesRead   = 0;
                                while (numBytesToRead > 0)
                                {
                                    // Read may return anything from 0 to numBytesToRead.
                                    int n = fsSource.Read(fileBytes, numBytesRead, numBytesToRead);

                                    // Break when the end of the file is reached.
                                    if (n == 0)
                                    {
                                        break;
                                    }

                                    numBytesRead   += n;
                                    numBytesToRead -= n;
                                }
                                numBytesToRead = fileBytes.Length;
                            }
                        }
                        catch (Exception ex)
                        {
                        }
                    }

                    else
                    {
                        fileBytes = node.GetBytes().SelectMany(chunk => chunk).ToArray();
                        CancellationHelper.ThrowIfCancelled();
                    }
                    this.PeData = PeDataObject.TryGetPeDataObject(fileBytes, parameters.OnlineCertValidation);
                    if (IsPeDataPopulated)
                    {
                        this.Sha256Hash = PeData.SHA256Hash;
                    }
                    else
                    {
                        this.Sha256Hash = GetSha256Hash_Array(fileBytes);
                    }
                    CancellationHelper.ThrowIfCancelled();

                    this.Authenticode = AuthenticodeData.TryGetAuthenticodeData(fileBytes);
                    CancellationHelper.ThrowIfCancelled();

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

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

            this.Attributes = new Attributes(node);
            CancellationHelper.ThrowIfCancelled();

            if (haveFileReadPermission)
            {
                PopulateFileInfoProperties(FullPath);
                CancellationHelper.ThrowIfCancelled();

                PopulateShellFileInfo(FullPath);
                CancellationHelper.ThrowIfCancelled();
            }
        }
Example #2
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();
        }