bool ScanMethodBody(ITypeDefinition analyzedEntity, IMethod method, MethodBodyBlock methodBody)
        {
            bool found          = false;
            var  blob           = methodBody.GetILReader();
            var  module         = (MetadataModule)method.ParentModule;
            var  genericContext = new Decompiler.TypeSystem.GenericContext();            // type parameters don't matter for this analyzer

            while (!found && blob.RemainingBytes > 0)
            {
                var opCode = blob.DecodeOpCode();
                if (!CanBeReference(opCode))
                {
                    blob.SkipOperand(opCode);
                    continue;
                }
                EntityHandle methodHandle = MetadataTokenHelpers.EntityHandleOrNil(blob.ReadInt32());
                if (!methodHandle.Kind.IsMemberKind())
                {
                    continue;
                }
                var ctor = module.ResolveMethod(methodHandle, genericContext);
                if (ctor == null || !ctor.IsConstructor)
                {
                    continue;
                }

                if (ctor.DeclaringTypeDefinition?.MetadataToken == analyzedEntity.MetadataToken &&
                    ctor.ParentModule.PEFile == analyzedEntity.ParentModule.PEFile)
                {
                    return(true);
                }
            }

            return(false);
        }
Beispiel #2
0
        public static int GetCodeSize(this MethodBodyBlock body)
        {
            if (body == null)
            {
                throw new ArgumentNullException(nameof(body));
            }

            return(body.GetILReader().Length);
        }
Beispiel #3
0
        bool ScanMethodBody(IField analyzedField, IMethod method, MethodBodyBlock methodBody)
        {
            if (methodBody == null)
            {
                return(false);
            }

            var mainModule     = (MetadataModule)method.ParentModule;
            var blob           = methodBody.GetILReader();
            var genericContext = new Decompiler.TypeSystem.GenericContext();             // type parameters don't matter for this analyzer

            while (blob.RemainingBytes > 0)
            {
                ILOpCode opCode;
                try
                {
                    opCode = blob.DecodeOpCode();
                    if (!CanBeReference(opCode))
                    {
                        blob.SkipOperand(opCode);
                        continue;
                    }
                }
                catch (BadImageFormatException)
                {
                    return(false);
                }
                EntityHandle fieldHandle = MetadataTokenHelpers.EntityHandleOrNil(blob.ReadInt32());
                if (!fieldHandle.Kind.IsMemberKind())
                {
                    continue;
                }
                IField field;
                try
                {
                    field = mainModule.ResolveEntity(fieldHandle, genericContext) as IField;
                }
                catch (BadImageFormatException)
                {
                    continue;
                }
                if (field == null)
                {
                    continue;
                }

                if (field.MetadataToken == analyzedField.MetadataToken &&
                    field.ParentModule.PEFile == analyzedField.ParentModule.PEFile)
                {
                    return(true);
                }
            }

            return(false);
        }
Beispiel #4
0
		public void Read(MethodBodyBlock body)
		{
			BlobReader ilReader = body.GetILReader();

			this.Read(ref ilReader);
		}
