Ejemplo n.º 1
0
 private static unsafe MethodBodyBlock ReadMethodBody(byte[] body)
 {
     fixed(byte *bodyPtr = &body[0])
     {
         return(MethodBodyBlock.Create(new BlobReader(bodyPtr, body.Length)));
     }
 }
Ejemplo n.º 2
0
    private static unsafe void VisualizeGenerationIL(MetadataVisualizer visualizer, int generationIndex, GenerationData generation, MetadataReader mdReader)
    {
        if (generation.PEReaderOpt != null)
        {
            foreach (var methodHandle in mdReader.MethodDefinitions)
            {
                var method = mdReader.GetMethodDefinition(methodHandle);
                var rva    = method.RelativeVirtualAddress;
                if (rva != 0)
                {
                    var body = generation.PEReaderOpt.GetMethodBody(rva);
                    visualizer.VisualizeMethodBody(body, methodHandle);
                }
            }
        }
        else if (generation.DeltaILOpt != null)
        {
            fixed(byte *deltaILPtr = generation.DeltaILOpt)
            {
                foreach (var generationHandle in mdReader.MethodDefinitions)
                {
                    var method = mdReader.GetMethodDefinition(generationHandle);
                    var rva    = method.RelativeVirtualAddress;
                    if (rva != 0)
                    {
                        var body = MethodBodyBlock.Create(new BlobReader(deltaILPtr + rva, generation.DeltaILOpt.Length - rva));

                        visualizer.VisualizeMethodBody(body, generationHandle, generationIndex);
                    }
                }
            }
        }
    }
Ejemplo n.º 3
0
        public static unsafe string GetMethodIL(this ImmutableArray <byte> ilArray)
        {
            var result = new StringBuilder();

            fixed(byte *ilPtr = ilArray.ToArray())
            {
                int offset = 0;

                while (true)
                {
                    // skip padding:
                    while (offset < ilArray.Length && ilArray[offset] == 0)
                    {
                        offset++;
                    }

                    if (offset == ilArray.Length)
                    {
                        break;
                    }

                    var reader   = new BlobReader(ilPtr + offset, ilArray.Length - offset);
                    var methodIL = MethodBodyBlock.Create(reader);

                    if (methodIL == null)
                    {
                        result.AppendFormat(
                            "<invalid byte 0x{0:X2} at offset {1}>",
                            ilArray[offset],
                            offset
                            );
                        offset++;
                    }
                    else
                    {
                        ILVisualizer.Default.DumpMethod(
                            result,
                            methodIL.MaxStack,
                            methodIL.GetILContent(),
                            ImmutableArray.Create <ILVisualizer.LocalInfo>(),
                            ImmutableArray.Create <ILVisualizer.HandlerSpan>()
                            );

                        offset += methodIL.Size;
                    }
                }
            }

            return(result.ToString());
        }
Ejemplo n.º 4
0
        public static unsafe MethodBodyBlock GetMethodBodyBlock(this ImmutableArray <byte> ilArray)
        {
            fixed(byte *ilPtr = ilArray.AsSpan())
            {
                int offset = 0;

                // skip padding:
                while (offset < ilArray.Length && ilArray[offset] == 0)
                {
                    offset++;
                }

                var reader = new BlobReader(ilPtr + offset, ilArray.Length - offset);

                return(MethodBodyBlock.Create(reader));
            }
        }
Ejemplo n.º 5
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            if (relocsOnly)
            {
                return(new ObjectData(
                           data: Array.Empty <byte>(),
                           relocs: Array.Empty <Relocation>(),
                           alignment: 1,
                           definedSymbols: new ISymbolDefinitionNode[] { this }));
            }

            var rva    = _method.MetadataReader.GetMethodDefinition(_method.Handle).RelativeVirtualAddress;
            var reader = _method.Module.PEReader.GetSectionData(rva).GetReader();
            int size   = MethodBodyBlock.Create(reader).Size;

            return(new ObjectData(reader.ReadBytes(size), Array.Empty <Relocation>(), 4, new ISymbolDefinitionNode[] { this }));
        }
Ejemplo n.º 6
0
        private static unsafe void VisualizeGenerationIL(MetadataVisualizer visualizer, int generationIndex, GenerationData generation, MetadataReader mdReader)
        {
            try
            {
                if (generation.PEReaderOpt != null)
                {
                    foreach (var methodHandle in mdReader.MethodDefinitions)
                    {
                        visualizer.VisualizeMethodBody(methodHandle, rva => generation.PEReaderOpt.GetMethodBody(rva));
                    }
                }
                else if (generation.ILDeltaOpt != null)
                {
                    fixed(byte *deltaILPtr = generation.ILDeltaOpt)
                    {
                        foreach (var generationHandle in mdReader.MethodDefinitions)
                        {
                            var method = mdReader.GetMethodDefinition(generationHandle);
                            var rva    = method.RelativeVirtualAddress;
                            if (rva != 0)
                            {
                                var body = MethodBodyBlock.Create(new BlobReader(deltaILPtr + rva, generation.ILDeltaOpt.Length - rva));

                                visualizer.VisualizeMethodBody(body, generationHandle, generationIndex);
                            }
                        }
                    }
                }
                else
                {
                    visualizer.WriteLine("<IL not available>");
                }
            }
            catch (BadImageFormatException)
            {
                visualizer.WriteLine("<bad metadata>");
            }
        }
