예제 #1
0
        private static AssemblyInfo SignSingleAssembly(string assemblyPath, string keyPath, string outputDirectory, string password, params string[] probingPaths)
        {
            try
            {
                PrintMessage(null, LogLevel.Verbose);
                PrintMessage(string.Format("Strong-name signing '{0}'...", assemblyPath), LogLevel.Verbose);

                var oldInfo = SigningHelper.GetAssemblyInfo(assemblyPath);
                var newInfo = SigningHelper.SignAssembly(assemblyPath, keyPath, outputDirectory, password, probingPaths);

                if (!oldInfo.IsSigned && newInfo.IsSigned)
                {
                    PrintMessageColor(string.Format("'{0}' was strong-name signed successfully.", newInfo.FilePath), LogLevel.Changes, ConsoleColor.Green);

                    return(newInfo);
                }
                else
                {
                    PrintMessage("Already strong-name signed...", LogLevel.Verbose);
                }
            }
            catch (BadImageFormatException bife)
            {
                PrintMessageColor(string.Format("Warning: {0}", bife.Message), LogLevel.Silent, ConsoleColor.Yellow);
            }
            catch (Exception ex)
            {
                PrintMessageColor(string.Format("Error: {0}", ex.Message), LogLevel.Silent, ConsoleColor.Red);
            }

            return(null);
        }
예제 #2
0
        private static bool TrySignPackagePart(PackagePart packagePart, string keyPath, string keyPassword, bool signedPackage)
        {
            if (packagePart.Uri.ToString().EndsWith(".exe") ||
                packagePart.Uri.ToString().EndsWith(".dll"))
            {
                string tempPath = Path.GetTempFileName();
                try
                {
                    using (var stream = new FileStream(tempPath, FileMode.OpenOrCreate, FileAccess.Write))
                    {
                        packagePart.GetStream().CopyTo(stream);
                    }

                    if (!SigningHelper.GetAssemblyInfo(tempPath).IsSigned)
                    {
                        signedPackage = true;

                        SigningHelper.SignAssembly(tempPath, keyPath ?? string.Empty, Path.GetDirectoryName(tempPath), keyPassword ?? string.Empty);

                        using (var stream = new FileStream(tempPath, FileMode.OpenOrCreate, FileAccess.Read))
                        {
                            stream.CopyTo(packagePart.GetStream(FileMode.Create, FileAccess.Write));
                        }
                    }
                }
                finally
                {
                    File.Delete(tempPath);
                }
            }
            return(signedPackage);
        }
예제 #3
0
        public void SignAssembly_NewLocationWithPdb_Should_Succeed()
        {
            var tempDir = Path.Combine(TestAssemblyDirectory, Guid.NewGuid().ToString("N"));

            Directory.CreateDirectory(tempDir);
            var outDir = Path.Combine(tempDir, "out");

            Directory.CreateDirectory(outDir);
            try
            {
                string sourceAssemblyPath = Path.Combine(tempDir, "Brutal.Dev.StrongNameSigner.TestAssembly.A.dll");
                File.Copy(Path.Combine(TestAssemblyDirectory, "Brutal.Dev.StrongNameSigner.TestAssembly.A.dll"), sourceAssemblyPath);
                File.Copy(Path.Combine(TestAssemblyDirectory, "Brutal.Dev.StrongNameSigner.TestAssembly.A.pdb"), Path.Combine(tempDir, "Brutal.Dev.StrongNameSigner.TestAssembly.A.pdb"));

                SigningHelper.SignAssembly(sourceAssemblyPath, null, outDir);
                string outAssembly = Path.Combine(outDir, Path.GetFileName(sourceAssemblyPath));
                Assert.IsTrue(File.Exists(outAssembly));
                Assert.IsTrue(File.Exists(Path.ChangeExtension(outAssembly, ".pdb")));
                var info = SigningHelper.GetAssemblyInfo(outAssembly);
                Assert.IsTrue(info.IsSigned);
            }
            finally
            {
                Directory.Delete(tempDir, true);
            }
        }