Beispiel #5
0
        void ScanMethodBody(TypeDefinitionUsedVisitor visitor, IMethod method, MethodBodyBlock methodBody, AnalyzerContext context)
        {
            if (methodBody == null)
            {
                return;
            }

            var module         = (MetadataModule)method.ParentModule;
            var genericContext = new Decompiler.TypeSystem.GenericContext();             // type parameters don't matter for this analyzer

            if (!methodBody.LocalSignature.IsNil)
            {
                ImmutableArray <IType> localSignature;
                try
                {
                    localSignature = module.DecodeLocalSignature(methodBody.LocalSignature, genericContext);
                }
                catch (BadImageFormatException)
                {
                    // Issue #2197: ignore invalid local signatures
                    localSignature = ImmutableArray <IType> .Empty;
                }
                foreach (var type in localSignature)
                {
                    type.AcceptVisitor(visitor);

                    if (visitor.Found)
                    {
                        return;
                    }
                }
            }

            var blob = methodBody.GetILReader();

            while (!visitor.Found && blob.RemainingBytes > 0)
            {
                var opCode = blob.DecodeOpCode();
                switch (opCode.GetOperandType())
                {
                case OperandType.Field:
                case OperandType.Method:
                case OperandType.Sig:
                case OperandType.Tok:
                case OperandType.Type:
                    var member = MetadataTokenHelpers.EntityHandleOrNil(blob.ReadInt32());
                    if (member.IsNil)
                    {
                        continue;
                    }
                    switch (member.Kind)
                    {
                    case HandleKind.TypeReference:
                    case HandleKind.TypeSpecification:
                    case HandleKind.TypeDefinition:
                        module.ResolveType(member, genericContext).AcceptVisitor(visitor);
                        if (visitor.Found)
                        {
                            return;
                        }
                        break;

                    case HandleKind.FieldDefinition:
                    case HandleKind.MethodDefinition:
                    case HandleKind.MemberReference:
                    case HandleKind.MethodSpecification:
                        VisitMember(visitor, module.ResolveEntity(member, genericContext) as IMember, context);

                        if (visitor.Found)
                        {
                            return;
                        }
                        break;

                    case HandleKind.StandaloneSignature:
                        var(_, fpt) = module.DecodeMethodSignature((StandaloneSignatureHandle)member, genericContext);
                        fpt.AcceptVisitor(visitor);

                        if (visitor.Found)
                        {
                            return;
                        }
                        break;

                    default:
                        break;
                    }
                    break;

                default:
                    blob.SkipOperand(opCode);
                    break;
                }
            }
        }
        void CollectNamespacesFromMethodBody(MethodBodyBlock method, MetadataModule module)
        {
            var metadata     = module.metadata;
            var instructions = method.GetILReader();

            if (!method.LocalSignature.IsNil)
            {
                ImmutableArray <IType> localSignature;
                try {
                    localSignature = module.DecodeLocalSignature(method.LocalSignature, genericContext);
                } catch (BadImageFormatException) {
                    // Issue #1211: ignore invalid local signatures
                    localSignature = ImmutableArray <IType> .Empty;
                }
                foreach (var type in localSignature)
                {
                    CollectNamespacesForTypeReference(type);
                }
            }

            foreach (var region in method.ExceptionRegions)
            {
                if (region.CatchType.IsNil)
                {
                    continue;
                }
                IType ty;
                try {
                    ty = module.ResolveType(region.CatchType, genericContext);
                } catch (BadImageFormatException) {
                    continue;
                }
                CollectNamespacesForTypeReference(ty);
            }

            while (instructions.RemainingBytes > 0)
            {
                ILOpCode opCode;
                try {
                    opCode = instructions.DecodeOpCode();
                } catch (BadImageFormatException) {
                    return;
                }
                switch (opCode.GetOperandType())
                {
                case OperandType.Field:
                case OperandType.Method:
                case OperandType.Sig:
                case OperandType.Tok:
                case OperandType.Type:
                    var handle = MetadataTokenHelpers.EntityHandleOrNil(instructions.ReadInt32());
                    if (handle.IsNil)
                    {
                        break;
                    }
                    switch (handle.Kind)
                    {
                    case HandleKind.TypeDefinition:
                    case HandleKind.TypeReference:
                    case HandleKind.TypeSpecification:
                        IType type;
                        try {
                            type = module.ResolveType(handle, genericContext);
                        } catch (BadImageFormatException) {
                            break;
                        }
                        CollectNamespacesForTypeReference(type);
                        break;

                    case HandleKind.FieldDefinition:
                    case HandleKind.MethodDefinition:
                    case HandleKind.MethodSpecification:
                    case HandleKind.MemberReference:
                        IMember member;
                        try {
                            member = module.ResolveEntity(handle, genericContext) as IMember;
                        } catch (BadImageFormatException) {
                            break;
                        }
                        CollectNamespacesForMemberReference(member);
                        break;

                    case HandleKind.StandaloneSignature:
                        StandaloneSignature sig;
                        try {
                            sig = metadata.GetStandaloneSignature((StandaloneSignatureHandle)handle);
                        } catch (BadImageFormatException) {
                            break;
                        }
                        if (sig.GetKind() == StandaloneSignatureKind.Method)
                        {
                            MethodSignature <IType> methodSig;
                            try {
                                methodSig = module.DecodeMethodSignature((StandaloneSignatureHandle)handle, genericContext);
                            } catch (BadImageFormatException) {
                                break;
                            }
                            CollectNamespacesForTypeReference(methodSig.ReturnType);
                            foreach (var paramType in methodSig.ParameterTypes)
                            {
                                CollectNamespacesForTypeReference(paramType);
                            }
                        }
                        break;
                    }
                    break;

                default:
                    try {
                        instructions.SkipOperand(opCode);
                    } catch (BadImageFormatException) {
                        return;
                    }
                    break;
                }
            }
        }
