Exemplo n.º 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);
        }
Exemplo n.º 2
0
        internal StrongNameSignature StrongHash(Stream stream, StrongNameOptions options)
        {
            // Bing "msdn pecoff".
            //   https://msdn.microsoft.com/en-us/library/windows/desktop/ms680547(v=vs.85).aspx
            //   Very many of the magic constants and names, funny or otherwise, come from this.
            // ref: Section 24.2.1, Partition II Metadata
            // ref: Section 24.2.2, Partition II Metadata
            // ref: Section 24.3.3, Partition II Metadata

            // Read MS-DOS header.

            const int mzSize = 64;

            byte[] mz = new byte [mzSize];

            int peHeader = 0;
            int mzRead   = stream.Read(mz, 0, mzSize);

            if (mzRead == mzSize && mz [0] == (byte)'M' && mz [1] == (byte)'Z')               // 0x5a4d
            {
                peHeader = BitConverterLE.ToInt32(mz, 60);
                if (peHeader < mzSize)
                {
                    return(Error("peHeader_lt_64"));
                }

                // Read MS-DOS stub.

                mz = ReadMore(stream, mz, peHeader);
                if (mz == null)
                {
                    return(Error("read_mz2_failed"));
                }
            }
            else if (mzRead >= 4 && mz [0] == (byte)'P' && mz [1] == (byte)'E' && mz [2] == 0 && mz [3] == 0)                 // 0x4550
            // MS-DOS header/stub can be omitted and just start with PE, though it is rare.
            {
                stream.Position = 0;
                mz = new byte [0];
            }
            else
            {
                return(Error("read_mz_or_mzsig_failed"));
            }

            // PE File Header
            // PE signature 4 bytes
            // file header 20 bytes (really, at this point)
            // optional header varies in size and its size is in the file header
            // "optional" means "not in .obj files", but always in .dll/.exes

            const int sizeOfPeSignature         = 4;
            const int sizeOfFileHeader          = 20;
            const int sizeOfOptionalHeaderMagic = 2;
            const int offsetOfFileHeader        = sizeOfPeSignature;
            const int offsetOfOptionalHeader    = sizeOfPeSignature + sizeOfFileHeader;
            int       sizeOfOptionalHeader      = sizeOfOptionalHeaderMagic;  // initial minimum
            int       minimumHeadersSize        = offsetOfOptionalHeader + sizeOfOptionalHeader;

            byte[] pe = new byte [minimumHeadersSize];
            if (stream.Read(pe, 0, minimumHeadersSize) != minimumHeadersSize ||
                pe [0] != (byte)'P' || pe [1] != (byte)'E' || pe [2] != 0 || pe [3] != 0)                    // 0x4550
            {
                return(Error("read_minimumHeadersSize_or_pesig_failed"));
            }

            sizeOfOptionalHeader = BitConverterLE.ToUInt16(pe, offsetOfFileHeader + 16);
            if (sizeOfOptionalHeader < sizeOfOptionalHeaderMagic)
            {
                return(Error($"sizeOfOptionalHeader_lt_2 ${sizeOfOptionalHeader}"));
            }

            int headersSize = offsetOfOptionalHeader + sizeOfOptionalHeader;

            if (headersSize < offsetOfOptionalHeader)             // check overflow
            {
                return(Error("headers_overflow"));
            }

            // Read the rest of the NT headers (i.e. the rest of the optional header).

            pe = ReadMore(stream, pe, headersSize);
            if (pe == null)
            {
                return(Error("read_pe2_failed"));
            }

            uint magic = BitConverterLE.ToUInt16(pe, offsetOfOptionalHeader);

            // Refer to PE32+ as PE64 for brevity.
            // PE64 proposal that widened more fields was rejected.
            // Between PE32 and PE32+:
            //   Some fields are the same size and offset. For example the entire
            //      MS-DOS header, FileHeader, and section headers, and some of the optional header.
            //   Some fields are PE32-only (BaseOfData).
            //   Some fields are constant size, some are pointer size.
            //   Relative virtual addresses and file offsets are always 4 bytes.
            //   Some fields offsets are offset by 4, 8, or 12, but mostly 0 or 16,
            //     and it so happens that the 4/8/12-offset fields are less interesting.
            int  pe64 = 0;
            bool rom  = false;

            if (magic == 0x10B)
            {
                // nothing
            }
            else if (magic == 0x20B)
            {
                pe64 = 16;
            }
            else if (magic == 0x107)
            {
                rom = true;
            }
            else
            {
                return(Error("bad_magic_value"));
            }

            uint numberOfRvaAndSizes = 0;

            if (!rom)               // ROM images have no data directories or checksum.
            {
                if (sizeOfOptionalHeader >= offsetOfOptionalHeader + 92 + pe64 + 4)
                {
                    numberOfRvaAndSizes = BitConverterLE.ToUInt32(pe, offsetOfOptionalHeader + 92 + pe64);
                }

                // Clear CheckSum and Security Directory if present.
                // CheckSum is located the same for PE32+, all data directories are not.

                for (int i = 64; i < sizeOfOptionalHeader && i < 68; ++i)
                {
                    pe [offsetOfOptionalHeader + i] = 0;
                }

                for (int i = 128 + pe64; i < sizeOfOptionalHeader && i < 128 + 8 + pe64; ++i)
                {
                    pe [offsetOfOptionalHeader + i] = 0;
                }
            }

            // Read the section headers if present (an image can have no sections, just headers).

            const int sizeOfSectionHeader = 40;
            int       numberOfSections    = BitConverterLE.ToUInt16(pe, offsetOfFileHeader + 2);

            byte[] sectionHeaders = new byte [numberOfSections * sizeOfSectionHeader];
            if (stream.Read(sectionHeaders, 0, sectionHeaders.Length) != sectionHeaders.Length)
            {
                return(Error("read_section_headers_failed"));
            }

            // Read the CLR header if present.

            uint SignaturePosition = 0;
            uint SignatureLength   = 0;
            uint MetadataPosition  = 0;
            uint MetadataLength    = 0;

            if (15 < numberOfRvaAndSizes && sizeOfOptionalHeader >= 216 + pe64)
            {
                uint cliHeaderRVA = BitConverterLE.ToUInt32(pe, offsetOfOptionalHeader + 208 + pe64);
                uint cliHeaderPos = RVAtoPosition(cliHeaderRVA, numberOfSections, sectionHeaders);
                int  cliHeaderSiz = BitConverterLE.ToInt32(pe, offsetOfOptionalHeader + 208 + 4 + pe64);

                // CLI Header
                // ref: Section 24.3.3, Partition II Metadata
                var cli = new byte [cliHeaderSiz];
                stream.Position = cliHeaderPos;
                if (stream.Read(cli, 0, cliHeaderSiz) != cliHeaderSiz)
                {
                    return(Error("read_cli_header_failed"));
                }

                uint strongNameSignatureRVA = BitConverterLE.ToUInt32(cli, 32);
                SignaturePosition = RVAtoPosition(strongNameSignatureRVA, numberOfSections, sectionHeaders);
                SignatureLength   = BitConverterLE.ToUInt32(cli, 36);

                uint metadataRVA = BitConverterLE.ToUInt32(cli, 8);
                MetadataPosition = RVAtoPosition(metadataRVA, numberOfSections, sectionHeaders);
                MetadataLength   = BitConverterLE.ToUInt32(cli, 12);
            }

            StrongNameSignature info = new StrongNameSignature();

            info.SignaturePosition = SignaturePosition;
            info.SignatureLength   = SignatureLength;
            info.MetadataPosition  = MetadataPosition;
            info.MetadataLength    = MetadataLength;

            using (HashAlgorithm hash = HashAlgorithm.Create(TokenAlgorithm)) {
                if (options == StrongNameOptions.Metadata)
                {
                    hash.Initialize();
                    byte[] metadata = new byte [MetadataLength];
                    stream.Position = MetadataPosition;
                    if (stream.Read(metadata, 0, (int)MetadataLength) != (int)MetadataLength)
                    {
                        return(Error("read_cli_metadata_failed"));
                    }
                    info.Hash = hash.ComputeHash(metadata);
                    return(info);
                }

                using (CryptoStream cs = new CryptoStream(Stream.Null, hash, CryptoStreamMode.Write)) {
                    cs.Write(mz, 0, mz.Length);                      // Hash MS-DOS header/stub despite that stub is not run.
                    cs.Write(pe, 0, pe.Length);
                    cs.Write(sectionHeaders, 0, sectionHeaders.Length);

                    // now we hash every section EXCEPT the signature block
                    for (int i = 0; i < numberOfSections; i++)
                    {
                        UInt32 start   = BitConverterLE.ToUInt32(sectionHeaders, i * sizeOfSectionHeader + 20);
                        int    length  = BitConverterLE.ToInt32(sectionHeaders, i * sizeOfSectionHeader + 16);
                        byte[] section = new byte [length];
                        stream.Position = start;
                        if (stream.Read(section, 0, length) != length)
                        {
                            return(Error("read_section_failed"));
                        }
                        // The signature is assumed not to straddle sections.
                        if ((start <= SignaturePosition) && (SignaturePosition < start + (uint)length))
                        {
                            // hash before the signature
                            int before = (int)(SignaturePosition - start);
                            if (before > 0)
                            {
                                cs.Write(section, 0, before);
                            }

                            // copy signature
                            info.Signature = new byte [SignatureLength];
                            Buffer.BlockCopy(section, before, info.Signature, 0, (int)SignatureLength);
                            Array.Reverse(info.Signature);
                            // hash after the signature
                            int s     = (int)(before + SignatureLength);
                            int after = (int)(length - s);
                            if (after > 0)
                            {
                                cs.Write(section, s, after);
                            }
                        }
                        else
                        {
                            cs.Write(section, 0, length);
                        }
                    }
                }
                info.Hash = hash.Hash;
            }
            return(info);
        }
