コード例 #1
0
        private static int WriteEmbeddedPortablePdbData(BlobBuilder builder, BlobBuilder debugMetadata)
        {
            int start = builder.Count;

            // header (signature, decompressed size):
            builder.WriteUInt32(PortablePdbVersions.DebugDirectoryEmbeddedSignature);
            builder.WriteInt32(debugMetadata.Count);

            // compressed data:
            var compressed = new MemoryStream();
            using (var deflate = new DeflateStream(compressed, CompressionLevel.Optimal, leaveOpen: true))
            {
                foreach (var blob in debugMetadata.GetBlobs())
                {
                    var segment = blob.GetBytes();
                    deflate.Write(segment.Array, segment.Offset, segment.Count);
                }
            }

            // TODO: avoid multiple copies:
            builder.WriteBytes(compressed.ToArray());

            return builder.Count - start;
        }
コード例 #2
0
ファイル: PEBuilder.cs プロジェクト: ESgarbi/corefx
        public BlobContentId Serialize(BlobBuilder builder)
        {
            // Define and serialize sections in two steps.
            // We need to know about all sections before serializing them.
            var serializedSections = SerializeSections();

            // The positions and sizes of directories are calculated during section serialization.
            var directories = GetDirectories();

            Blob stampFixup;
            WritePESignature(builder);
            WriteCoffHeader(builder, serializedSections, out stampFixup);
            WritePEHeader(builder, directories, serializedSections);
            WriteSectionHeaders(builder, serializedSections);
            builder.Align(Header.FileAlignment);

            foreach (var section in serializedSections)
            {
                builder.LinkSuffix(section.Builder);
                builder.Align(Header.FileAlignment);
            }

            var contentId = IdProvider(builder.GetBlobs());

            // patch timestamp in COFF header:
            var stampWriter = new BlobWriter(stampFixup);
            stampWriter.WriteUInt32(contentId.Stamp);
            Debug.Assert(stampWriter.RemainingBytes == 0);

            return contentId;
        }
コード例 #3
0
ファイル: ManagedPEBuilder.cs プロジェクト: ChuangYang/corefx
        private IEnumerable<Blob> GetContentToSign(BlobBuilder peImage)
        {
            // Signed content includes 
            // - PE header without its alignment padding
            // - all sections including their alignment padding and excluding strong name signature blob

            int remainingHeader = Header.ComputeSizeOfPeHeaders(GetSections().Length);
            foreach (var blob in peImage.GetBlobs())
            {
                if (remainingHeader > 0)
                {
                    int length = Math.Min(remainingHeader, blob.Length);
                    yield return new Blob(blob.Buffer, blob.Start, length);
                    remainingHeader -= length;
                }
                else if (blob.Buffer == _lazyStrongNameSignature.Buffer)
                {
                    yield return new Blob(blob.Buffer, blob.Start, _lazyStrongNameSignature.Start - blob.Start);
                    yield return new Blob(blob.Buffer, _lazyStrongNameSignature.Start + _lazyStrongNameSignature.Length, blob.Length - _lazyStrongNameSignature.Length);
                }
                else
                {
                    yield return new Blob(blob.Buffer, blob.Start, blob.Length);
                }
            }
        }
コード例 #4
0
ファイル: PEBuilder.cs プロジェクト: geoffkizer/corefx
        // internal for testing
        internal static IEnumerable<Blob> GetContentToSign(BlobBuilder peImage, int peHeadersSize, int peHeaderAlignment, Blob strongNameSignatureFixup)
        {
            // Signed content includes 
            // - PE header without its alignment padding
            // - all sections including their alignment padding and excluding strong name signature blob

            // PE specification: 
            //   To calculate the PE image hash, Authenticode orders the sections that are specified in the section table 
            //   by address range, then hashes the resulting sequence of bytes, passing over the exclusion ranges.
            // 
            // Note that sections are by construction ordered by their address, so there is no need to reorder.

            int remainingHeaderToSign = peHeadersSize;
            int remainingHeader = BitArithmetic.Align(peHeadersSize, peHeaderAlignment);
            foreach (var blob in peImage.GetBlobs())
            {
                int blobStart = blob.Start;
                int blobLength = blob.Length;
                while (blobLength > 0)
                {
                    if (remainingHeader > 0)
                    {
                        int length;

                        if (remainingHeaderToSign > 0)
                        {
                            length = Math.Min(remainingHeaderToSign, blobLength);
                            yield return new Blob(blob.Buffer, blobStart, length);
                            remainingHeaderToSign -= length;
                        }
                        else
                        {
                            length = Math.Min(remainingHeader, blobLength);
                        }

                        remainingHeader -= length;
                        blobStart += length;
                        blobLength -= length;
                    }
                    else if (blob.Buffer == strongNameSignatureFixup.Buffer)
                    {
                        yield return GetPrefixBlob(new Blob(blob.Buffer, blobStart, blobLength), strongNameSignatureFixup);
                        yield return GetSuffixBlob(new Blob(blob.Buffer, blobStart, blobLength), strongNameSignatureFixup);
                        break;
                    }
                    else
                    {
                        yield return new Blob(blob.Buffer, blobStart, blobLength);
                        break;
                    }
                }
            }
        }
コード例 #5
0
ファイル: PEBuilder.cs プロジェクト: geoffkizer/corefx
 // internal for testing
 internal static IEnumerable<Blob> GetContentToChecksum(BlobBuilder peImage, Blob checksumFixup)
 {
     foreach (var blob in peImage.GetBlobs())
     {
         if (blob.Buffer == checksumFixup.Buffer)
         {
             yield return GetPrefixBlob(blob, checksumFixup);
             yield return GetSuffixBlob(blob, checksumFixup);
         }
         else
         {
             yield return blob;
         }
     }
 }