Beispiel #7
0
        public ILStructure(PEFile module, MethodDefinitionHandle handle, MetadataGenericContext genericContext, MethodBodyBlock body)
            : this(module, handle, genericContext, ILStructureType.Root, 0, body.GetILReader().Length)
        {
            // Build the tree of exception structures:
            for (int i = 0; i < body.ExceptionRegions.Length; i++)
            {
                ExceptionRegion eh = body.ExceptionRegions[i];
                if (!body.ExceptionRegions.Take(i).Any(oldEh => oldEh.TryOffset == eh.TryOffset && oldEh.TryLength == eh.TryLength))
                {
                    AddNestedStructure(new ILStructure(module, handle, genericContext, ILStructureType.Try, eh.TryOffset, eh.TryOffset + eh.TryLength, eh));
                }
                if (eh.Kind == ExceptionRegionKind.Filter)
                {
                    AddNestedStructure(new ILStructure(module, handle, genericContext, ILStructureType.Filter, eh.FilterOffset, eh.HandlerOffset, eh));
                }
                AddNestedStructure(new ILStructure(module, handle, genericContext, ILStructureType.Handler, eh.HandlerOffset, eh.HandlerOffset + eh.HandlerLength, eh));
            }
            // Very simple loop detection: look for backward branches
            (var allBranches, var isAfterUnconditionalBranch) = FindAllBranches(body.GetILReader());
            // We go through the branches in reverse so that we find the biggest possible loop boundary first (think loops with "continue;")
            for (int i = allBranches.Count - 1; i >= 0; i--)
            {
                int loopEnd   = allBranches[i].Source.End;
                int loopStart = allBranches[i].Target;
                if (loopStart < loopEnd)
                {
                    // We found a backward branch. This is a potential loop.
                    // Check that is has only one entry point:
                    int entryPoint = -1;

                    // entry point is first instruction in loop if prev inst isn't an unconditional branch
                    if (loopStart > 0 && !isAfterUnconditionalBranch[loopStart])
                    {
                        entryPoint = allBranches[i].Target;
                    }

                    bool multipleEntryPoints = false;
                    foreach (var branch in allBranches)
                    {
                        if (branch.Source.Start < loopStart || branch.Source.Start >= loopEnd)
                        {
                            if (loopStart <= branch.Target && branch.Target < loopEnd)
                            {
                                // jump from outside the loop into the loop
                                if (entryPoint < 0)
                                {
                                    entryPoint = branch.Target;
                                }
                                else if (branch.Target != entryPoint)
                                {
                                    multipleEntryPoints = true;
                                }
                            }
                        }
                    }
                    if (!multipleEntryPoints)
                    {
                        AddNestedStructure(new ILStructure(module, handle, genericContext, ILStructureType.Loop, loopStart, loopEnd, entryPoint));
                    }
                }
            }
            SortChildren();
        }