internal static void WriteModule(StrongNameKeyPair keyPair, byte[] publicKey, ModuleBuilder moduleBuilder, PEFileKinds fileKind, PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine, ResourceSection resources, int entryPointToken, Stream stream) { if (stream == null) { string fileName = moduleBuilder.FullyQualifiedName; bool mono = System.Type.GetType("Mono.Runtime") != null; if (mono) { try { // Mono mmaps the file, so unlink the previous version since it may be in use File.Delete(fileName); } catch { } } using (FileStream fs = new FileStream(fileName, FileMode.Create)) { WriteModuleImpl(keyPair, publicKey, moduleBuilder, fileKind, portableExecutableKind, imageFileMachine, resources, entryPointToken, fs); } // if we're running on Mono, mark the module as executable by using a Mono private API extension if (mono) { File.SetAttributes(fileName, (FileAttributes)(unchecked((int)0x80000000))); } } else { WriteModuleImpl(keyPair, publicKey, moduleBuilder, fileKind, portableExecutableKind, imageFileMachine, resources, entryPointToken, stream); } }
public void Execute() { var keyFilePath = GetKeyFilePath(); if (keyFilePath != null) { if (!File.Exists(keyFilePath)) { throw new WeavingException(string.Format("KeyFilePath was defined but file does not exist. '{0}'.", keyFilePath)); } StrongNameKeyPair = new StrongNameKeyPair(File.OpenRead(keyFilePath)); } }
public virtual void FindStrongNameKey() { if (!SignAssembly) { return; } var keyFilePath = GetKeyFilePath(); if (keyFilePath != null) { if (!File.Exists(keyFilePath)) { throw new WeavingException(string.Format("KeyFilePath was defined but file does not exist. '{0}'.", keyFilePath)); } StrongNameKeyPair = new StrongNameKeyPair(File.OpenRead(keyFilePath)); } }
internal static void WriteModule(StrongNameKeyPair keyPair, byte[] publicKey, ModuleBuilder moduleBuilder, PEFileKinds fileKind, PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine, ResourceSection resources, int entryPointToken, Stream stream) { if (stream == null) { using (FileStream fs = new FileStream(moduleBuilder.FullyQualifiedName, FileMode.Create)) { WriteModuleImpl(keyPair, publicKey, moduleBuilder, fileKind, portableExecutableKind, imageFileMachine, resources, entryPointToken, fs); } } else { WriteModuleImpl(keyPair, publicKey, moduleBuilder, fileKind, portableExecutableKind, imageFileMachine, resources, entryPointToken, stream); } }
public virtual void FindStrongNameKey() { if (!SignAssembly) { return; } var keyFilePath = GetKeyFilePath(); if (keyFilePath != null) { if (!File.Exists(keyFilePath)) { throw new WeavingException(string.Format("KeyFilePath was defined but file does not exist. '{0}'.", keyFilePath)); } StrongNameKeyPair = new StrongNameKeyPair(File.OpenRead(keyFilePath)); } }
private void SetAssemblyNamePublicKey(AssemblyNameReference anr, StrongNameKeyPair sn) { if (sn == null) { anr.Attributes &= ~AssemblyAttributes.PublicKey; anr.HashAlgorithm = AssemblyHashAlgorithm.None; anr.PublicKey = null; } else { anr.Attributes &= AssemblyAttributes.PublicKey; anr.HashAlgorithm = AssemblyHashAlgorithm.SHA1; //PublicKey must be null when save, or AssemblyNameReference saved wrong anr.PublicKey = null; anr.PublicKeyToken = TokenUtils.GetPublicKeyToken(sn.PublicKey, AssemblyHashAlgorithm.SHA1); } }
public void ConstructorInvalidFileStream() { FileStream testFile = new FileStream(file, FileMode.OpenOrCreate); byte[] badheader = { 0xB, 0xAD }; testFile.Write(badheader, 0, badheader.Length); testFile.Write(test, 0, test.Length); testFile.Close(); // doesn't work on DLL files (actually it works on SNK files) FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); snpk = new StrongNameKeyPair(fs); fs.Close(); Assert.AreEqual(BitConverter.ToString(pk), BitConverter.ToString(snpk.PublicKey), "#1"); }
public static void Main() { // Open a file that contains a public key value. The line below // assumes that the Strong Name tool (SN.exe) was executed from // a command prompt as follows: // SN.exe -k C:\Company.keys FileStream fs = File.Open("C:\\Company.keys", FileMode.Open); // Construct a StrongNameKeyPair object. This object should obtain // the public key from the Company.keys file. StrongNameKeyPair k = new StrongNameKeyPair(fs); // Display the bytes that make up the public key. Console.WriteLine(BitConverter.ToString(k.PublicKey)); // Close the file. fs.Close(); }
public static void SignGendarmeFramework(string baseFolder) { var key = Path.Combine(baseFolder, StrongNameKey); var assembly = Path.Combine(baseFolder, SourceFolder, "Gendarme.Framework.dll"); var newAssembly = Path.Combine(baseFolder, TargetFolder, "Gendarme.Framework.dll"); assembly = Path.GetFullPath(assembly); newAssembly = Path.GetFullPath(newAssembly); File.Copy(assembly, newAssembly, true); var definition = AssemblyDefinition.ReadAssembly(newAssembly); var keyPair = new StrongNameKeyPair(new FileStream(key, FileMode.Open, FileAccess.Read)); definition.Write(newAssembly, new WriterParameters() { StrongNameKeyPair = keyPair }); }
public static RSA CreateRSA(this StrongNameKeyPair key_pair) { byte [] key; string key_container; if (!TryGetKeyContainer(key_pair, out key, out key_container)) { return(CryptoConvert.FromCapiKeyBlob(key)); } var parameters = new CspParameters { Flags = CspProviderFlags.UseMachineKeyStore, KeyContainerName = key_container, KeyNumber = 2, }; return(new RSACryptoServiceProvider(parameters)); }
private static void CheckSignedSavedAssembly(string path) { Assert.IsTrue(File.Exists(path)); var assemblyName = AssemblyName.GetAssemblyName(path); Assert.AreEqual(ModuleScope.DEFAULT_ASSEMBLY_NAME, assemblyName.Name); var keyPairBytes = ModuleScope.GetKeyPair(); var keyPair = new StrongNameKeyPair(keyPairBytes); var loadedPublicKey = assemblyName.GetPublicKey(); Assert.AreEqual(keyPair.PublicKey.Length, loadedPublicKey.Length); for (var i = 0; i < keyPair.PublicKey.Length; ++i) { Assert.AreEqual(keyPair.PublicKey[i], loadedPublicKey[i]); } }
public static RSA CreateRSA(this StrongNameKeyPair key_pair) { byte[] blob; string keyContainerName; if (!Mixin.TryGetKeyContainer(key_pair, out blob, out keyContainerName)) { return(CryptoConvert.FromCapiKeyBlob(blob)); } CspParameters parameters = new CspParameters { Flags = CspProviderFlags.UseMachineKeyStore, KeyContainerName = keyContainerName, KeyNumber = 2 }; return(new RSACryptoServiceProvider(parameters)); }
private static void Main(string[] args) { var assemblyName = AssemblyName.GetAssemblyName(@"C:\Users\Hellsing\OneDrive\Development\EloBuddy\Loader\System\EloBuddy.SDK.dll"); Clipboard.SetText(assemblyName.GetPublicKey().ToHex()); return; //using (var stream = File.OpenRead(@"C:\Users\Hellsing\OneDrive\Development\EloBuddy\EloBuddy.SDK\EloBuddy.SDK\EloBuddy.SDK.snk")) using (var stream = File.OpenRead(@"C:\Users\Hellsing\OneDrive\Development\EloBuddy\Loader\System\SharpDX.dll")) { var keyBytes = new byte[stream.Length]; stream.Read(keyBytes, 0, (int)stream.Length); var kp = new StrongNameKeyPair(keyBytes); Clipboard.SetText(kp.PublicKey.ToHex()); } }
/// <summary> /// Возвращает контент публичного ключа. /// </summary> /// <param name="snk"></param> /// <returns></returns> private byte[] GetPublicKeyToken(byte[] snk) { StrongNameKeyPair skp = new StrongNameKeyPair(snk); using (var csp = new SHA1CryptoServiceProvider()) { byte[] hash = csp.ComputeHash(skp.PublicKey); byte[] token = new byte[8]; for (int i = 0; i < 8; i++) { token[i] = hash[hash.Length - i - 1]; } return(token); } }
internal AssemblyBuilder(Universe universe, AssemblyName name, string dir, IEnumerable <CustomAttributeBuilder> customAttributes) : base(universe) { this.name = name.Name; SetVersionHelper(name.Version); if (!string.IsNullOrEmpty(name.Culture)) { this.culture = name.Culture; } this.flags = name.RawFlags; this.hashAlgorithm = name.HashAlgorithm; if (this.hashAlgorithm == AssemblyHashAlgorithm.None) { this.hashAlgorithm = AssemblyHashAlgorithm.SHA1; } this.keyPair = name.KeyPair; if (this.keyPair != null) { this.publicKey = this.keyPair.PublicKey; } else { byte[] publicKey = name.GetPublicKey(); if (publicKey != null && publicKey.Length != 0) { this.publicKey = (byte[])publicKey.Clone(); } } this.dir = dir ?? "."; if (customAttributes != null) { this.customAttributes.AddRange(customAttributes); } if (universe.HasMscorlib && !universe.Mscorlib.__IsMissing && universe.Mscorlib.ImageRuntimeVersion != null) { this.imageRuntimeVersion = universe.Mscorlib.ImageRuntimeVersion; } else { this.imageRuntimeVersion = typeof(object).Assembly.ImageRuntimeVersion; } universe.RegisterDynamicAssembly(this); }
internal static void FindStrongNameKey(WeaverConfig?config, AssemblyDefinition asm, ILogger log, out StrongNameKeyPair?keyPair, out byte[]?publicKey) { keyPair = null; publicKey = null; if (config == null || !config.SignAssembly) { return; } var keyFilePath = GetKeyFilePath(config, asm, log); if (keyFilePath == null) { return; } if (!File.Exists(keyFilePath)) { throw new FileNotFoundException("KeyFilePath was defined but file does not exist.", keyFilePath); } var fileBytes = File.ReadAllBytes(keyFilePath); keyPair = new StrongNameKeyPair(fileBytes); try { publicKey = keyPair.PublicKey; } catch (ArgumentException e) { log.Debug(e, "Exception while trying to load strong-name key pair."); keyPair = null; publicKey = fileBytes; } catch (NotSupportedException) { log.Warning("Sigourney does not support strong naming on some platforms like .NET Core-based MSBuild."); throw; } }
internal static void ReadKeyFile(TaskLoggingHelper log, string keyFile, out StrongNameKeyPair keyPair, out byte[] publicKey) { byte[] buffer; keyPair = null; publicKey = null; try { using (FileStream stream = new FileStream(keyFile, FileMode.Open, FileAccess.Read, FileShare.Read)) { buffer = new byte[(int)stream.Length]; stream.Read(buffer, 0, (int)stream.Length); } } catch (ArgumentException exception) { log.LogErrorWithCodeFromResources("StrongNameUtils.KeyFileReadFailure", new object[] { keyFile }); log.LogErrorFromException(exception); throw new StrongNameException(exception); } catch (IOException exception2) { log.LogErrorWithCodeFromResources("StrongNameUtils.KeyFileReadFailure", new object[] { keyFile }); log.LogErrorFromException(exception2); throw new StrongNameException(exception2); } catch (SecurityException exception3) { log.LogErrorWithCodeFromResources("StrongNameUtils.KeyFileReadFailure", new object[] { keyFile }); log.LogErrorFromException(exception3); throw new StrongNameException(exception3); } StrongNameKeyPair pair = new StrongNameKeyPair(buffer); try { publicKey = pair.PublicKey; keyPair = pair; } catch (ArgumentException) { publicKey = buffer; } }
private static AssemblyName GetAssemblyName() { StrongNameKeyPair kp; // Getting this from a resource would be a good idea. using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Mapster.Tests.mock.keys")) using (var mem = new MemoryStream()) { stream.CopyTo(mem); mem.Position = 0; kp = new StrongNameKeyPair(mem.ToArray()); } var name = "Mapster.Dynamic"; return(new AssemblyName(name) { KeyPair = kp }); }
public AssemblyBuilder ConvertTypeLibToAssembly([MarshalAs(UnmanagedType.Interface)] Object typeLib, String asmFileName, int flags, ITypeLibImporterNotifySink notifySink, byte[] publicKey, StrongNameKeyPair keyPair, bool unsafeInterfaces) { return(ConvertTypeLibToAssembly(typeLib, asmFileName, (unsafeInterfaces ? TypeLibImporterFlags.UnsafeInterfaces : 0), notifySink, publicKey, keyPair, null, null)); }
/// <summary> /// Given our KeyFile, KeyContainer, and DelaySign parameters, generate the public / private /// key pair and validate that it exists to the extent needed. /// </summary> internal void GetAndValidateStrongNameKey(out StrongNameKeyPair keyPair, out byte[] publicKey) { keyPair = null; publicKey = null; // get key pair/public key StrongNameUtils.GetStrongNameKey(Log, KeyFile, KeyContainer, out keyPair, out publicKey); // make sure we give as much data to the typelib converter as necessary but not more, or we might end up // with something we didn't want if (DelaySign) { keyPair = null; if (publicKey == null) { Log.LogErrorWithCodeFromResources(null, ReferenceInfo.SourceItemSpec, 0, 0, 0, 0, "StrongNameUtils.NoPublicKeySpecified"); throw new StrongNameException(); } } else { publicKey = null; // If the user did not specify delay sign and we didn't get a public/private // key pair then we have an error since a public key by itself is not enough // to fully sign the assembly. (only if either KeyContainer or KeyFile was specified though) if (keyPair == null) { if (!string.IsNullOrEmpty(KeyContainer)) { Log.LogErrorWithCodeFromResources(null, ReferenceInfo.SourceItemSpec, 0, 0, 0, 0, "ResolveComReference.StrongNameUtils.NoKeyPairInContainer", KeyContainer); throw new StrongNameException(); } if (!string.IsNullOrEmpty(KeyFile)) { Log.LogErrorWithCodeFromResources(null, ReferenceInfo.SourceItemSpec, 0, 0, 0, 0, "ResolveComReference.StrongNameUtils.NoKeyPairInFile", KeyFile); throw new StrongNameException(); } } } }
public void Execute() { if (config.KeyFilePath == null) { var projectFilePath = buildEnginePropertyExtractor.GetProjectPath(); if (!IsSignAssemblyTrue(projectFilePath)) { return; } var assemblyOriginatorKeyFile = GetKeyFile(projectFilePath); if (assemblyOriginatorKeyFile == null) { return; } config.KeyFilePath = Path.Combine(Path.GetDirectoryName(projectFilePath), assemblyOriginatorKeyFile); } StrongNameKeyPair = new StrongNameKeyPair(File.OpenRead(config.KeyFilePath)); }
/// <summary> /// Method to generate strong key file. /// </summary> /// <param name="name">The string that include de source file name, wich will be the key file name. Null means that will be used the default name.</param> /// <returns>bool</returns> public static string create_strong_key(string nameWithoutExtension, string userName, string password, string curDir) { // string nameWithoutExtension = name.Split('.')[0]; String snkFileName = Constants.PATH_TEMP_WORKER + nameWithoutExtension + ".snk"; if (!File.Exists(snkFileName)) { runCommand(Constants.key_generator, "-k " + snkFileName, userName, password, curDir); } FileStream f = File.Open(snkFileName, FileMode.Open); StrongNameKeyPair rr = new StrongNameKeyPair(f); string skp = BitConverter.ToString(rr.PublicKey); f.Close(); return(skp.Replace("-", "")); }
private void Sign(string file, StrongNameKeyPair sn) { AssemblyDefinition ad = AssemblyDefinition.ReadAssembly(file); AssemblyNameDefinition adName = ad.Name; _allAssemblies.Add(file, ad); adName.HashAlgorithm = AssemblyHashAlgorithm.SHA1; adName.PublicKey = sn.PublicKey; ad.Name.Attributes &= AssemblyAttributes.PublicKey; //foreach (ModuleDefinition md in ad.Modules) //{ // md.Image.CLIHeader.Flags &= ~Mono.Cecil.Binary.RuntimeImage.StrongNameSigned; //} _changedAssemblies.Add(adName.Name, 1); Options.AppendTextInfo(String.Format("Assembly signed: {0}\r\n", adName.FullName)); Application.DoEvents(); }
public static StrongNameKeyPair GetKeyPair(MetadataReader mr) { // sanity checks: if (!IsMrValid(mr)) { return(null); } try { FileStream oKeyPairFileStream = File.OpenRead("FileName"); System.Reflection.StrongNameKeyPair oKeyPairFile = new StrongNameKeyPair(oKeyPairFileStream); oKeyPairFileStream.Close(); return(oKeyPairFile); } catch (Exception exc) { return(null); } }
public void Sign() { ValidateFilesExist(); var snk = new StrongNameKeyPair(File.ReadAllBytes(pathToSnk)); var assemblyDef = AssemblyDefinition.ReadAssembly(pathToAssembly); assemblyDef.Name.HashAlgorithm = AssemblyHashAlgorithm.SHA1; assemblyDef.Name.PublicKey = snk.PublicKey; assemblyDef.Name.HasPublicKey = true; assemblyDef.Name.Attributes &= AssemblyAttributes.PublicKey; assemblyDef.Write(outputFile); //Mono.Cecil. //assemblyDef.Name.Flags &= AssemblyFlags.PublicKey; //AssemblyFactory.SaveAssembly(assemblyDef, outputFile); }
public void Execute() { if (config.KeyFilePath == null) { var projectFilePath = buildEnginePropertyExtractor.GetProjectPath(); if (!IsSignAssemblyTrue(projectFilePath)) { return; } var assemblyOriginatorKeyFile = GetKeyFile(projectFilePath); if (assemblyOriginatorKeyFile == null) { return; } config.KeyFilePath = Path.Combine(Path.GetDirectoryName(projectFilePath), assemblyOriginatorKeyFile); } StrongNameKeyPair = new StrongNameKeyPair(File.OpenRead(config.KeyFilePath)); }
public void ReadProjectKey() { if (KeyFilePath == null) { var projectFilePath = GetProjectPath(); if (!IsSignAssemblyTrue(projectFilePath)) { return; } var assemblyOriginatorKeyFile = GetKeyFile(projectFilePath); if (assemblyOriginatorKeyFile == null) { return; } KeyFilePath = Path.Combine(Path.GetDirectoryName(projectFilePath), assemblyOriginatorKeyFile); } StrongNameKeyPair = new StrongNameKeyPair(File.OpenRead(KeyFilePath)); }
public void Perform() { if (_repackOptions.KeyContainer != null || (_repackOptions.KeyFile != null && File.Exists(_repackOptions.KeyFile))) { var snkp = default(StrongNameKeyPair); var publicKey = default(byte[]); if (_repackOptions.KeyContainer != null) { snkp = new StrongNameKeyPair(_repackOptions.KeyContainer); } else if (_repackOptions.KeyFile != null && File.Exists(_repackOptions.KeyFile)) { var keyFileContents = File.ReadAllBytes(_repackOptions.KeyFile); try { snkp = new StrongNameKeyPair(keyFileContents); publicKey = snkp.PublicKey; } catch (ArgumentException) { snkp = null; if (_repackOptions.DelaySign) { publicKey = keyFileContents; } } } _repackContext.TargetAssemblyDefinition.Name.PublicKey = publicKey; _repackContext.TargetAssemblyDefinition.Name.Attributes |= AssemblyAttributes.PublicKey; _repackContext.TargetAssemblyMainModule.Attributes |= ModuleAttributes.StrongNameSigned; if (!_repackOptions.DelaySign) { KeyPair = snkp; } } else { _repackContext.TargetAssemblyDefinition.Name.PublicKey = null; _repackContext.TargetAssemblyMainModule.Attributes &= ~ModuleAttributes.StrongNameSigned; } }
public static void SignGendarmeRulesMaintainability(string baseFolder) { var frameworkAssembly = Path.Combine(baseFolder, TargetFolder, "Gendarme.Framework.dll"); var frameworkDefinition = AssemblyDefinition.ReadAssembly(frameworkAssembly); var frameworkAssemblyRef = AssemblyNameReference.Parse(frameworkDefinition.Name.ToString()); var key = Path.Combine(baseFolder, StrongNameKey); var assembly = Path.Combine(baseFolder, SourceFolder, "Gendarme.Rules.Maintainability.dll"); var newAssembly = Path.Combine(baseFolder, TargetFolder, "Gendarme.Rules.Maintainability.dll"); assembly = Path.GetFullPath(assembly); newAssembly = Path.GetFullPath(newAssembly); File.Copy(assembly, newAssembly, true); var definition = AssemblyDefinition.ReadAssembly(newAssembly); // update all type references to the now signed base assembly foreach (var typeReference in definition.MainModule.GetTypeReferences()) { if (typeReference.Scope.Name == frameworkDefinition.Name.Name) { typeReference.Scope = frameworkAssemblyRef; } } // update assembly references to use the now signed base assembly var oldReference = definition.MainModule.AssemblyReferences.FirstOrDefault(x => x.Name == frameworkDefinition.Name.Name); if (oldReference != null) { definition.MainModule.AssemblyReferences.Remove(oldReference); definition.MainModule.AssemblyReferences.Add(frameworkAssemblyRef); } var keyPair = new StrongNameKeyPair(new FileStream(key, FileMode.Open, FileAccess.Read)); definition.Write(newAssembly, new WriterParameters() { StrongNameKeyPair = keyPair }); }
internal AssemblyBuilder(Universe universe, AssemblyName name, string dir, PermissionSet requiredPermissions, PermissionSet optionalPermissions, PermissionSet refusedPermissions) : base(universe) { this.name = name.Name; SetVersionHelper(name.Version); if (!string.IsNullOrEmpty(name.Culture)) { this.culture = name.Culture; } this.flags = name.RawFlags; this.hashAlgorithm = name.HashAlgorithm; if (this.hashAlgorithm == AssemblyHashAlgorithm.None) { this.hashAlgorithm = AssemblyHashAlgorithm.SHA1; } this.keyPair = name.KeyPair; if (this.keyPair != null) { this.publicKey = this.keyPair.PublicKey; } else { byte[] publicKey = name.GetPublicKey(); if (publicKey != null && publicKey.Length != 0) { this.publicKey = (byte[])publicKey.Clone(); } } this.dir = dir ?? "."; this.requiredPermissions = requiredPermissions; this.optionalPermissions = optionalPermissions; this.refusedPermissions = refusedPermissions; if (universe.HasMscorlib && !universe.Mscorlib.__IsMissing && universe.Mscorlib.ImageRuntimeVersion != null) { this.imageRuntimeVersion = universe.Mscorlib.ImageRuntimeVersion; } else { this.imageRuntimeVersion = typeof(object).Assembly.ImageRuntimeVersion; } }
/// <summary>Saves the assembly.</summary> /// <param name="assembly">The assembly.</param> /// <param name="assemblyFileName">Name of the assembly file.</param> /// <param name="keyPair">The key pair.</param> public static void SaveAssembly( AssemblyDefinition assembly, string assemblyFileName, StrongNameKeyPair keyPair = null) { var tempFileName = String.Format("{0}.{1:N}", assemblyFileName, Guid.NewGuid()); try { if (keyPair == null) { Log.Debug("Saving '{0}'", assemblyFileName); assembly.Write(tempFileName); } else { Log.Debug("Saving and signing '{0}'", assemblyFileName); assembly.Write(tempFileName, new WriterParameters { StrongNameKeyPair = keyPair }); } File.Delete(assemblyFileName); File.Move(tempFileName, assemblyFileName); // TODO:MAK pdb may also be merged, but it's not a priority for me. // I need to deleted in though as it no longer matches assembly var pdbFileName = Path.ChangeExtension(assemblyFileName, "pdb"); if (File.Exists(pdbFileName)) { DeleteFile(pdbFileName); } } catch { if (File.Exists(tempFileName)) { DeleteFile(tempFileName); } throw; } }
internal static void WriteModule(StrongNameKeyPair keyPair, byte[] publicKey, ModuleBuilder moduleBuilder, PEFileKinds fileKind, PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine, ResourceSection resources, int entryPointToken, Stream stream) { if (stream == null) { using (FileStream fs = new FileStream(moduleBuilder.FullyQualifiedName, FileMode.Create)) { WriteModuleImpl(keyPair, publicKey, moduleBuilder, fileKind, portableExecutableKind, imageFileMachine, resources, entryPointToken, fs); } // if we're running on Mono, mark the module as executable by using a Mono private API extension if (System.Type.GetType("Mono.Runtime") != null) { File.SetAttributes(moduleBuilder.FullyQualifiedName, (FileAttributes)(unchecked((int)0x80000000))); } } else { WriteModuleImpl(keyPair, publicKey, moduleBuilder, fileKind, portableExecutableKind, imageFileMachine, resources, entryPointToken, stream); } }
public void Can_sign_using_keyfile() { // ARRANGE var outputFile = Path.Combine(TestContext.DeploymentDirectory, Path.ChangeExtension(Path.GetRandomFileName(), Extension)); var ilMerge = new ILMerge { KeyFile = "test.snk", OutputFile = outputFile }; ilMerge.SetUpInputAssemblyForTest(Assembly.GetExecutingAssembly()); // ACT ilMerge.Merge(); // ASSERT var expectedKeyBytes = new StrongNameKeyPair(File.ReadAllBytes(TestSnk)).PublicKey; var outputFileKeyBytes = AssemblyName.GetAssemblyName(outputFile).GetPublicKey(); CollectionAssert.AreEqual(expectedKeyBytes, outputFileKeyBytes, "Expected PublicKey bytes do not match-up to the generated assembly PublicKey bytes"); }
private static bool SetStrongNameKeyPair(ref StrongNameKeyPair strongNameKeyPair, string fileNameOrKeyContainer, bool file) { try { if (file) { strongNameKeyPair = new StrongNameKeyPair(File.ReadAllBytes(fileNameOrKeyContainer)); } else { strongNameKeyPair = new StrongNameKeyPair(fileNameOrKeyContainer); } // FXBUG we explicitly try to access the public key force a check (the StrongNameKeyPair constructor doesn't validate the key) return(strongNameKeyPair.PublicKey != null); } catch (Exception x) { Console.Error.WriteLine("Error: Invalid key {0} specified.\n\t(\"{1}\")", file ? "file" : "container", x.Message); return(false); } }
internal static RSA CreateRSA(StrongNameKeyPair keyPair) { // HACK use serialization to get at the private key or key container name, // this should be more future proof than using reflection to access the fields directly. SerializationInfo ser = new SerializationInfo(typeof(StrongNameKeyPair), new FormatterConverter()); ((ISerializable)keyPair.keyPair).GetObjectData(ser, new StreamingContext()); byte[] key = (byte[])ser.GetValue("_keyPairArray", typeof(byte[])); string keycontainer = ser.GetString("_keyPairContainer"); if (keycontainer != null) { CspParameters parm = new CspParameters(); parm.Flags = CspProviderFlags.UseMachineKeyStore; parm.KeyContainerName = keycontainer; parm.KeyNumber = 2; // Signature return new RSACryptoServiceProvider(parm); } else { return Mono.Security.Cryptography.CryptoConvert.FromCapiKeyBlob(key); } }
private AssemblyName GetAssemblyName() { var version = new System.Version(AssemblyVersion); var name = new AssemblyName(); name.Name = Path.GetFileNameWithoutExtension(AssemblyName); name.Version = version; if (string.IsNullOrEmpty(AssemblyKeyFile) || !File.Exists(AssemblyKeyFile)) { return(name); } using (var fs = File.OpenRead(AssemblyKeyFile)) { var keyPair = new StrongNameKeyPair(fs); name.KeyPair = keyPair; } return(name); }
/// <summary> /// Creates DLL assembly linked to policy file /// </summary> /// <param name="saveDirectory">Directory to save to</param> /// <returns>Success or failure</returns> protected bool CreateLinkedAssembly(DirectoryInfo saveDirectory) { OpenFileDialog keyDiag = new OpenFileDialog(); keyDiag.AddExtension = true; keyDiag.CheckFileExists = true; keyDiag.DefaultExt = ".snk"; keyDiag.Filter = "Key file (*.snk)|*.snk|All files (*.*)|*.*"; keyDiag.Title = "Load key file"; if (keyDiag.ShowDialog() == DialogResult.OK) { StrongNameKeyPair kp = null; using (FileStream fs = new FileStream(keyDiag.FileName, FileMode.Open, FileAccess.Read)) { kp = new StrongNameKeyPair(fs); fs.Close(); } string filename = string.Format("policy.{0}.{1}.{2}", this._nameDetails.Version.Major, this._nameDetails.Version.Minor, this._nameDetails.Name); AssemblyName assName = new AssemblyName(filename); assName.KeyPair = kp; assName.Version = new Version(this._nameDetails.Version.Major, this._nameDetails.Version.Minor); AssemblyBuilder build = System.Threading.Thread.GetDomain().DefineDynamicAssembly(assName, AssemblyBuilderAccess.Save, saveDirectory.FullName); if (this.KeyToString(build.GetName().GetPublicKeyToken()) != this._nameDetails.PublicKeyToken) { throw new System.Security.SecurityException("Provided key token does not match original assembly."); } build.AddResourceFile(filename + ".xml", filename + ".xml"); build.Save(filename + ".dll"); return(true); } return(false); }
static int ExtractPublicKey(string inFile, string outFile) { var inputName = GetFileName(inFile); var outputName = GetFileName(outFile); if (inputName == outputName) { outputName = Path.ChangeExtension(outputName, "public.snk"); } // do not overwrite output file if (File.Exists(outputName)) { return 0; } // read key pair blob and extract public key var array = File.ReadAllBytes(inputName); var snk = new StrongNameKeyPair(array); var publicKey = snk.PublicKey; File.WriteAllBytes(outputName, publicKey); return 0; }
internal static RSA CreateRSA(StrongNameKeyPair keyPair) { // HACK use serialization to get at the private key or key container name, // this should be more future proof than using reflection to access the fields directly. SerializationInfo ser = new SerializationInfo(typeof(StrongNameKeyPair), new FormatterConverter()); ((ISerializable)keyPair.keyPair).GetObjectData(ser, new StreamingContext()); byte[] key = (byte[])ser.GetValue("_keyPairArray", typeof(byte[])); string keycontainer = ser.GetString("_keyPairContainer"); if (keycontainer != null) { CspParameters parm = new CspParameters(); parm.Flags = CspProviderFlags.UseMachineKeyStore; parm.KeyContainerName = keycontainer; parm.KeyNumber = 2; // Signature return(new RSACryptoServiceProvider(parm)); } else { return(Mono.Security.Cryptography.CryptoConvert.FromCapiKeyBlob(key)); } }
private static void StrongName(FileStream fs, StrongNameKeyPair keyPair, uint headerLength, uint textSectionFileOffset, uint strongNameSignatureFileOffset, uint strongNameSignatureLength) { SHA1Managed hash = new SHA1Managed(); using (CryptoStream cs = new CryptoStream(Stream.Null, hash, CryptoStreamMode.Write)) { fs.Seek(0, SeekOrigin.Begin); byte[] buf = new byte[8192]; HashChunk(fs, cs, buf, (int)headerLength); fs.Seek(textSectionFileOffset, SeekOrigin.Begin); HashChunk(fs, cs, buf, (int)(strongNameSignatureFileOffset - textSectionFileOffset)); fs.Seek(strongNameSignatureLength, SeekOrigin.Current); HashChunk(fs, cs, buf, (int)(fs.Length - (strongNameSignatureFileOffset + strongNameSignatureLength))); } using (RSA rsa = CryptoHack.CreateRSA(keyPair)) { RSAPKCS1SignatureFormatter sign = new RSAPKCS1SignatureFormatter(rsa); sign.SetHashAlgorithm("SHA1"); byte[] signature = sign.CreateSignature(hash.Hash); Array.Reverse(signature); Debug.Assert(signature.Length == strongNameSignatureLength); fs.Seek(strongNameSignatureFileOffset, SeekOrigin.Begin); fs.Write(signature, 0, signature.Length); } // compute the PE checksum fs.Seek(0, SeekOrigin.Begin); int count = (int)fs.Length / 4; BinaryReader br = new BinaryReader(fs); long sum = 0; for (int i = 0; i < count; i++) { sum += br.ReadUInt32(); int carry = (int)(sum >> 32); sum &= 0xFFFFFFFFU; sum += carry; } while ((sum >> 16) != 0) { sum = (sum & 0xFFFF) + (sum >> 16); } sum += fs.Length; // write the PE checksum, note that it is always at offset 0xD8 in the file ByteBuffer bb = new ByteBuffer(4); bb.Write((int)sum); fs.Seek(0xD8, SeekOrigin.Begin); bb.WriteTo(fs); }
internal static void WriteModule(StrongNameKeyPair keyPair, byte[] publicKey, ModuleBuilder moduleBuilder, PEFileKinds fileKind, PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine, ByteBuffer versionInfoData, byte[] unmanagedResources, int entryPointToken) { moduleBuilder.FixupMethodBodyTokens(); moduleBuilder.ModuleTable.Add(0, moduleBuilder.Strings.Add(moduleBuilder.moduleName), moduleBuilder.Guids.Add(moduleBuilder.ModuleVersionId), 0, 0); if (moduleBuilder.UserStrings.IsEmpty) { // for compat with Ref.Emit, if there aren't any user strings, we add one moduleBuilder.UserStrings.Add(" "); } using (FileStream fs = new FileStream(moduleBuilder.FullyQualifiedName, FileMode.Create)) { PEWriter writer = new PEWriter(fs); switch (imageFileMachine) { case ImageFileMachine.I386: writer.Headers.FileHeader.Machine = IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_I386; writer.Headers.FileHeader.Characteristics |= IMAGE_FILE_HEADER.IMAGE_FILE_32BIT_MACHINE; break; case ImageFileMachine.AMD64: writer.Headers.FileHeader.Machine = IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_AMD64; writer.Headers.FileHeader.Characteristics |= IMAGE_FILE_HEADER.IMAGE_FILE_LARGE_ADDRESS_AWARE; writer.Headers.FileHeader.SizeOfOptionalHeader = 0xF0; writer.Headers.OptionalHeader.Magic = IMAGE_OPTIONAL_HEADER.IMAGE_NT_OPTIONAL_HDR64_MAGIC; writer.Headers.OptionalHeader.SizeOfStackReserve = 0x400000; writer.Headers.OptionalHeader.SizeOfStackCommit = 0x4000; writer.Headers.OptionalHeader.SizeOfHeapCommit = 0x2000; break; case ImageFileMachine.IA64: writer.Headers.FileHeader.Machine = IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_IA64; writer.Headers.FileHeader.Characteristics |= IMAGE_FILE_HEADER.IMAGE_FILE_LARGE_ADDRESS_AWARE; writer.Headers.FileHeader.SizeOfOptionalHeader = 0xF0; writer.Headers.OptionalHeader.Magic = IMAGE_OPTIONAL_HEADER.IMAGE_NT_OPTIONAL_HDR64_MAGIC; writer.Headers.OptionalHeader.SizeOfStackReserve = 0x400000; writer.Headers.OptionalHeader.SizeOfStackCommit = 0x4000; writer.Headers.OptionalHeader.SizeOfHeapCommit = 0x2000; break; default: throw new ArgumentOutOfRangeException("imageFileMachine"); } if (fileKind == PEFileKinds.Dll) { writer.Headers.FileHeader.Characteristics |= IMAGE_FILE_HEADER.IMAGE_FILE_DLL; } switch (fileKind) { case PEFileKinds.WindowApplication: writer.Headers.OptionalHeader.Subsystem = IMAGE_OPTIONAL_HEADER.IMAGE_SUBSYSTEM_WINDOWS_GUI; break; default: writer.Headers.OptionalHeader.Subsystem = IMAGE_OPTIONAL_HEADER.IMAGE_SUBSYSTEM_WINDOWS_CUI; break; } writer.Headers.OptionalHeader.DllCharacteristics = IMAGE_OPTIONAL_HEADER.IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE | IMAGE_OPTIONAL_HEADER.IMAGE_DLLCHARACTERISTICS_NO_SEH | IMAGE_OPTIONAL_HEADER.IMAGE_DLLCHARACTERISTICS_NX_COMPAT | IMAGE_OPTIONAL_HEADER.IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE; CliHeader cliHeader = new CliHeader(); cliHeader.Cb = 0x48; cliHeader.MajorRuntimeVersion = 2; cliHeader.MinorRuntimeVersion = moduleBuilder.MDStreamVersion < 0x20000 ? (ushort)0 : (ushort)5; if ((portableExecutableKind & PortableExecutableKinds.ILOnly) != 0) { cliHeader.Flags |= CliHeader.COMIMAGE_FLAGS_ILONLY; } if ((portableExecutableKind & PortableExecutableKinds.Required32Bit) != 0) { cliHeader.Flags |= CliHeader.COMIMAGE_FLAGS_32BITREQUIRED; } if (keyPair != null) { cliHeader.Flags |= CliHeader.COMIMAGE_FLAGS_STRONGNAMESIGNED; } if (moduleBuilder.IsPseudoToken(entryPointToken)) { entryPointToken = moduleBuilder.ResolvePseudoToken(entryPointToken); } cliHeader.EntryPointToken = (uint)entryPointToken; moduleBuilder.Strings.Freeze(); moduleBuilder.UserStrings.Freeze(); moduleBuilder.Guids.Freeze(); moduleBuilder.Blobs.Freeze(); MetadataWriter mw = new MetadataWriter(moduleBuilder, fs); moduleBuilder.Tables.Freeze(mw); TextSection code = new TextSection(writer, cliHeader, moduleBuilder, publicKey != null); ResourceSection resources = new ResourceSection(versionInfoData, unmanagedResources); // Import Directory writer.Headers.OptionalHeader.DataDirectory[1].VirtualAddress = code.ImportDirectoryRVA; writer.Headers.OptionalHeader.DataDirectory[1].Size = code.ImportDirectoryLength; // Import Address Table Directory writer.Headers.OptionalHeader.DataDirectory[12].VirtualAddress = code.ImportAddressTableRVA; writer.Headers.OptionalHeader.DataDirectory[12].Size = code.ImportAddressTableLength; // COM Descriptor Directory writer.Headers.OptionalHeader.DataDirectory[14].VirtualAddress = code.ComDescriptorRVA; writer.Headers.OptionalHeader.DataDirectory[14].Size = code.ComDescriptorLength; // Debug Directory if (code.DebugDirectoryLength != 0) { writer.Headers.OptionalHeader.DataDirectory[6].VirtualAddress = code.DebugDirectoryRVA; writer.Headers.OptionalHeader.DataDirectory[6].Size = code.DebugDirectoryLength; } writer.Headers.FileHeader.NumberOfSections = 2; if (moduleBuilder.initializedData.Length != 0) { writer.Headers.FileHeader.NumberOfSections++; } if (resources.Length != 0) { writer.Headers.FileHeader.NumberOfSections++; } SectionHeader text = new SectionHeader(); text.Name = ".text"; text.VirtualAddress = code.BaseRVA; text.VirtualSize = (uint)code.Length; text.PointerToRawData = code.PointerToRawData; text.SizeOfRawData = writer.ToFileAlignment((uint)code.Length); text.Characteristics = SectionHeader.IMAGE_SCN_CNT_CODE | SectionHeader.IMAGE_SCN_MEM_EXECUTE | SectionHeader.IMAGE_SCN_MEM_READ; SectionHeader sdata = new SectionHeader(); sdata.Name = ".sdata"; sdata.VirtualAddress = text.VirtualAddress + writer.ToSectionAlignment(text.VirtualSize); sdata.VirtualSize = (uint)moduleBuilder.initializedData.Length; sdata.PointerToRawData = text.PointerToRawData + text.SizeOfRawData; sdata.SizeOfRawData = writer.ToFileAlignment((uint)moduleBuilder.initializedData.Length); sdata.Characteristics = SectionHeader.IMAGE_SCN_CNT_INITIALIZED_DATA | SectionHeader.IMAGE_SCN_MEM_READ | SectionHeader.IMAGE_SCN_MEM_WRITE; SectionHeader rsrc = new SectionHeader(); rsrc.Name = ".rsrc"; rsrc.VirtualAddress = sdata.VirtualAddress + writer.ToSectionAlignment(sdata.VirtualSize); rsrc.PointerToRawData = sdata.PointerToRawData + sdata.SizeOfRawData; rsrc.VirtualSize = (uint)resources.Length; rsrc.SizeOfRawData = writer.ToFileAlignment(rsrc.VirtualSize); rsrc.Characteristics = SectionHeader.IMAGE_SCN_MEM_READ | SectionHeader.IMAGE_SCN_CNT_INITIALIZED_DATA; if (rsrc.SizeOfRawData != 0) { // Resource Directory writer.Headers.OptionalHeader.DataDirectory[2].VirtualAddress = rsrc.VirtualAddress; writer.Headers.OptionalHeader.DataDirectory[2].Size = rsrc.VirtualSize; } SectionHeader reloc = new SectionHeader(); reloc.Name = ".reloc"; reloc.VirtualAddress = rsrc.VirtualAddress + writer.ToSectionAlignment(rsrc.VirtualSize); reloc.VirtualSize = 12; reloc.PointerToRawData = rsrc.PointerToRawData + rsrc.SizeOfRawData; reloc.SizeOfRawData = writer.ToFileAlignment(reloc.VirtualSize); reloc.Characteristics = SectionHeader.IMAGE_SCN_MEM_READ | SectionHeader.IMAGE_SCN_CNT_INITIALIZED_DATA | SectionHeader.IMAGE_SCN_MEM_DISCARDABLE; // Base Relocation Directory writer.Headers.OptionalHeader.DataDirectory[5].VirtualAddress = reloc.VirtualAddress; writer.Headers.OptionalHeader.DataDirectory[5].Size = reloc.VirtualSize; writer.Headers.OptionalHeader.SizeOfCode = text.SizeOfRawData; writer.Headers.OptionalHeader.SizeOfInitializedData = sdata.SizeOfRawData + rsrc.SizeOfRawData + reloc.SizeOfRawData; writer.Headers.OptionalHeader.SizeOfUninitializedData = 0; writer.Headers.OptionalHeader.SizeOfImage = reloc.VirtualAddress + writer.ToSectionAlignment(reloc.VirtualSize); writer.Headers.OptionalHeader.SizeOfHeaders = text.PointerToRawData; writer.Headers.OptionalHeader.BaseOfCode = code.BaseRVA; writer.Headers.OptionalHeader.BaseOfData = sdata.VirtualAddress; writer.Headers.OptionalHeader.ImageBase = (ulong)moduleBuilder.__ImageBase; if (imageFileMachine == ImageFileMachine.IA64) { // apparently for IA64 AddressOfEntryPoint points to the address of the entry point // (i.e. there is an additional layer of indirection), so we add the offset to the pointer writer.Headers.OptionalHeader.AddressOfEntryPoint = code.StartupStubRVA + 0x20; } else { writer.Headers.OptionalHeader.AddressOfEntryPoint = code.StartupStubRVA; } writer.WritePEHeaders(); writer.WriteSectionHeader(text); if (sdata.SizeOfRawData != 0) { writer.WriteSectionHeader(sdata); } if (rsrc.SizeOfRawData != 0) { writer.WriteSectionHeader(rsrc); } writer.WriteSectionHeader(reloc); fs.Seek(text.PointerToRawData, SeekOrigin.Begin); code.Write(mw, (int)sdata.VirtualAddress); fs.Seek(sdata.PointerToRawData, SeekOrigin.Begin); mw.Write(moduleBuilder.initializedData); if (rsrc.SizeOfRawData != 0) { fs.Seek(rsrc.PointerToRawData, SeekOrigin.Begin); resources.Write(mw, rsrc.VirtualAddress); } fs.Seek(reloc.PointerToRawData, SeekOrigin.Begin); // .reloc section uint relocAddress = code.StartupStubRVA; switch (imageFileMachine) { case ImageFileMachine.I386: case ImageFileMachine.AMD64: relocAddress += 2; break; case ImageFileMachine.IA64: relocAddress += 0x20; break; } uint pageRVA = relocAddress & ~0xFFFU; mw.Write(pageRVA); // PageRVA mw.Write(0x000C); // Block Size if (imageFileMachine == ImageFileMachine.I386) { mw.Write(0x3000 + relocAddress - pageRVA); // Type / Offset } else if (imageFileMachine == ImageFileMachine.AMD64) { mw.Write(0xA000 + relocAddress - pageRVA); // Type / Offset } else if (imageFileMachine == ImageFileMachine.IA64) { // on IA64 the StartupStubRVA is 16 byte aligned, so these two addresses won't cross a page boundary mw.Write((short)(0xA000 + relocAddress - pageRVA)); // Type / Offset mw.Write((short)(0xA000 + relocAddress - pageRVA + 8)); // Type / Offset } // file alignment mw.Write(new byte[writer.Headers.OptionalHeader.FileAlignment - reloc.VirtualSize]); // do the strong naming if (keyPair != null) { StrongName(fs, keyPair, writer.HeaderSize, text.PointerToRawData, code.StrongNameSignatureRVA - text.VirtualAddress + text.PointerToRawData, code.StrongNameSignatureLength); } } if (moduleBuilder.symbolWriter != null) { moduleBuilder.WriteSymbolTokenMap(); moduleBuilder.symbolWriter.Close(); } }
internal AssemblyBuilder(Universe universe, AssemblyName name, string dir, IEnumerable<CustomAttributeBuilder> customAttributes) : base(universe) { this.name = name.Name; SetVersionHelper(name.Version); if (!string.IsNullOrEmpty(name.Culture)) { this.culture = name.Culture; } this.flags = name.RawFlags; this.hashAlgorithm = name.HashAlgorithm; if (this.hashAlgorithm == AssemblyHashAlgorithm.None) { this.hashAlgorithm = AssemblyHashAlgorithm.SHA1; } this.keyPair = name.KeyPair; if (this.keyPair != null) { this.publicKey = this.keyPair.PublicKey; } else { byte[] publicKey = name.GetPublicKey(); if (publicKey != null && publicKey.Length != 0) { this.publicKey = (byte[])publicKey.Clone(); } } this.dir = dir ?? "."; if (customAttributes != null) { this.customAttributes.AddRange(customAttributes); } if (universe.HasMscorlib && !universe.Mscorlib.__IsMissing && universe.Mscorlib.ImageRuntimeVersion != null) { this.imageRuntimeVersion = universe.Mscorlib.ImageRuntimeVersion; } else { this.imageRuntimeVersion = typeof(object).Assembly.ImageRuntimeVersion; } universe.RegisterDynamicAssembly(this); }
public void __SetAssemblyKeyPair(StrongNameKeyPair keyPair) { AssemblyName oldName = GetName(); this.keyPair = keyPair; if (keyPair != null) { this.publicKey = keyPair.PublicKey; } Rename(oldName); }
internal AssemblyBuilder(Universe universe, AssemblyName name, string dir, PermissionSet requiredPermissions, PermissionSet optionalPermissions, PermissionSet refusedPermissions) : base(universe) { this.name = name.Name; SetVersionHelper(name.Version); if (!string.IsNullOrEmpty(name.Culture)) { this.culture = name.Culture; } this.flags = name.RawFlags; this.hashAlgorithm = name.HashAlgorithm; if (this.hashAlgorithm == AssemblyHashAlgorithm.None) { this.hashAlgorithm = AssemblyHashAlgorithm.SHA1; } this.keyPair = name.KeyPair; if (this.keyPair != null) { this.publicKey = this.keyPair.PublicKey; } else { byte[] publicKey = name.GetPublicKey(); if (publicKey != null && publicKey.Length != 0) { this.publicKey = (byte[])publicKey.Clone(); } } this.dir = dir ?? "."; this.requiredPermissions = requiredPermissions; this.optionalPermissions = optionalPermissions; this.refusedPermissions = refusedPermissions; if (universe.HasMscorlib && !universe.Mscorlib.__IsMissing && universe.Mscorlib.ImageRuntimeVersion != null) { this.imageRuntimeVersion = universe.Mscorlib.ImageRuntimeVersion; } else { this.imageRuntimeVersion = typeof(object).Assembly.ImageRuntimeVersion; } }
internal static void WriteModule(StrongNameKeyPair keyPair, byte[] publicKey, ModuleBuilder moduleBuilder, PEFileKinds fileKind, PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine, ResourceSection resources, int entryPointToken) { WriteModule(keyPair, publicKey, moduleBuilder, fileKind, portableExecutableKind, imageFileMachine, resources, entryPointToken, null); }
private static void StrongName(Stream stream, StrongNameKeyPair keyPair, uint headerLength, uint textSectionFileOffset, uint strongNameSignatureFileOffset, uint strongNameSignatureLength) { SHA1Managed hash = new SHA1Managed(); using (CryptoStream cs = new CryptoStream(Stream.Null, hash, CryptoStreamMode.Write)) { stream.Seek(0, SeekOrigin.Begin); byte[] buf = new byte[8192]; HashChunk(stream, cs, buf, (int)headerLength); stream.Seek(textSectionFileOffset, SeekOrigin.Begin); HashChunk(stream, cs, buf, (int)(strongNameSignatureFileOffset - textSectionFileOffset)); stream.Seek(strongNameSignatureLength, SeekOrigin.Current); HashChunk(stream, cs, buf, (int)(stream.Length - (strongNameSignatureFileOffset + strongNameSignatureLength))); } using (RSA rsa = keyPair.CreateRSA()) { RSAPKCS1SignatureFormatter sign = new RSAPKCS1SignatureFormatter(rsa); byte[] signature = sign.CreateSignature(hash); Array.Reverse(signature); if (signature.Length != strongNameSignatureLength) { throw new InvalidOperationException("Signature length mismatch"); } stream.Seek(strongNameSignatureFileOffset, SeekOrigin.Begin); stream.Write(signature, 0, signature.Length); } // compute the PE checksum stream.Seek(0, SeekOrigin.Begin); int count = (int)stream.Length / 4; BinaryReader br = new BinaryReader(stream); long sum = 0; for (int i = 0; i < count; i++) { sum += br.ReadUInt32(); int carry = (int)(sum >> 32); sum &= 0xFFFFFFFFU; sum += carry; } while ((sum >> 16) != 0) { sum = (sum & 0xFFFF) + (sum >> 16); } sum += stream.Length; // write the PE checksum, note that it is always at offset 0xD8 in the file ByteBuffer bb = new ByteBuffer(4); bb.Write((int)sum); stream.Seek(0xD8, SeekOrigin.Begin); bb.WriteTo(stream); }
private static void WriteModuleImpl(StrongNameKeyPair keyPair, byte[] publicKey, ModuleBuilder moduleBuilder, PEFileKinds fileKind, PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine, ResourceSection resources, int entryPointToken, Stream stream) { moduleBuilder.ApplyUnmanagedExports(imageFileMachine); moduleBuilder.FixupMethodBodyTokens(); moduleBuilder.ModuleTable.Add(0, moduleBuilder.Strings.Add(moduleBuilder.moduleName), moduleBuilder.Guids.Add(moduleBuilder.ModuleVersionId), 0, 0); if (moduleBuilder.UserStrings.IsEmpty) { // for compat with Ref.Emit, if there aren't any user strings, we add one moduleBuilder.UserStrings.Add(" "); } if (resources != null) { resources.Finish(); } PEWriter writer = new PEWriter(stream); writer.Headers.OptionalHeader.FileAlignment = (uint)moduleBuilder.__FileAlignment; switch (imageFileMachine) { case ImageFileMachine.I386: writer.Headers.FileHeader.Machine = IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_I386; writer.Headers.FileHeader.Characteristics |= IMAGE_FILE_HEADER.IMAGE_FILE_32BIT_MACHINE; writer.Headers.OptionalHeader.SizeOfStackReserve = moduleBuilder.GetStackReserve(0x100000); break; case ImageFileMachine.ARM: writer.Headers.FileHeader.Machine = IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_ARM; writer.Headers.FileHeader.Characteristics |= IMAGE_FILE_HEADER.IMAGE_FILE_32BIT_MACHINE; writer.Headers.OptionalHeader.SizeOfStackReserve = moduleBuilder.GetStackReserve(0x100000); break; case ImageFileMachine.AMD64: writer.Headers.FileHeader.Machine = IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_AMD64; writer.Headers.FileHeader.Characteristics |= IMAGE_FILE_HEADER.IMAGE_FILE_LARGE_ADDRESS_AWARE; writer.Headers.FileHeader.SizeOfOptionalHeader = 0xF0; writer.Headers.OptionalHeader.Magic = IMAGE_OPTIONAL_HEADER.IMAGE_NT_OPTIONAL_HDR64_MAGIC; writer.Headers.OptionalHeader.SizeOfStackReserve = moduleBuilder.GetStackReserve(0x400000); writer.Headers.OptionalHeader.SizeOfStackCommit = 0x4000; writer.Headers.OptionalHeader.SizeOfHeapCommit = 0x2000; break; case ImageFileMachine.IA64: writer.Headers.FileHeader.Machine = IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_IA64; writer.Headers.FileHeader.Characteristics |= IMAGE_FILE_HEADER.IMAGE_FILE_LARGE_ADDRESS_AWARE; writer.Headers.FileHeader.SizeOfOptionalHeader = 0xF0; writer.Headers.OptionalHeader.Magic = IMAGE_OPTIONAL_HEADER.IMAGE_NT_OPTIONAL_HDR64_MAGIC; writer.Headers.OptionalHeader.SizeOfStackReserve = moduleBuilder.GetStackReserve(0x400000); writer.Headers.OptionalHeader.SizeOfStackCommit = 0x4000; writer.Headers.OptionalHeader.SizeOfHeapCommit = 0x2000; break; default: throw new ArgumentOutOfRangeException("imageFileMachine"); } if (fileKind == PEFileKinds.Dll) { writer.Headers.FileHeader.Characteristics |= IMAGE_FILE_HEADER.IMAGE_FILE_DLL; } switch (fileKind) { case PEFileKinds.WindowApplication: writer.Headers.OptionalHeader.Subsystem = IMAGE_OPTIONAL_HEADER.IMAGE_SUBSYSTEM_WINDOWS_GUI; break; default: writer.Headers.OptionalHeader.Subsystem = IMAGE_OPTIONAL_HEADER.IMAGE_SUBSYSTEM_WINDOWS_CUI; break; } writer.Headers.OptionalHeader.DllCharacteristics = (ushort)moduleBuilder.__DllCharacteristics; CliHeader cliHeader = new CliHeader(); cliHeader.Cb = 0x48; cliHeader.MajorRuntimeVersion = 2; cliHeader.MinorRuntimeVersion = moduleBuilder.MDStreamVersion < 0x20000 ? (ushort)0 : (ushort)5; if ((portableExecutableKind & PortableExecutableKinds.ILOnly) != 0) { cliHeader.Flags |= CliHeader.COMIMAGE_FLAGS_ILONLY; } if ((portableExecutableKind & PortableExecutableKinds.Required32Bit) != 0) { cliHeader.Flags |= CliHeader.COMIMAGE_FLAGS_32BITREQUIRED; } if ((portableExecutableKind & PortableExecutableKinds.Preferred32Bit) != 0) { cliHeader.Flags |= CliHeader.COMIMAGE_FLAGS_32BITREQUIRED | CliHeader.COMIMAGE_FLAGS_32BITPREFERRED; } if (keyPair != null) { cliHeader.Flags |= CliHeader.COMIMAGE_FLAGS_STRONGNAMESIGNED; } if (moduleBuilder.IsPseudoToken(entryPointToken)) { entryPointToken = moduleBuilder.ResolvePseudoToken(entryPointToken); } cliHeader.EntryPointToken = (uint)entryPointToken; moduleBuilder.Strings.Freeze(); moduleBuilder.UserStrings.Freeze(); moduleBuilder.Guids.Freeze(); moduleBuilder.Blobs.Freeze(); MetadataWriter mw = new MetadataWriter(moduleBuilder, stream); moduleBuilder.Tables.Freeze(mw); TextSection code = new TextSection(writer, cliHeader, moduleBuilder, ComputeStrongNameSignatureLength(publicKey)); // Export Directory if (code.ExportDirectoryLength != 0) { writer.Headers.OptionalHeader.DataDirectory[0].VirtualAddress = code.ExportDirectoryRVA; writer.Headers.OptionalHeader.DataDirectory[0].Size = code.ExportDirectoryLength; } // Import Directory if (code.ImportDirectoryLength != 0) { writer.Headers.OptionalHeader.DataDirectory[1].VirtualAddress = code.ImportDirectoryRVA; writer.Headers.OptionalHeader.DataDirectory[1].Size = code.ImportDirectoryLength; } // Import Address Table Directory if (code.ImportAddressTableLength != 0) { writer.Headers.OptionalHeader.DataDirectory[12].VirtualAddress = code.ImportAddressTableRVA; writer.Headers.OptionalHeader.DataDirectory[12].Size = code.ImportAddressTableLength; } // COM Descriptor Directory writer.Headers.OptionalHeader.DataDirectory[14].VirtualAddress = code.ComDescriptorRVA; writer.Headers.OptionalHeader.DataDirectory[14].Size = code.ComDescriptorLength; // Debug Directory if (code.DebugDirectoryLength != 0) { writer.Headers.OptionalHeader.DataDirectory[6].VirtualAddress = code.DebugDirectoryRVA; writer.Headers.OptionalHeader.DataDirectory[6].Size = code.DebugDirectoryLength; } // we need to start by computing the number of sections, because code.PointerToRawData depends on that writer.Headers.FileHeader.NumberOfSections = 1; if (moduleBuilder.initializedData.Length != 0) { // .sdata writer.Headers.FileHeader.NumberOfSections++; } if (resources != null) { // .rsrc writer.Headers.FileHeader.NumberOfSections++; } if (imageFileMachine != ImageFileMachine.ARM) { // .reloc writer.Headers.FileHeader.NumberOfSections++; } SectionHeader text = new SectionHeader(); text.Name = ".text"; text.VirtualAddress = code.BaseRVA; text.VirtualSize = (uint)code.Length; text.PointerToRawData = code.PointerToRawData; text.SizeOfRawData = writer.ToFileAlignment((uint)code.Length); text.Characteristics = SectionHeader.IMAGE_SCN_CNT_CODE | SectionHeader.IMAGE_SCN_MEM_EXECUTE | SectionHeader.IMAGE_SCN_MEM_READ; SectionHeader sdata = new SectionHeader(); sdata.Name = ".sdata"; sdata.VirtualAddress = text.VirtualAddress + writer.ToSectionAlignment(text.VirtualSize); sdata.VirtualSize = (uint)moduleBuilder.initializedData.Length; sdata.PointerToRawData = text.PointerToRawData + text.SizeOfRawData; sdata.SizeOfRawData = writer.ToFileAlignment((uint)moduleBuilder.initializedData.Length); sdata.Characteristics = SectionHeader.IMAGE_SCN_CNT_INITIALIZED_DATA | SectionHeader.IMAGE_SCN_MEM_READ | SectionHeader.IMAGE_SCN_MEM_WRITE; SectionHeader rsrc = new SectionHeader(); rsrc.Name = ".rsrc"; rsrc.VirtualAddress = sdata.VirtualAddress + writer.ToSectionAlignment(sdata.VirtualSize); rsrc.PointerToRawData = sdata.PointerToRawData + sdata.SizeOfRawData; rsrc.VirtualSize = resources == null ? 0 : (uint)resources.Length; rsrc.SizeOfRawData = writer.ToFileAlignment(rsrc.VirtualSize); rsrc.Characteristics = SectionHeader.IMAGE_SCN_MEM_READ | SectionHeader.IMAGE_SCN_CNT_INITIALIZED_DATA; if (rsrc.SizeOfRawData != 0) { // Resource Directory writer.Headers.OptionalHeader.DataDirectory[2].VirtualAddress = rsrc.VirtualAddress; writer.Headers.OptionalHeader.DataDirectory[2].Size = rsrc.VirtualSize; } SectionHeader reloc = new SectionHeader(); reloc.Name = ".reloc"; reloc.VirtualAddress = rsrc.VirtualAddress + writer.ToSectionAlignment(rsrc.VirtualSize); if (imageFileMachine != ImageFileMachine.ARM) { reloc.VirtualSize = ((uint)moduleBuilder.unmanagedExports.Count + 1) * 12; } reloc.PointerToRawData = rsrc.PointerToRawData + rsrc.SizeOfRawData; reloc.SizeOfRawData = writer.ToFileAlignment(reloc.VirtualSize); reloc.Characteristics = SectionHeader.IMAGE_SCN_MEM_READ | SectionHeader.IMAGE_SCN_CNT_INITIALIZED_DATA | SectionHeader.IMAGE_SCN_MEM_DISCARDABLE; if (reloc.SizeOfRawData != 0) { // Base Relocation Directory writer.Headers.OptionalHeader.DataDirectory[5].VirtualAddress = reloc.VirtualAddress; writer.Headers.OptionalHeader.DataDirectory[5].Size = reloc.VirtualSize; } writer.Headers.OptionalHeader.SizeOfCode = text.SizeOfRawData; writer.Headers.OptionalHeader.SizeOfInitializedData = sdata.SizeOfRawData + rsrc.SizeOfRawData + reloc.SizeOfRawData; writer.Headers.OptionalHeader.SizeOfUninitializedData = 0; writer.Headers.OptionalHeader.SizeOfImage = reloc.VirtualAddress + writer.ToSectionAlignment(reloc.VirtualSize); writer.Headers.OptionalHeader.SizeOfHeaders = text.PointerToRawData; writer.Headers.OptionalHeader.BaseOfCode = code.BaseRVA; writer.Headers.OptionalHeader.BaseOfData = sdata.VirtualAddress; writer.Headers.OptionalHeader.ImageBase = (ulong)moduleBuilder.__ImageBase; if (imageFileMachine == ImageFileMachine.IA64) { // apparently for IA64 AddressOfEntryPoint points to the address of the entry point // (i.e. there is an additional layer of indirection), so we add the offset to the pointer writer.Headers.OptionalHeader.AddressOfEntryPoint = code.StartupStubRVA + 0x20; } else if (imageFileMachine != ImageFileMachine.ARM) { writer.Headers.OptionalHeader.AddressOfEntryPoint = code.StartupStubRVA; } writer.WritePEHeaders(); writer.WriteSectionHeader(text); if (sdata.SizeOfRawData != 0) { writer.WriteSectionHeader(sdata); } if (rsrc.SizeOfRawData != 0) { writer.WriteSectionHeader(rsrc); } if (reloc.SizeOfRawData != 0) { writer.WriteSectionHeader(reloc); } stream.Seek(text.PointerToRawData, SeekOrigin.Begin); code.Write(mw, sdata.VirtualAddress); if (sdata.SizeOfRawData != 0) { stream.Seek(sdata.PointerToRawData, SeekOrigin.Begin); mw.Write(moduleBuilder.initializedData); } if (rsrc.SizeOfRawData != 0) { stream.Seek(rsrc.PointerToRawData, SeekOrigin.Begin); resources.Write(mw, rsrc.VirtualAddress); } if (reloc.SizeOfRawData != 0) { stream.Seek(reloc.PointerToRawData, SeekOrigin.Begin); code.WriteRelocations(mw); } // file alignment stream.SetLength(reloc.PointerToRawData + reloc.SizeOfRawData); // do the strong naming if (keyPair != null) { StrongName(stream, keyPair, writer.HeaderSize, text.PointerToRawData, code.StrongNameSignatureRVA - text.VirtualAddress + text.PointerToRawData, code.StrongNameSignatureLength); } if (moduleBuilder.symbolWriter != null) { moduleBuilder.WriteSymbolTokenMap(); moduleBuilder.symbolWriter.Close(); } }