コード例 #6
0
ファイル: PEBuilderTests.cs プロジェクト: geoffkizer/corefx
        private static bool TestChecksumAndAuthenticodeSignature(Stream peStream, byte[] privateKeyOpt = null)
        {
            var peHeaders = new PEHeaders(peStream);
            bool is32bit = peHeaders.PEHeader.Magic == PEMagic.PE32;
            uint expectedChecksum = peHeaders.PEHeader.CheckSum;
            int peHeadersSize = peHeaders.PEHeaderStartOffset + PEHeader.Size(is32bit) + SectionHeader.Size * peHeaders.SectionHeaders.Length;

            peStream.Position = 0;

            if (expectedChecksum == 0)
            {
                // not signed
                return false;
            }

            int peSize = (int)peStream.Length;
            var peImage = new BlobBuilder(peSize);
            Assert.Equal(peSize, peImage.TryWriteBytes(peStream, peSize));

            var buffer = peImage.GetBlobs().Single().Buffer;
            var checksumBlob = new Blob(buffer, peHeaders.PEHeaderStartOffset + PEHeader.OffsetOfChecksum, sizeof(uint));

            uint checksum = PEBuilder.CalculateChecksum(peImage, checksumBlob);
            Assert.Equal(expectedChecksum, checksum);

            // validate signature:
            if (privateKeyOpt != null)
            {
                // signature is calculated with checksum zeroed:
                new BlobWriter(checksumBlob).WriteUInt32(0);

                int snOffset;
                Assert.True(peHeaders.TryGetDirectoryOffset(peHeaders.CorHeader.StrongNameSignatureDirectory, out snOffset));
                var snBlob = new Blob(buffer, snOffset, peHeaders.CorHeader.StrongNameSignatureDirectory.Size);
                var expectedSignature = snBlob.GetBytes().ToArray();
                var signature = SigningUtilities.CalculateRsaSignature(PEBuilder.GetContentToSign(peImage, peHeadersSize, peHeaders.PEHeader.FileAlignment, snBlob), privateKeyOpt);
                AssertEx.Equal(expectedSignature, signature);
            }

            return true;
        }
コード例 #7
0
ファイル: PEBuilderTests.cs プロジェクト: geoffkizer/corefx
        private static IEnumerable<string> GetBlobRanges(BlobBuilder builder, IEnumerable<Blob> blobs)
        {
            var blobIndex = new Dictionary<byte[], int>();
            int i = 0;
            foreach (var blob in builder.GetBlobs())
            {
                blobIndex.Add(blob.Buffer, i++);
            }

            foreach (var blob in blobs)
            {
                yield return $"{blobIndex[blob.Buffer]}: [{blob.Start}, {blob.Start + blob.Length})";
            }
        }
コード例 #8
0
ファイル: PEBuilderTests.cs プロジェクト: geoffkizer/corefx
        public void GetContentToSign_HeaderAndFixupInDistinctBlobs()
        {
            var builder = new BlobBuilder(16);
            builder.WriteBytes(0, 16);
            builder.WriteBytes(1, 16);
            builder.WriteBytes(2, 16);
            builder.WriteBytes(3, 16);
            var snFixup = builder.ReserveBytes(16);
            builder.WriteBytes(5, 16);
            builder.WriteBytes(6, 1);
            Assert.Equal(7, builder.GetBlobs().Count());

            AssertEx.Equal(
                new[]
                {
                    "0: [0, 1)",
                    "0: [4, 16)",
                    "1: [0, 16)",
                    "2: [0, 16)",
                    "3: [0, 16)",
                    "4: [0, 0)",
                    "4: [16, 16)",
                    "5: [0, 16)",
                    "6: [0, 1)"
                },
                GetBlobRanges(builder, PEBuilder.GetContentToSign(builder, peHeadersSize: 1, peHeaderAlignment: 4, strongNameSignatureFixup: snFixup)));
        }
コード例 #9
0
ファイル: PEBuilderTests.cs プロジェクト: geoffkizer/corefx
        public void GetContentToSign_MultiBlobHeader()
        {
            var builder = new BlobBuilder(16);
            builder.WriteBytes(0, 16);
            builder.WriteBytes(1, 16);
            builder.WriteBytes(2, 16);
            builder.WriteBytes(3, 16);
            builder.WriteBytes(4, 2);
            var snFixup = builder.ReserveBytes(1);
            builder.WriteBytes(4, 13);
            builder.WriteBytes(5, 10);
            Assert.Equal(6, builder.GetBlobs().Count());

            AssertEx.Equal(
                new[]
                {
                    "0: [0, 16)",
                    "1: [0, 16)",
                    "2: [0, 1)",
                    "4: [0, 2)",
                    "4: [3, 16)",
                    "5: [0, 10)"
                },
                GetBlobRanges(builder, PEBuilder.GetContentToSign(builder, peHeadersSize: 33, peHeaderAlignment: 64, strongNameSignatureFixup: snFixup)));
        }
コード例 #10
0
ファイル: PEBuilderTests.cs プロジェクト: geoffkizer/corefx
        public void GetContentToSign_AllInOneBlob()
        {
            var builder = new BlobBuilder(16);
            builder.WriteBytes(1, 5);
            var snFixup = builder.ReserveBytes(5);
            builder.WriteBytes(2, 6);
            Assert.Equal(1, builder.GetBlobs().Count());

            AssertEx.Equal(
                new[]
                {
                    "0: [0, 2)",
                    "0: [4, 5)",
                    "0: [10, 16)"
                },
                GetBlobRanges(builder, PEBuilder.GetContentToSign(builder, peHeadersSize: 2, peHeaderAlignment: 4, strongNameSignatureFixup: snFixup)));
        }