Пример #1
0
        /// <summary>
        /// Process a single file path as an InstallShield archive
        /// </summary>
        /// <param name="file">Name of the file to process</param>
        /// <param name="outputInfo">True to display the cabinet information, false otherwise</param>
        /// <param name="extract">True to extract the cabinet, false otherwise</param>
        private static void ProcessArchivePath(string file, bool outputInfo = true, bool extract = true)
        {
            if (!File.Exists(file))
            {
                return;
            }

            var archive = new InstallShieldArchiveV3(file);

            if (outputInfo)
            {
                Console.WriteLine($"File count: {archive.Header.FileCount}");
                Console.WriteLine($"Archive size: {archive.Header.ArchiveSize}");
                Console.WriteLine($"Directory count: {archive.Header.DirCount}");

                Console.WriteLine("Directory List:");
                foreach (ArchiveDirectory directory in archive.Directories)
                {
                    Console.WriteLine($"Directory: {directory.Name ?? string.Empty}, File Count: {directory.FileCount}");
                }

                Console.WriteLine("File list:");
                foreach (CompressedFile cfile in archive.Files.Select(kvp => kvp.Value))
                {
                    Console.WriteLine($"File: {cfile.FullPath ?? string.Empty}, Compressed Size: {cfile.CompressedSize}, Offset: {cfile.Offset}");
                }
            }

            if (extract)
            {
                string baseDirectory = Path.Combine(Path.GetDirectoryName(Path.GetFullPath(file)), Path.GetFileNameWithoutExtension(file));
                if (!Directory.Exists(baseDirectory))
                {
                    Directory.CreateDirectory(baseDirectory);
                }

                foreach (CompressedFile internalFile in archive.Files.Select(kvp => kvp.Value))
                {
                    string newfile = Path.Combine(baseDirectory, internalFile.FullPath);

                    if (!Directory.Exists(Path.GetDirectoryName(newfile)))
                    {
                        Directory.CreateDirectory(Path.GetDirectoryName(newfile));
                    }

                    (byte[] fileContents, string error) = archive.Extract(internalFile.FullPath);
                    if (!string.IsNullOrWhiteSpace(error))
                    {
                        Console.WriteLine($"Error detected while reading '{internalFile.FullPath}': {error}");
                        continue;
                    }

                    Console.WriteLine($"Outputting file {internalFile.FullPath} to {newfile}...");
                    using (FileStream fs = File.OpenWrite(newfile))
                    {
                        fs.Write(fileContents, 0, fileContents.Length);
                    }
                }
            }
        }