Ejemplo n.º 7
0
        public unsafe void FatBody()
        {
            var streamBuilder = new BlobBuilder();
            var codeBuilder   = new BlobBuilder();
            var flowBuilder   = new ControlFlowBuilder();
            var il            = new InstructionEncoder(codeBuilder, flowBuilder);

            codeBuilder.WriteBytes(1, 62);
            var l1 = il.DefineLabel();

            il.MarkLabel(l1);

            Assert.Equal(62, flowBuilder.Labels.Single());

            il.Branch(ILOpCode.Br_s, l1);

            var brInfo = flowBuilder.Branches.Single();

            Assert.Equal(62, brInfo.ILOffset);
            Assert.Equal(l1, brInfo.Label);
            Assert.Equal(ILOpCode.Br_s, brInfo.OpCode);

            AssertEx.Equal(new byte[] { 1, 1, (byte)ILOpCode.Br_s, unchecked ((byte)-1) }, codeBuilder.ToArray(60, 4));

            var streamEncoder = new MethodBodyStreamEncoder(streamBuilder);
            int bodyOffset    = streamEncoder.AddMethodBody(
                il,
                maxStack: 2,
                localVariablesSignature: default(StandaloneSignatureHandle),
                attributes: MethodBodyAttributes.None);

            var bodyBytes = streamBuilder.ToArray();

            AssertEx.Equal(new byte[]
            {
                0x03, 0x30, 0x02, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // fat header
                0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x2B, 0xFE
            }, bodyBytes);

            fixed(byte *bodyPtr = &bodyBytes[0])
            {
                var body = MethodBodyBlock.Create(new BlobReader(bodyPtr, bodyBytes.Length));

                Assert.Equal(0, body.ExceptionRegions.Length);
                Assert.Equal(default(StandaloneSignatureHandle), body.LocalSignature);
                Assert.Equal(2, body.MaxStack);
                Assert.Equal(bodyBytes.Length, body.Size);

                var ilBytes = body.GetILBytes();

                AssertEx.Equal(new byte[]
                {
                    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x2B, 0xFE
                }, ilBytes);
            }
        }
Ejemplo n.º 8
0
        public unsafe void TinyBody()
        {
            var bodyBuilder   = new BlobBuilder();
            var codeBuilder   = new BlobBuilder();
            var branchBuilder = new BranchBuilder();
            var il            = new InstructionEncoder(codeBuilder, branchBuilder);

            var bodyEncoder = new MethodBodyEncoder(
                bodyBuilder,
                maxStack: 2,
                exceptionRegionCount: 0,
                localVariablesSignature: default(StandaloneSignatureHandle),
                attributes: MethodBodyAttributes.None);

            Assert.True(bodyEncoder.IsTiny(10));
            Assert.True(bodyEncoder.IsTiny(63));
            Assert.False(bodyEncoder.IsTiny(64));

            codeBuilder.WriteBytes(1, 61);
            var l1 = il.DefineLabel();

            il.MarkLabel(l1);

            Assert.Equal(61, branchBuilder.Labels.Single());

            il.Branch(ILOpCode.Br, l1);

            var brInfo = branchBuilder.Branches.Single();

            Assert.Equal(61, brInfo.ILOffset);
            Assert.Equal(l1, brInfo.Label);
            Assert.Equal((byte)ILOpCode.Br_s, brInfo.ShortOpCode);

            AssertEx.Equal(new byte[] { 1, (byte)ILOpCode.Br_s, unchecked ((byte)-1) }, codeBuilder.ToArray(60, 3));

            int bodyOffset;

            bodyEncoder.WriteInstructions(codeBuilder, branchBuilder, out bodyOffset);

            var bodyBytes = bodyBuilder.ToArray();

            AssertEx.Equal(new byte[]
            {
                0xFE, // tiny header
                0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                0x01, 0x01, 0x01, 0x01, 0x01, 0x2B, 0xFE
            }, bodyBytes);

            fixed(byte *bodyPtr = &bodyBytes[0])
            {
                var body = MethodBodyBlock.Create(new BlobReader(bodyPtr, bodyBytes.Length));

                Assert.Equal(0, body.ExceptionRegions.Length);
                Assert.Equal(default(StandaloneSignatureHandle), body.LocalSignature);
                Assert.Equal(8, body.MaxStack);
                Assert.Equal(bodyBytes.Length, body.Size);

                var ilBytes = body.GetILBytes();

                AssertEx.Equal(new byte[]
                {
                    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                    0x01, 0x01, 0x01, 0x01, 0x01, 0x2B, 0xFE
                }, ilBytes);
            }
        }