Example #1
0
        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);
        }