Пример #2
0
        /// <summary>
        /// Get the content-detectable protections associated with a single path
        /// </summary>
        /// <param name="file">Path to the file to scan</param>
        /// <returns>Dictionary of list of strings representing the found protections</returns>
        private ConcurrentDictionary <string, ConcurrentQueue <string> > GetInternalProtections(string file)
        {
            // Quick sanity check before continuing
            if (!File.Exists(file))
            {
                return(null);
            }

            // Initialze the protections found
            var protections = new ConcurrentDictionary <string, ConcurrentQueue <string> >();

            // Get the extension for certain checks
            string extension = Path.GetExtension(file).ToLower().TrimStart('.');

            // Open the file and begin scanning
            using (FileStream fs = File.OpenRead(file))
            {
                // Get the first 16 bytes for matching
                byte[] magic = new byte[16];
                try
                {
                    fs.Read(magic, 0, 16);
                    fs.Seek(-16, SeekOrigin.Current);
                }
                catch
                {
                    // We don't care what the issue was, we can't read or seek the file
                    return(null);
                }

                #region Non-Archive File Types

                // Executable
                if (ScanAllFiles || new Executable().ShouldScan(magic))
                {
                    var subProtections = new Executable().Scan(this, fs, file);
                    Utilities.AppendToDictionary(protections, subProtections);
                }

                // Text-based files
                if (ScanAllFiles || new Textfile().ShouldScan(magic, extension))
                {
                    var subProtections = new Textfile().Scan(this, fs, file);
                    Utilities.AppendToDictionary(protections, subProtections);
                }

                #endregion

                #region Archive File Types

                // If we're scanning archives, we have a few to try out
                if (ScanArchives)
                {
                    // 7-Zip archive
                    if (new SevenZip().ShouldScan(magic))
                    {
                        var subProtections = new SevenZip().Scan(this, fs, file);
                        Utilities.PrependToKeys(subProtections, file);
                        Utilities.AppendToDictionary(protections, subProtections);
                    }

                    // BFPK archive
                    if (new BFPK().ShouldScan(magic))
                    {
                        var subProtections = new BFPK().Scan(this, fs, file);
                        Utilities.PrependToKeys(subProtections, file);
                        Utilities.AppendToDictionary(protections, subProtections);
                    }

                    // BZip2
                    if (new BZip2().ShouldScan(magic))
                    {
                        var subProtections = new BZip2().Scan(this, fs, file);
                        Utilities.PrependToKeys(subProtections, file);
                        Utilities.AppendToDictionary(protections, subProtections);
                    }

                    // GZIP
                    if (new GZIP().ShouldScan(magic))
                    {
                        var subProtections = new GZIP().Scan(this, fs, file);
                        Utilities.PrependToKeys(subProtections, file);
                        Utilities.AppendToDictionary(protections, subProtections);
                    }

                    // InstallShield Archive V3 (Z)
                    if (file != null && new InstallShieldArchiveV3().ShouldScan(magic))
                    {
                        var subProtections = new InstallShieldArchiveV3().Scan(this, file);
                        Utilities.PrependToKeys(subProtections, file);
                        Utilities.AppendToDictionary(protections, subProtections);
                    }

                    // InstallShield Cabinet
                    if (file != null && new InstallShieldCAB().ShouldScan(magic))
                    {
                        var subProtections = new InstallShieldCAB().Scan(this, file);
                        Utilities.PrependToKeys(subProtections, file);
                        Utilities.AppendToDictionary(protections, subProtections);
                    }

                    // Microsoft Cabinet
                    if (file != null && new MicrosoftCAB().ShouldScan(magic))
                    {
                        var subProtections = new MicrosoftCAB().Scan(this, file);
                        Utilities.PrependToKeys(subProtections, file);
                        Utilities.AppendToDictionary(protections, subProtections);
                    }

                    // MSI
                    if (file != null && new MSI().ShouldScan(magic))
                    {
                        var subProtections = new MSI().Scan(this, file);
                        Utilities.PrependToKeys(subProtections, file);
                        Utilities.AppendToDictionary(protections, subProtections);
                    }

                    // MPQ archive
                    if (file != null && new MPQ().ShouldScan(magic))
                    {
                        var subProtections = new MPQ().Scan(this, file);
                        Utilities.PrependToKeys(subProtections, file);
                        Utilities.AppendToDictionary(protections, subProtections);
                    }

                    // PKZIP archive (and derivatives)
                    if (new PKZIP().ShouldScan(magic))
                    {
                        var subProtections = new PKZIP().Scan(this, fs, file);
                        Utilities.PrependToKeys(subProtections, file);
                        Utilities.AppendToDictionary(protections, subProtections);
                    }

                    // RAR archive
                    if (new RAR().ShouldScan(magic))
                    {
                        var subProtections = new RAR().Scan(this, fs, file);
                        Utilities.PrependToKeys(subProtections, file);
                        Utilities.AppendToDictionary(protections, subProtections);
                    }

                    // Tape Archive
                    if (new TapeArchive().ShouldScan(magic))
                    {
                        var subProtections = new TapeArchive().Scan(this, fs, file);
                        Utilities.PrependToKeys(subProtections, file);
                        Utilities.AppendToDictionary(protections, subProtections);
                    }

                    // Valve archive formats
                    if (file != null && new Valve().ShouldScan(magic))
                    {
                        var subProtections = new Valve().Scan(this, file);
                        Utilities.PrependToKeys(subProtections, file);
                        Utilities.AppendToDictionary(protections, subProtections);
                    }

                    // XZ
                    if (new XZ().ShouldScan(magic))
                    {
                        var subProtections = new XZ().Scan(this, fs, file);
                        Utilities.PrependToKeys(subProtections, file);
                        Utilities.AppendToDictionary(protections, subProtections);
                    }
                }

                #endregion
            }

            // Clear out any empty keys
            Utilities.ClearEmptyKeys(protections);

            return(protections);
        }