Exemple #1
0
        Instruction ReplaceInstruction(ILProcessor ilProcessor, Instruction instruction, MethodReference calledMethod)
        {
            var nextInstruction = instruction.Next;

            var    opcodeField = OpcodesFields.FirstOrDefault(info => info.Name == calledMethod.Name);
            OpCode opcode;

            if (opcodeField == null)
            {
                // Special case stelem because we don't want to call it Stelem_Any
                if (calledMethod.Name == "Stelem")
                {
                    opcode = OpCodes.Stelem_Any;
                }
                // Special case ldelem because we don't want to call it Ldelem_Any
                else if (calledMethod.Name == "Ldelem")
                {
                    opcode = OpCodes.Ldelem_Any;
                }
                else
                {
                    throw new Exception(string.Format("Unknown opcode {0}, ignoring", calledMethod.Name));
                }
            }
            else
            {
                opcode = (OpCode)opcodeField.GetValue(null);
            }

            if (calledMethod is GenericInstanceMethod)
            {
                var generic_method = calledMethod as GenericInstanceMethod;
                var typetok        = generic_method.GenericArguments[0];
                StackAnalyser.ReplaceInstruction(ilProcessor, instruction, Instruction.Create(opcode, typetok));
            }
            else
            {
                if (calledMethod.Parameters.Count == 0)
                {
                    StackAnalyser.ReplaceInstruction(ilProcessor, instruction, Instruction.Create(opcode));
                }
                if (calledMethod.Parameters.Count == 1)
                {
                    var stack = Analysis[instruction.Previous];

                    var operandEntry = stack.Head;
                    StackAnalyser.RemoveInstructionChain(ilProcessor.Body.Method, operandEntry.Item1, Analysis);

                    if (!operandEntry.Item2.IsConstant)
                    {
                        Console.WriteLine("Inline ({0}) without constant argument, ignoring.", opcode);
                        StackAnalyser.RemoveInstructionChain(ilProcessor.Body.Method, instruction, Analysis);
                        return(nextInstruction);
                    }

                    var operand = operandEntry.Item2.Value;

                    if (opcode.OperandType == OperandType.InlineVar)
                    {
                        var variable = ilProcessor.Body.Variables[(int)operand];
                        StackAnalyser.ReplaceInstruction(ilProcessor, instruction, Instruction.Create(opcode, variable));
                    }
                    else if (opcode.OperandType == OperandType.InlineArg)
                    {
                        var variable = ilProcessor.Body.Method.Parameters[(int)operand];
                        StackAnalyser.ReplaceInstruction(ilProcessor, instruction, Instruction.Create(opcode, variable));
                    }
                    else if (opcode.OperandType == OperandType.InlineBrTarget)
                    {
                        var jump = Labels.GetJumpLocation(ilProcessor.Body, (string)operand);
                        StackAnalyser.ReplaceInstruction(ilProcessor, instruction, Instruction.Create(opcode, jump));
                    }
                    else if (opcode.OperandType == OperandType.ShortInlineI)
                    {
                        var integer = (byte)operand;
                        StackAnalyser.ReplaceInstruction(ilProcessor, instruction, Instruction.Create(opcode, integer));
                    }
                    else if (opcode.OperandType == OperandType.InlineI)
                    {
                        var integer = (int)operand;
                        StackAnalyser.ReplaceInstruction(ilProcessor, instruction, Instruction.Create(opcode, integer));
                    }
                    else if (opcode.OperandType == OperandType.InlineI8)
                    {
                        var integer = (long)operand;
                        StackAnalyser.ReplaceInstruction(ilProcessor, instruction, Instruction.Create(opcode, integer));
                    }
                    else if (opcode.OperandType == OperandType.ShortInlineR)
                    {
                        var real = (float)operand;
                        StackAnalyser.ReplaceInstruction(ilProcessor, instruction, Instruction.Create(opcode, real));
                    }
                    else if (opcode.OperandType == OperandType.InlineR)
                    {
                        var real = (double)operand;
                        StackAnalyser.ReplaceInstruction(ilProcessor, instruction, Instruction.Create(opcode, real));
                    }
                    else if (opcode.OperandType == OperandType.InlineSwitch)
                    {
                        var target_string = (string)operand;
                        var targets       = target_string.Split(';').Select(label => Labels.GetJumpLocation(ilProcessor.Body, label)).ToArray();

                        StackAnalyser.ReplaceInstruction(ilProcessor, instruction, Instruction.Create(opcode, targets));
                    }
                    else if (opcode.OperandType == OperandType.InlineField)
                    {
                        var module   = ilProcessor.Body.Method.Module;
                        var field    = (string)operand;
                        var fieldref = Reference.ParseFieldReference(
                            Reference.Scope.NewMethodScope(ilProcessor.Body.Method), field);
                        StackAnalyser.ReplaceInstruction(ilProcessor, instruction, Instruction.Create(opcode, fieldref));
                    }
                    else if (opcode.OperandType == OperandType.InlineMethod)
                    {
                        var module    = ilProcessor.Body.Method.Module;
                        var method    = (string)operand;
                        var methodref = Reference.ParseMethodReference(
                            Reference.Scope.NewMethodScope(ilProcessor.Body.Method), method);

                        StackAnalyser.ReplaceInstruction(ilProcessor, instruction, Instruction.Create(opcode, methodref));
                    }
                    else if (opcode.OperandType == OperandType.InlineType)
                    {
                        var module  = ilProcessor.Body.Method.Module;
                        var type    = (string)operand;
                        var typeref = Reference.ParseTypeReference(
                            Reference.Scope.NewMethodScope(ilProcessor.Body.Method), type);

                        StackAnalyser.ReplaceInstruction(ilProcessor, instruction, Instruction.Create(opcode, typeref));
                    }
                    else
                    {
                        throw new ArgumentException(string.Format("Inline opcode ({0}) without argument, ignoring.", opcode));
                    }
                }
                else
                {
                    if (opcode.OperandType == OperandType.InlineSig)
                    {
                        return(ReplaceCalli(ilProcessor, instruction, calledMethod));
                    }
                }
            }

            return(nextInstruction);
        }