Exemplo n.º 3
0
        internal StrongNameSignature StrongHash(Stream stream, StrongNameOptions options)
        {
            StrongNameSignature signature = new StrongNameSignature();
            HashAlgorithm       transform = HashAlgorithm.Create(this.TokenAlgorithm);
            CryptoStream        stream2   = new CryptoStream(Stream.Null, transform, CryptoStreamMode.Write);

            byte[] buffer = new byte[0x80];
            stream.Read(buffer, 0, 0x80);
            if (BitConverterLE.ToUInt16(buffer, 0) != 0x5a4d)
            {
                return(null);
            }
            uint num = BitConverterLE.ToUInt32(buffer, 60);

            stream2.Write(buffer, 0, 0x80);
            if (num != 0x80)
            {
                byte[] buffer2 = new byte[num - 0x80];
                stream.Read(buffer2, 0, buffer2.Length);
                stream2.Write(buffer2, 0, buffer2.Length);
            }
            byte[] buffer3 = new byte[0xf8];
            stream.Read(buffer3, 0, 0xf8);
            if (BitConverterLE.ToUInt32(buffer3, 0) != 0x4550)
            {
                return(null);
            }
            if (BitConverterLE.ToUInt16(buffer3, 4) != 0x14c)
            {
                return(null);
            }
            byte[] src = new byte[8];
            Buffer.BlockCopy(src, 0, buffer3, 0x58, 4);
            Buffer.BlockCopy(src, 0, buffer3, 0x98, 8);
            stream2.Write(buffer3, 0, 0xf8);
            ushort sections = BitConverterLE.ToUInt16(buffer3, 6);
            int    count    = sections * 40;

            byte[] buffer5 = new byte[count];
            stream.Read(buffer5, 0, count);
            stream2.Write(buffer5, 0, count);
            uint r    = BitConverterLE.ToUInt32(buffer3, 0xe8);
            uint num5 = this.RVAtoPosition(r, sections, buffer5);
            int  num6 = (int)BitConverterLE.ToUInt32(buffer3, 0xec);

            byte[] buffer6 = new byte[num6];
            stream.Position = num5;
            stream.Read(buffer6, 0, num6);
            uint num7 = BitConverterLE.ToUInt32(buffer6, 0x20);

            signature.SignaturePosition = this.RVAtoPosition(num7, sections, buffer5);
            signature.SignatureLength   = BitConverterLE.ToUInt32(buffer6, 0x24);
            uint num8 = BitConverterLE.ToUInt32(buffer6, 8);

            signature.MetadataPosition = this.RVAtoPosition(num8, sections, buffer5);
            signature.MetadataLength   = BitConverterLE.ToUInt32(buffer6, 12);
            if (options == StrongNameOptions.Metadata)
            {
                stream2.Close();
                transform.Initialize();
                byte[] buffer7 = new byte[signature.MetadataLength];
                stream.Position = signature.MetadataPosition;
                stream.Read(buffer7, 0, buffer7.Length);
                signature.Hash = transform.ComputeHash(buffer7);
                return(signature);
            }
            for (int i = 0; i < sections; i++)
            {
                uint   num10   = BitConverterLE.ToUInt32(buffer5, (i * 40) + 20);
                int    num11   = (int)BitConverterLE.ToUInt32(buffer5, (i * 40) + 0x10);
                byte[] buffer8 = new byte[num11];
                stream.Position = num10;
                stream.Read(buffer8, 0, num11);
                if ((num10 <= signature.SignaturePosition) && (signature.SignaturePosition < (num10 + num11)))
                {
                    int num12 = (int)(signature.SignaturePosition - num10);
                    if (num12 > 0)
                    {
                        stream2.Write(buffer8, 0, num12);
                    }
                    signature.Signature = new byte[signature.SignatureLength];
                    Buffer.BlockCopy(buffer8, num12, signature.Signature, 0, (int)signature.SignatureLength);
                    Array.Reverse(signature.Signature);
                    int offset = num12 + ((int)signature.SignatureLength);
                    int num14  = num11 - offset;
                    if (num14 > 0)
                    {
                        stream2.Write(buffer8, offset, num14);
                    }
                }
                else
                {
                    stream2.Write(buffer8, 0, num11);
                }
            }
            stream2.Close();
            signature.Hash = transform.Hash;
            return(signature);
        }
