internal StrongNameSignature StrongHash(Stream stream, StrongNameOptions options) { StrongNameSignature info = new StrongNameSignature(); HashAlgorithm hash = HashAlgorithm.Create(TokenAlgorithm); CryptoStream cs = new CryptoStream(Stream.Null, hash, CryptoStreamMode.Write); // MS-DOS Header - always 128 bytes // ref: Section 24.2.1, Partition II Metadata byte[] mz = new byte [128]; stream.Read(mz, 0, 128); if (BitConverterLE.ToUInt16(mz, 0) != 0x5a4d) { return(null); } UInt32 peHeader = BitConverterLE.ToUInt32(mz, 60); cs.Write(mz, 0, 128); if (peHeader != 128) { byte[] mzextra = new byte [peHeader - 128]; stream.Read(mzextra, 0, mzextra.Length); cs.Write(mzextra, 0, mzextra.Length); } // PE File Header - always 248 bytes // ref: Section 24.2.2, Partition II Metadata byte[] pe = new byte [248]; stream.Read(pe, 0, 248); if (BitConverterLE.ToUInt32(pe, 0) != 0x4550) { return(null); } if (BitConverterLE.ToUInt16(pe, 4) != 0x14c) { return(null); } // MUST zeroize both CheckSum and Security Directory byte[] v = new byte [8]; Buffer.BlockCopy(v, 0, pe, 88, 4); Buffer.BlockCopy(v, 0, pe, 152, 8); cs.Write(pe, 0, 248); UInt16 numSection = BitConverterLE.ToUInt16(pe, 6); int sectionLength = (numSection * 40); byte[] sectionHeaders = new byte [sectionLength]; stream.Read(sectionHeaders, 0, sectionLength); cs.Write(sectionHeaders, 0, sectionLength); UInt32 cliHeaderRVA = BitConverterLE.ToUInt32(pe, 232); UInt32 cliHeaderPos = RVAtoPosition(cliHeaderRVA, numSection, sectionHeaders); int cliHeaderSiz = (int)BitConverterLE.ToUInt32(pe, 236); // CLI Header // ref: Section 24.3.3, Partition II Metadata byte[] cli = new byte [cliHeaderSiz]; stream.Position = cliHeaderPos; stream.Read(cli, 0, cliHeaderSiz); UInt32 strongNameSignatureRVA = BitConverterLE.ToUInt32(cli, 32); info.SignaturePosition = RVAtoPosition(strongNameSignatureRVA, numSection, sectionHeaders); info.SignatureLength = BitConverterLE.ToUInt32(cli, 36); UInt32 metadataRVA = BitConverterLE.ToUInt32(cli, 8); info.MetadataPosition = RVAtoPosition(metadataRVA, numSection, sectionHeaders); info.MetadataLength = BitConverterLE.ToUInt32(cli, 12); if (options == StrongNameOptions.Metadata) { cs.Close(); hash.Initialize(); byte[] metadata = new byte [info.MetadataLength]; stream.Position = info.MetadataPosition; stream.Read(metadata, 0, metadata.Length); info.Hash = hash.ComputeHash(metadata); return(info); } // now we hash every section EXCEPT the signature block for (int i = 0; i < numSection; i++) { UInt32 start = BitConverterLE.ToUInt32(sectionHeaders, i * 40 + 20); int length = (int)BitConverterLE.ToUInt32(sectionHeaders, i * 40 + 16); byte[] section = new byte [length]; stream.Position = start; stream.Read(section, 0, length); if ((start <= info.SignaturePosition) && (info.SignaturePosition < start + length)) { // hash before the signature int before = (int)(info.SignaturePosition - start); if (before > 0) { cs.Write(section, 0, before); } // copy signature info.Signature = new byte [info.SignatureLength]; Buffer.BlockCopy(section, before, info.Signature, 0, (int)info.SignatureLength); Array.Reverse(info.Signature); // hash after the signature int s = (int)(before + info.SignatureLength); int after = (int)(length - s); if (after > 0) { cs.Write(section, s, after); } } else { cs.Write(section, 0, length); } } cs.Close(); info.Hash = hash.Hash; return(info); }
internal StrongName.StrongNameSignature StrongHash(Stream stream, StrongName.StrongNameOptions options) { StrongName.StrongNameSignature strongNameSignature = new StrongName.StrongNameSignature(); HashAlgorithm hashAlgorithm = HashAlgorithm.Create(this.TokenAlgorithm); CryptoStream cryptoStream = new CryptoStream(Stream.Null, hashAlgorithm, CryptoStreamMode.Write); byte[] array = new byte[128]; stream.Read(array, 0, 128); if (BitConverterLE.ToUInt16(array, 0) != 23117) { return(null); } uint num = BitConverterLE.ToUInt32(array, 60); cryptoStream.Write(array, 0, 128); if (num != 128u) { byte[] array2 = new byte[num - 128u]; stream.Read(array2, 0, array2.Length); cryptoStream.Write(array2, 0, array2.Length); } byte[] array3 = new byte[248]; stream.Read(array3, 0, 248); if (BitConverterLE.ToUInt32(array3, 0) != 17744u) { return(null); } if (BitConverterLE.ToUInt16(array3, 4) != 332) { return(null); } byte[] src = new byte[8]; Buffer.BlockCopy(src, 0, array3, 88, 4); Buffer.BlockCopy(src, 0, array3, 152, 8); cryptoStream.Write(array3, 0, 248); ushort num2 = BitConverterLE.ToUInt16(array3, 6); int num3 = (int)(num2 * 40); byte[] array4 = new byte[num3]; stream.Read(array4, 0, num3); cryptoStream.Write(array4, 0, num3); uint r = BitConverterLE.ToUInt32(array3, 232); uint num4 = this.RVAtoPosition(r, (int)num2, array4); int num5 = (int)BitConverterLE.ToUInt32(array3, 236); byte[] array5 = new byte[num5]; stream.Position = (long)((ulong)num4); stream.Read(array5, 0, num5); uint r2 = BitConverterLE.ToUInt32(array5, 32); strongNameSignature.SignaturePosition = this.RVAtoPosition(r2, (int)num2, array4); strongNameSignature.SignatureLength = BitConverterLE.ToUInt32(array5, 36); uint r3 = BitConverterLE.ToUInt32(array5, 8); strongNameSignature.MetadataPosition = this.RVAtoPosition(r3, (int)num2, array4); strongNameSignature.MetadataLength = BitConverterLE.ToUInt32(array5, 12); if (options == StrongName.StrongNameOptions.Metadata) { cryptoStream.Close(); hashAlgorithm.Initialize(); byte[] array6 = new byte[strongNameSignature.MetadataLength]; stream.Position = (long)((ulong)strongNameSignature.MetadataPosition); stream.Read(array6, 0, array6.Length); strongNameSignature.Hash = hashAlgorithm.ComputeHash(array6); return(strongNameSignature); } for (int i = 0; i < (int)num2; i++) { uint num6 = BitConverterLE.ToUInt32(array4, i * 40 + 20); int num7 = (int)BitConverterLE.ToUInt32(array4, i * 40 + 16); byte[] array7 = new byte[num7]; stream.Position = (long)((ulong)num6); stream.Read(array7, 0, num7); if (num6 <= strongNameSignature.SignaturePosition && (ulong)strongNameSignature.SignaturePosition < (ulong)num6 + (ulong)((long)num7)) { int num8 = (int)(strongNameSignature.SignaturePosition - num6); if (num8 > 0) { cryptoStream.Write(array7, 0, num8); } strongNameSignature.Signature = new byte[strongNameSignature.SignatureLength]; Buffer.BlockCopy(array7, num8, strongNameSignature.Signature, 0, (int)strongNameSignature.SignatureLength); Array.Reverse(strongNameSignature.Signature); int num9 = (int)((long)num8 + (long)((ulong)strongNameSignature.SignatureLength)); int num10 = num7 - num9; if (num10 > 0) { cryptoStream.Write(array7, num9, num10); } } else { cryptoStream.Write(array7, 0, num7); } } cryptoStream.Close(); strongNameSignature.Hash = hashAlgorithm.Hash; return(strongNameSignature); }