Exemple #2
0
        private Instruction ReplaceLoadAddress(ILProcessor ilProcessor, Instruction instruction, MethodReference calledMethod)
        {
            var generic_method = calledMethod as GenericInstanceMethod;
            var typetok        = generic_method.GenericArguments[0];

            var stack = Analysis[instruction.Previous];

            var operandEntry     = stack.Head;
            var addr_instruction = operandEntry.Item1;
            var next             = instruction.Next;

            if (addr_instruction.OpCode == OpCodes.Ldloc)
            {
                var local = (VariableDefinition)addr_instruction.Operand;
                StackAnalyser.ReplaceInstruction(ilProcessor, addr_instruction, Instruction.Create(OpCodes.Ldloca, local));
            }
            else if (addr_instruction.OpCode == OpCodes.Ldarg)
            {
                var argument = (ParameterDefinition)addr_instruction.Operand;
                StackAnalyser.ReplaceInstruction(ilProcessor, addr_instruction, Instruction.Create(OpCodes.Ldarga, argument));
            }
            else if (addr_instruction.OpCode == OpCodes.Ldsfld)
            {
                var field = (FieldReference)addr_instruction.Operand;
                StackAnalyser.ReplaceInstruction(ilProcessor, addr_instruction, Instruction.Create(OpCodes.Ldsflda, field));
            }
            else if (addr_instruction.OpCode == OpCodes.Ldfld)
            {
                var field = (FieldReference)addr_instruction.Operand;
                StackAnalyser.ReplaceInstruction(ilProcessor, addr_instruction, Instruction.Create(OpCodes.Ldflda, field));
            }
            else if (
                addr_instruction.OpCode == OpCodes.Ldelem_Any)
            {
                var type = (TypeReference)addr_instruction.Operand;
                StackAnalyser.ReplaceInstruction(ilProcessor, addr_instruction, Instruction.Create(OpCodes.Ldelema, type));
            }
            else if (
                addr_instruction.OpCode == OpCodes.Ldelem_I ||
                addr_instruction.OpCode == OpCodes.Ldelem_I1 ||
                addr_instruction.OpCode == OpCodes.Ldelem_I2 ||
                addr_instruction.OpCode == OpCodes.Ldelem_I4 ||
                addr_instruction.OpCode == OpCodes.Ldelem_I8 ||
                addr_instruction.OpCode == OpCodes.Ldelem_U1 ||
                addr_instruction.OpCode == OpCodes.Ldelem_U2 ||
                addr_instruction.OpCode == OpCodes.Ldelem_U4 ||
                addr_instruction.OpCode == OpCodes.Ldelem_R4 ||
                addr_instruction.OpCode == OpCodes.Ldelem_R8 ||
                addr_instruction.OpCode == OpCodes.Ldelem_Ref)
            {
                var module = ilProcessor.Body.Method.Module;

                TypeReference type;
                switch (addr_instruction.OpCode.Code)
                {
                case Code.Ldelem_I:
                    type = new TypeReference("System", "IntPtr", module, module);
                    break;

                case Code.Ldelem_I1:
                    type = new TypeReference("System", "SByte", module, module);
                    break;

                case Code.Ldelem_I2:
                    type = new TypeReference("System", "Int16", module, module);
                    break;

                case Code.Ldelem_I4:
                    type = new TypeReference("System", "Int32", module, module);
                    break;

                case Code.Ldelem_I8:
                    type = new TypeReference("System", "Int64", module, module);
                    break;

                case Code.Ldelem_U1:
                    type = new TypeReference("System", "Byte", module, module);
                    break;

                case Code.Ldelem_U2:
                    type = new TypeReference("System", "UInt16", module, module);
                    break;

                case Code.Ldelem_U4:
                    type = new TypeReference("System", "UInt32", module, module);
                    break;

                case Code.Ldelem_R4:
                    type = new TypeReference("System", "Single", module, module);
                    break;

                case Code.Ldelem_R8:
                    type = new TypeReference("System", "Double", module, module);
                    break;

                case Code.Ldelem_Ref:
                default:
                {
                    // array is the lower item in the stack
                    var array_instruction = Analysis[addr_instruction.Previous].Tail.Head.Item1;
                    // whatever load loaded this array it will have a type with it
                    type = array_instruction.Operand as TypeReference;
                }
                break;
                }

                StackAnalyser.ReplaceInstruction(ilProcessor, addr_instruction, Instruction.Create(OpCodes.Ldelema, type));
            }
            else
            {
                throw new Exception("ReplaceLoadAddress: How did we get here?!");
            }

            StackAnalyser.RemoveInstruction(ilProcessor, instruction);

            return(next);
        }