Exemplo n.º 4
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;
		}
Exemplo n.º 5
0
        internal StrongNameSignature StrongHash(Stream stream, StrongNameOptions options)
        {
            StrongNameSignature strongNameSignature = new StrongNameSignature();
            HashAlgorithm       hashAlgorithm       = HashAlgorithm.Create(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 != 128)
            {
                byte[] array2 = new byte[num - 128];
                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) != 17744)
            {
                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 = 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 = RVAtoPosition(r, num2, array4);
            int  num5 = (int)BitConverterLE.ToUInt32(array3, 236);

            byte[] array5 = new byte[num5];
            stream.Position = num4;
            stream.Read(array5, 0, num5);
            uint r2 = BitConverterLE.ToUInt32(array5, 32);

            strongNameSignature.SignaturePosition = RVAtoPosition(r2, num2, array4);
            strongNameSignature.SignatureLength   = BitConverterLE.ToUInt32(array5, 36);
            uint r3 = BitConverterLE.ToUInt32(array5, 8);

            strongNameSignature.MetadataPosition = RVAtoPosition(r3, num2, array4);
            strongNameSignature.MetadataLength   = BitConverterLE.ToUInt32(array5, 12);
            if (options == StrongNameOptions.Metadata)
            {
                cryptoStream.Close();
                hashAlgorithm.Initialize();
                byte[] array6 = new byte[strongNameSignature.MetadataLength];
                stream.Position = strongNameSignature.MetadataPosition;
                stream.Read(array6, 0, array6.Length);
                strongNameSignature.Hash = hashAlgorithm.ComputeHash(array6);
                return(strongNameSignature);
            }
            for (int i = 0; i < 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 = num6;
                stream.Read(array7, 0, num7);
                if (num6 <= strongNameSignature.SignaturePosition && strongNameSignature.SignaturePosition < num6 + 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)(num8 + 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);
        }