Beispiel #1
0
        static void RestoreConstrainedPrefix(MethodDef method)
        {
            if (method == null || method.Body == null)
            {
                return;
            }

            var instrs = method.Body.Instructions;

            for (int i = 0; i < instrs.Count; i++)
            {
                var instr = instrs[i];
                if (instr.OpCode.Code != Code.Callvirt)
                {
                    continue;
                }

                var calledMethod = instr.Operand as IMethod;
                if (calledMethod == null)
                {
                    continue;
                }
                var sig = calledMethod.MethodSig;
                if (sig == null || !sig.HasThis)
                {
                    continue;
                }
                var thisType = MethodStack.GetLoadedType(method, instrs, i, sig.Params.Count) as ByRefSig;
                if (thisType == null)
                {
                    continue;
                }
                if (HasPrefix(instrs, i, Code.Constrained))
                {
                    continue;
                }
                instrs.Insert(i, OpCodes.Constrained.ToInstruction(thisType.Next.ToTypeDefOrRef()));
                i++;
            }
        }
Beispiel #2
0
        public bool Restore(MethodDef method)
        {
            this.method = method;
            bool atLeastOneFailed = false;

            if (method == null || method.Body == null)
            {
                return(!atLeastOneFailed);
            }

            var instrs = method.Body.Instructions;

            for (int i = 0; i < instrs.Count; i++)
            {
                var instr = instrs[i];
                if (instr.Operand != null)
                {
                    continue;
                }

                TypeSig    operandType = null, operandTypeTmp;
                OpCode     newOpCode = null;
                SZArraySig arrayType;
                switch (instr.OpCode.Code)
                {
                case Code.Ldelem:
                    arrayType = MethodStack.GetLoadedType(method, instrs, i, 1) as SZArraySig;
                    if (arrayType == null)
                    {
                        break;
                    }
                    operandTypeTmp = arrayType.Next;
                    if (operandTypeTmp == null)
                    {
                        newOpCode = OpCodes.Ldelem_Ref;
                    }
                    else
                    {
                        switch (operandTypeTmp.ElementType)
                        {
                        case ElementType.Boolean: newOpCode = OpCodes.Ldelem_I1; break;

                        case ElementType.Char: newOpCode = OpCodes.Ldelem_U2; break;

                        case ElementType.I:  newOpCode = OpCodes.Ldelem_I; break;

                        case ElementType.I1: newOpCode = OpCodes.Ldelem_I1; break;

                        case ElementType.I2: newOpCode = OpCodes.Ldelem_I2; break;

                        case ElementType.I4: newOpCode = OpCodes.Ldelem_I4; break;

                        case ElementType.I8: newOpCode = OpCodes.Ldelem_I8; break;

                        case ElementType.U:  newOpCode = OpCodes.Ldelem_I; break;

                        case ElementType.U1: newOpCode = OpCodes.Ldelem_U1; break;

                        case ElementType.U2: newOpCode = OpCodes.Ldelem_U2; break;

                        case ElementType.U4: newOpCode = OpCodes.Ldelem_U4; break;

                        case ElementType.U8: newOpCode = OpCodes.Ldelem_I8; break;

                        case ElementType.R4: newOpCode = OpCodes.Ldelem_R4; break;

                        case ElementType.R8: newOpCode = OpCodes.Ldelem_R8; break;

                        default:             newOpCode = OpCodes.Ldelem_Ref; break;
                            //TODO: Ldelem
                        }
                    }
                    break;

                case Code.Stelem:
                    arrayType = MethodStack.GetLoadedType(method, instrs, i, 2) as SZArraySig;
                    if (arrayType == null)
                    {
                        break;
                    }
                    operandTypeTmp = arrayType.Next;
                    if (operandTypeTmp == null)
                    {
                        newOpCode = OpCodes.Stelem_Ref;
                    }
                    else
                    {
                        switch (operandTypeTmp.ElementType)
                        {
                        case ElementType.U:
                        case ElementType.I:  newOpCode = OpCodes.Stelem_I; break;

                        case ElementType.Boolean:
                        case ElementType.U1:
                        case ElementType.I1: newOpCode = OpCodes.Stelem_I1; break;

                        case ElementType.Char:
                        case ElementType.U2:
                        case ElementType.I2: newOpCode = OpCodes.Stelem_I2; break;

                        case ElementType.U4:
                        case ElementType.I4: newOpCode = OpCodes.Stelem_I4; break;

                        case ElementType.U8:
                        case ElementType.I8: newOpCode = OpCodes.Stelem_I8; break;

                        case ElementType.R4: newOpCode = OpCodes.Stelem_R4; break;

                        case ElementType.R8: newOpCode = OpCodes.Stelem_R8; break;

                        default: newOpCode = OpCodes.Stelem_Ref; break;
                            //TODO: Stelem
                        }
                    }
                    break;

                case Code.Ldelema:
                    arrayType = MethodStack.GetLoadedType(method, instrs, i, 1) as SZArraySig;
                    if (arrayType == null)
                    {
                        break;
                    }
                    operandType = arrayType.Next;
                    break;

                case Code.Ldobj:
                    operandType = GetPtrElementType(MethodStack.GetLoadedType(method, instrs, i, 0));
                    break;

                case Code.Stobj:
                    operandType = MethodStack.GetLoadedType(method, instrs, i, 0);
                    if (!IsValidType(operandType))
                    {
                        operandType = GetPtrElementType(MethodStack.GetLoadedType(method, instrs, i, 1));
                    }
                    break;

                default:
                    continue;
                }
                if (newOpCode == null && !IsValidType(operandType))
                {
                    atLeastOneFailed = true;
                    continue;
                }

                instr.Operand = operandType.ToTypeDefOrRef();
                if (newOpCode != null)
                {
                    instr.OpCode = newOpCode;
                }
            }

            return(!atLeastOneFailed);
        }