예제 #4
0
        private static bool RemoveInvalidFriendAssemblyReferences(string assemblyPath, string keyFile, string keyFilePassword, params string[] probingPaths)
        {
            try
            {
                PrintMessage(null, LogLevel.Verbose);
                PrintMessage(string.Format("Removing invalid friend references from '{0}'...", assemblyPath), LogLevel.Verbose);

                var info = SigningHelper.GetAssemblyInfo(assemblyPath);
                if (SigningHelper.RemoveInvalidFriendAssemblies(assemblyPath, keyFile, keyFilePassword, probingPaths))
                {
                    PrintMessageColor(string.Format("Invalid friend assemblies removed successfully from '{0}'.", assemblyPath), LogLevel.Changes, ConsoleColor.Green);

                    return(true);
                }
                else
                {
                    PrintMessage("No friend references to fix...", LogLevel.Verbose);
                }
            }
            catch (BadImageFormatException bife)
            {
                PrintMessageColor(string.Format("Warning: {0}", bife.Message), LogLevel.Silent, ConsoleColor.Yellow);
            }
            catch (Exception ex)
            {
                PrintMessageColor(string.Format("Error: {0}", ex.Message), LogLevel.Silent, ConsoleColor.Red);
            }

            return(false);
        }
예제 #5
0
        private void ListViewAssembliesDragDrop(object sender, DragEventArgs e)
        {
            var data = e.Data.GetData(DataFormats.FileDrop) as IEnumerable <string>;

            if (data != null)
            {
                var assemblies = data.Where(d => (Path.GetExtension(d).Equals(".exe", StringComparison.OrdinalIgnoreCase) ||
                                                  Path.GetExtension(d).Equals(".dll", StringComparison.OrdinalIgnoreCase)) &&
                                            File.Exists(d)).ToList();

                // Add all files in directories.
                var directories = data.Where(d => Directory.Exists(d) && File.GetAttributes(d).HasFlag(FileAttributes.Directory)).ToList();
                directories.ForEach(d => assemblies.AddRange(Directory.GetFiles(d, "*.exe", SearchOption.AllDirectories)));
                directories.ForEach(d => assemblies.AddRange(Directory.GetFiles(d, "*.dll", SearchOption.AllDirectories)));

                foreach (var assembly in assemblies)
                {
                    try
                    {
                        AddAssemblyToList(SigningHelper.GetAssemblyInfo(assembly));
                    }
                    catch (BadImageFormatException)
                    {
                        MessageBox.Show(string.Format(CultureInfo.CurrentCulture, "Could not get assembly info for '{0}'. This may not be a .NET assembly.", assembly), "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    }
                }

                ResizeColumnWidths();

                buttonSign.Enabled = listViewAssemblies.Items.Count > 0;
            }
        }
예제 #6
0
        public void GetAssemblyInfo_Detects_Correct_Version_40_Assembly()
        {
            var info = SigningHelper.GetAssemblyInfo(Path.Combine(TestAssemblyDirectory, "Brutal.Dev.StrongNameSigner.TestAssembly.NET40.exe"));

            info.IsManagedAssembly.ShouldBe(true);
            info.DotNetVersion.ShouldBe("4.0.30319");
        }
예제 #7
0
        private static bool FixSingleAssemblyReference(string assemblyPath, string referencePath, string keyFile, string keyFilePassword, params string[] probingPaths)
        {
            try
            {
                PrintMessage(null, LogLevel.Verbose);
                PrintMessage(string.Format("Fixing references to '{1}' in '{0}'...", assemblyPath, referencePath), LogLevel.Verbose);

                var info = SigningHelper.GetAssemblyInfo(assemblyPath);
                if (SigningHelper.FixAssemblyReference(assemblyPath, referencePath, keyFile, keyFilePassword, probingPaths))
                {
                    PrintMessageColor(string.Format("References to '{1}' in '{0}' were fixed successfully.", assemblyPath, referencePath), LogLevel.Changes, ConsoleColor.Green);

                    return(true);
                }
                else
                {
                    PrintMessage("No assembly references to fix...", LogLevel.Verbose);
                }
            }
            catch (BadImageFormatException bife)
            {
                PrintMessageColor(string.Format("Warning: {0}", bife.Message), LogLevel.Silent, ConsoleColor.Yellow);
            }
            catch (Exception ex)
            {
                PrintMessageColor(string.Format("Error: {0}", ex.Message), LogLevel.Silent, ConsoleColor.Red);
            }

            return(false);
        }
예제 #8
0
        public void GetAssemblyInfo_Detects_Signed_40_Assembly()
        {
            var info = SigningHelper.GetAssemblyInfo(Path.Combine(TestAssemblyDirectory, "Brutal.Dev.StrongNameSigner.TestAssembly.NET40-Signed.exe"));

            info.IsSigned.ShouldBe(true);
            info.IsAnyCpu.ShouldBe(true);
        }
예제 #9
0
        public void GetAssemblyInfo_Detects_Obfuscated_Assembly()
        {
            var info = SigningHelper.GetAssemblyInfo(Path.Combine(TestAssemblyDirectory, "Brutal.Dev.StrongNameSigner.TestAssembly.NET40-Obfuscated.exe")); info.IsSigned.ShouldBe(false);

            info.IsAnyCpu.ShouldBe(true);
            info.Is32BitOnly.ShouldBe(false);
            info.Is32BitPreferred.ShouldBe(false);
            info.Is64BitOnly.ShouldBe(false);
        }
예제 #10
0
        public void GetAssemblyInfo_Public_API_Test()
        {
            var info = SigningHelper.GetAssemblyInfo(Path.Combine(TestAssemblyDirectory, "Brutal.Dev.StrongNameSigner.TestAssembly.NET20.exe"));

            info.ShouldNotBe(null);
            info.DotNetVersion.ShouldBe("2.0.50727");
            info.Is32BitOnly.ShouldBe(false);
            info.Is32BitPreferred.ShouldBe(false);
            info.Is64BitOnly.ShouldBe(false);
            info.IsAnyCpu.ShouldBe(true);
            info.IsSigned.ShouldBe(false);
        }
예제 #11
0
        private void ButtonAddClick(object sender, EventArgs e)
        {
            if (CommonOpenFileDialog.IsPlatformSupported)
            {
                using (CommonOpenFileDialog dialog = new CommonOpenFileDialog())
                {
                    dialog.Title            = openFileDialogAssembly.Title;
                    dialog.DefaultExtension = openFileDialogAssembly.DefaultExt;
                    dialog.Filters.Add(new CommonFileDialogFilter("Assembly files", "*.exe;*.dll"));
                    dialog.EnsurePathExists = true;
                    dialog.EnsureValidNames = true;
                    dialog.IsFolderPicker   = false;
                    dialog.Multiselect      = true;

                    if (dialog.ShowDialog() == CommonFileDialogResult.Ok)
                    {
                        foreach (var file in dialog.FileNames)
                        {
                            try
                            {
                                AddAssemblyToList(SigningHelper.GetAssemblyInfo(file));
                            }
                            catch (BadImageFormatException)
                            {
                                MessageBox.Show(string.Format(CultureInfo.CurrentCulture, "Could not get assembly info for '{0}'. This may not be a .NET assembly.", file), "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                            }
                        }
                    }
                }
            }
            else
            {
                if (openFileDialogAssembly.ShowDialog() == DialogResult.OK)
                {
                    foreach (var file in openFileDialogAssembly.FileNames)
                    {
                        try
                        {
                            AddAssemblyToList(SigningHelper.GetAssemblyInfo(file));
                        }
                        catch (BadImageFormatException)
                        {
                            MessageBox.Show(string.Format(CultureInfo.CurrentCulture, "Could not get assembly info for '{0}'. This may not be a .NET assembly.", file), "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                        }
                    }
                }
            }

            ResizeColumnWidths();

            buttonSign.Enabled = listViewAssemblies.Items.Count > 0;
        }
예제 #12
0
        public void SignAssembly_InPlaceWithoutPdb_Should_Succeed()
        {
            var tempDir = Path.Combine(TestAssemblyDirectory, Guid.NewGuid().ToString("N"));

            Directory.CreateDirectory(tempDir);
            try
            {
                string targetAssemblyPath = Path.Combine(tempDir, "Brutal.Dev.StrongNameSigner.TestAssembly.A.dll");
                File.Copy(Path.Combine(TestAssemblyDirectory, "Brutal.Dev.StrongNameSigner.TestAssembly.A.dll"), targetAssemblyPath);

                SigningHelper.SignAssembly(targetAssemblyPath);
                var info = SigningHelper.GetAssemblyInfo(targetAssemblyPath);
                Assert.IsTrue(info.IsSigned);
            }
            finally
            {
                Directory.Delete(tempDir, true);
            }
        }
예제 #13
0
        private static bool SignSingleAssembly(string assemblyPath, string keyPath, string outputDirectory)
        {
            try
            {
                C.WriteLine();
                C.WriteLine("Strong-name signing {0}...", assemblyPath);

                var info = SigningHelper.GetAssemblyInfo(assemblyPath);
                if (!info.IsSigned)
                {
                    info = SigningHelper.SignAssembly(assemblyPath, keyPath, outputDirectory);

                    C.ForegroundColor = ConsoleColor.Green;
                    C.WriteLine("{0} was strong-name signed successfully!", info.FilePath);
                    C.ResetColor();

                    return(true);
                }
                else
                {
                    C.WriteLine("Already strong-name signed...");
                }
            }
            catch (BadImageFormatException bife)
            {
                C.ForegroundColor = ConsoleColor.Yellow;
                C.WriteLine("Warning: {0}", bife.Message);
                C.ResetColor();
            }
            catch (Exception ex)
            {
                C.ForegroundColor = ConsoleColor.Red;
                C.WriteLine("Error: {0}", ex.Message);
                C.ResetColor();
            }

            return(false);
        }
예제 #14
0
        private static bool FixSingleAssemblyReference(string assemblyPath, string referencePath)
        {
            try
            {
                C.WriteLine();
                C.WriteLine("Fixing references to '{1}' in '{0}'...", assemblyPath, referencePath);

                var info = SigningHelper.GetAssemblyInfo(assemblyPath);
                if (SigningHelper.FixAssemblyReference(assemblyPath, referencePath))
                {
                    C.ForegroundColor = ConsoleColor.Green;
                    C.WriteLine("References were fixed successfully!");
                    C.ResetColor();

                    return(true);
                }
                else
                {
                    C.WriteLine("Nothing to fix...");
                }
            }
            catch (BadImageFormatException bife)
            {
                C.ForegroundColor = ConsoleColor.Yellow;
                C.WriteLine("Warning: {0}", bife.Message);
                C.ResetColor();
            }
            catch (Exception ex)
            {
                C.ForegroundColor = ConsoleColor.Red;
                C.WriteLine("Error: {0}", ex.Message);
                C.ResetColor();
            }

            return(false);
        }
예제 #15
0
        private void BackgroundWorkerDoWork(object sender, DoWorkEventArgs e)
        {
            e.Result = string.Empty;

            int progress       = 0;
            int signedFiles    = 0;
            int referenceFixes = 0;
            var assemblies     = e.Argument as IEnumerable <string>;

            if (assemblies != null)
            {
                // We go through assemblies twice and every assembly -1 for reference fixes.
                double progressMax = assemblies.Count() + (assemblies.Count() * (assemblies.Count() - 1));

                foreach (var assembly in assemblies)
                {
                    AssemblyInfo info = null;

                    try
                    {
                        log.AppendFormat("Strong-name signing {0}...", assembly).AppendLine();

                        info = SigningHelper.GetAssemblyInfo(assembly);
                        if (!info.IsSigned)
                        {
                            info = SigningHelper.SignAssembly(assembly, keyFile, outputPath);
                            log.Append("Strong-name signed successfully.").AppendLine();
                            signedFiles++;
                        }
                        else
                        {
                            log.Append("Already strong-name signed...").AppendLine();
                        }
                    }
                    catch (Exception ex)
                    {
                        log.AppendFormat("Error strong-name signing {0}: {1}", assembly, ex.Message).AppendLine();
                    }

                    backgroundWorker.ReportProgress(Convert.ToInt32((++progress / progressMax) * 100), info);

                    if (backgroundWorker.CancellationPending)
                    {
                        e.Cancel = true;
                        break;
                    }
                }

                var referencesToFix = new List <string>(assemblies);
                foreach (var assembly in assemblies)
                {
                    // Go through all the references excluding the file we are working on.
                    foreach (var reference in referencesToFix.Where(r => !r.Equals(assembly)))
                    {
                        backgroundWorker.ReportProgress(Convert.ToInt32((++progress / progressMax) * 100));

                        if (backgroundWorker.CancellationPending)
                        {
                            e.Cancel = true;
                            break;
                        }

                        log.AppendFormat("Fixing references to {1} in {0}...", assembly, reference).AppendLine();
                        if (SigningHelper.FixAssemblyReference(assembly, reference))
                        {
                            log.Append("Reference was found and fixed.").AppendLine();
                            referenceFixes++;
                        }
                        else
                        {
                            log.Append("Nothing to fix.").AppendLine();
                        }
                    }
                }

                e.Result = string.Format(CultureInfo.CurrentCulture, "{0} out of {1} assemblies were strong-name signed and {2} references were fixed.", signedFiles, assemblies.Count(), referenceFixes);
            }
        }
예제 #16
0
 public void GetAssemblyInfo_Public_API_Invalid_File_Should_Throw_Exception()
 {
     Assert.Throws <BadImageFormatException>(() => SigningHelper.GetAssemblyInfo(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "calc.exe")));
 }
예제 #17
0
 public void GetAssemblyInfo_Public_API_Invalid_Path_Should_Throw_Exception()
 {
     Assert.Throws <FileNotFoundException>(() => SigningHelper.GetAssemblyInfo(Path.Combine(TestAssemblyDirectory, "Brutal.Dev.StrongNameSigner.TestAssembly.NET20.doesnotexist")));
 }
예제 #18
0
        private void BackgroundWorkerDoWork(object sender, DoWorkEventArgs e)
        {
            e.Result = string.Empty;

            int progress               = 0;
            int signedFiles            = 0;
            int referenceFixes         = 0;
            var processedAssemblyPaths = new HashSet <string>(StringComparer.OrdinalIgnoreCase);
            var signedAssemblyPaths    = new HashSet <string>(StringComparer.OrdinalIgnoreCase);

            if (e.Argument is IEnumerable <string> assemblyPaths)
            {
                var probingPaths = assemblyPaths.Select(f => Path.GetDirectoryName(f)).Distinct().ToArray();

                // We go through assemblies three times and every assembly -1 for reference fixes.
                double progressMax = (assemblyPaths.Count() + (assemblyPaths.Count() * (assemblyPaths.Count() - 1))) * 3;

                foreach (var filePath in assemblyPaths)
                {
                    var assemblyPair = new AssemblyPair();

                    try
                    {
                        log.AppendFormat("Strong-name signing {0}...", filePath).AppendLine();

                        assemblyPair.OldInfo = SigningHelper.GetAssemblyInfo(filePath);
                        assemblyPair.NewInfo = SigningHelper.SignAssembly(filePath, keyFile, outputPath, password, probingPaths);

                        if (assemblyPair.NewInfo.SigningType == StrongNameType.DelaySigned)
                        {
                            log.Append("Delay-signed assembly signing is not supported yet...").AppendLine();
                        }
                        else if (!assemblyPair.OldInfo.IsSigned && assemblyPair.NewInfo.IsSigned)
                        {
                            log.Append("Strong-name signed successfully.").AppendLine();
                            signedAssemblyPaths.Add(assemblyPair.NewInfo.FilePath);
                            signedFiles++;
                        }
                        else
                        {
                            log.Append("Already strong-name signed...").AppendLine();
                        }

                        processedAssemblyPaths.Add(assemblyPair.NewInfo.FilePath);
                    }
                    catch (Exception ex)
                    {
                        log.AppendFormat("Error strong-name signing {0}: {1}", filePath, ex.Message).AppendLine();
                    }

                    backgroundWorker.ReportProgress(Convert.ToInt32((++progress / progressMax) * 100), assemblyPair);

                    if (backgroundWorker.CancellationPending)
                    {
                        e.Cancel = true;
                        break;
                    }
                }

                var referencesToFix = new HashSet <string>(processedAssemblyPaths, StringComparer.OrdinalIgnoreCase);
                foreach (var filePath in processedAssemblyPaths)
                {
                    // Go through all the references excluding the file we are working on.
                    foreach (var reference in referencesToFix.Where(r => !r.Equals(filePath)))
                    {
                        backgroundWorker.ReportProgress(Convert.ToInt32((++progress / progressMax) * 100));

                        if (backgroundWorker.CancellationPending)
                        {
                            e.Cancel = true;
                            break;
                        }

                        log.AppendFormat("Fixing references to {1} in {0}...", filePath, reference).AppendLine();
                        if (SigningHelper.FixAssemblyReference(filePath, reference, keyFile, password, probingPaths))
                        {
                            log.Append("Reference was found and fixed.").AppendLine();
                            referenceFixes++;
                        }
                        else
                        {
                            log.Append("Nothing to fix.").AppendLine();
                        }
                    }
                }

                // Go through all processed assemblies and remove invalid friend references.
                foreach (var filePath in signedAssemblyPaths)
                {
                    backgroundWorker.ReportProgress(Convert.ToInt32((++progress / progressMax) * 100));

                    if (backgroundWorker.CancellationPending)
                    {
                        e.Cancel = true;
                        break;
                    }

                    log.AppendFormat("Removing invalid friend references from '{0}'...", filePath).AppendLine();
                    if (SigningHelper.RemoveInvalidFriendAssemblies(filePath, keyFile, password, probingPaths))
                    {
                        log.Append("Invalid friend assemblies removed.").AppendLine();
                        referenceFixes++;
                    }
                    else
                    {
                        log.Append("Nothing to fix.").AppendLine();
                    }
                }

                e.Result = string.Format(CultureInfo.CurrentCulture, "{0} out of {1} assemblies were strong-name signed and {2} references were fixed.", signedFiles, assemblyPaths.Count(), referenceFixes);
            }
        }