Esempio n. 1
0
        private bool ProcessOpCall_retval2(MethodDefinition currentMethod, Instruction callInstruction, MethodReference callMethodRef, string methodOpName)
        {
            var ILprocessorEx = new ILProcessorEx(currentMethod);

            if (Match_Stloc(callInstruction.Next))
            {
                Instruction StlocInstruction = callInstruction.Next;
                int         n;
                Instruction newLdlocaInstruction = Stloc2Ldloca(ILprocessorEx, StlocInstruction, out n);

                Instruction op_outInstruction = GetMethodRefOp2(ILprocessorEx, callMethodRef, methodOpName);
                if (op_outInstruction == null)
                {
                    return(false);
                }

                Console.WriteLine(@"Patching " + callMethodRef.FullName + @" (0x" + callInstruction.Offset.ToString("X") + ")");
                Console.WriteLine(@" ...into " + ((MethodReference)op_outInstruction.Operand).FullName);

                ILprocessorEx.Remove(StlocInstruction);
                ILprocessorEx.InsertBefore(callInstruction, newLdlocaInstruction);
                // replace 'valuetype Op(...)' with 'void Op(..., out valuetype)'
                ILprocessorEx.Replace(callInstruction, op_outInstruction);

                return(true);
            }

            return(false);
        }
Esempio n. 2
0
        private static Instruction GetMethodRefOp2(ILProcessorEx ILprocessorEx, MethodReference callMethodRef, string methodOpName)
        {
            MethodReference MethodDefOp = null;
            var             typeDef     = callMethodRef.DeclaringType.Resolve();

            foreach (var method in typeDef.Methods)
            {
                if (method.HasThis)
                {
                    continue;
                }
                if (method.Name != methodOpName)
                {
                    continue;
                }
                if (method.ReturnType.FullName != "System.Void") //
                {
                    continue;
                }
                //if (callMethodRef.ReturnType.FullName) //
                //    continue;
                if ((method.Parameters.Count - 1) != callMethodRef.Parameters.Count)
                {
                    continue;
                }

                var match = true;
                for (int i = 0; i < callMethodRef.Parameters.Count; i++)
                {
                    if (method.Parameters[i].ParameterType.IsByReference != callMethodRef.Parameters[i].ParameterType.IsByReference)
                    {
                        match = false;
                        continue;
                    }
                }

                if (match != true)
                {
                    continue;
                }

                //if (method.Parameters[0].ParameterType.IsByReference == false &&
                //    method.Parameters[1].ParameterType.IsByReference == true)
                MethodDefOp = method;
                break;
            }

            if (MethodDefOp == null)
            {
                //method not found
                return(null);
            }

            var methodRefOp       = callMethodRef.DeclaringType.Module.ImportReference(MethodDefOp);
            var op_outInstruction = ILprocessorEx.Create(OpCodes.Call, methodRefOp);

            return(op_outInstruction);
        }
Esempio n. 3
0
        private static Instruction Stloc2Ldloca(ILProcessorEx ILprocessorEx, Instruction StlocInstruction, out int n)
        {
            if (StlocInstruction.OpCode.Code == Code.Stloc)
            {
                var varDef = StlocInstruction.Operand as VariableDefinition;
                n = varDef.Index;
                return(ILprocessorEx.Create(OpCodes.Ldloca, ILprocessorEx.Method.Body.Variables[n]));
            }
            else if (StlocInstruction.OpCode.Code == Code.Stloc_S)
            {
                var varDef = StlocInstruction.Operand as VariableDefinition;
                n = varDef.Index;
            }
            else if (StlocInstruction.OpCode.Code == Code.Stloc_0)
            {
                n = 0;
            }
            else if (StlocInstruction.OpCode.Code == Code.Stloc_1)
            {
                n = 1;
            }
            else if (StlocInstruction.OpCode.Code == Code.Stloc_2)
            {
                n = 2;
            }
            else if (StlocInstruction.OpCode.Code == Code.Stloc_3)
            {
                n = 3;
            }
            else
            {
                throw new InvalidOperationException();
            }

            return(ILprocessorEx.Create(OpCodes.Ldloca_S, ILprocessorEx.Method.Body.Variables[n]));
        }
Esempio n. 4
0
        private static Instruction Ldarg2Ldarga(ILProcessorEx ILprocessorEx, Instruction LdargInstruction, out int n)
        {
            if (LdargInstruction.OpCode.Code == Code.Ldarg)
            {
                var varDef = LdargInstruction.Operand as VariableDefinition;
                n = varDef.Index;
                return(ILprocessorEx.Create(OpCodes.Ldarga, ILprocessorEx.Method.Parameters[n]));
            }
            else if (LdargInstruction.OpCode.Code == Code.Ldarg_S)
            {
                var varDef = LdargInstruction.Operand as VariableDefinition;
                n = varDef.Index;
            }
            else if (LdargInstruction.OpCode.Code == Code.Ldarg_0)
            {
                n = 0;
            }
            else if (LdargInstruction.OpCode.Code == Code.Ldarg_1)
            {
                n = 1;
            }
            else if (LdargInstruction.OpCode.Code == Code.Ldarg_2)
            {
                n = 2;
            }
            else if (LdargInstruction.OpCode.Code == Code.Ldarg_3)
            {
                n = 3;
            }
            else
            {
                throw new InvalidOperationException();
            }

            return(ILprocessorEx.Create(OpCodes.Ldarga_S, ILprocessorEx.Method.Parameters[n]));
        }
Esempio n. 5
0
        private bool ProcessOpCall_retout(MethodDefinition currentMethod, Instruction callInstruction, MethodReference callMethodRef, string methodOpName)
        {
            var ILprocessorEx = new ILProcessorEx(currentMethod);

            return(false);
        }
Esempio n. 6
0
        private bool ProcessOpCall_retval(MethodDefinition currentMethod, Instruction callInstruction, MethodReference callMethodRef, string methodOpName)
        {
            var ILprocessorEx = new ILProcessorEx(currentMethod);

            int currentParamIdx = callMethodRef.Parameters.Count - 1;

            // for now we support only operators (with two arguments). currentParamIdx has to be #1.
            if (currentParamIdx != 1)
            {
                throw new InvalidOperationException();
            }
            var currentParam        = callMethodRef.Parameters[currentParamIdx];
            var isCurrentParamByRef = currentParam.ParameterType.IsByReference;

            for (var instruction = callInstruction.Previous; instruction != null; instruction = instruction.Previous)
            {
                //TODO: check if there is a branch target between instruction and callInstruction and quit
                //    break;

                if (isCurrentParamByRef == false)
                {
                    if (Match_Ldloc(instruction))
                    {
                        Instruction LdlocInstruction = instruction;
                        int         n;
                        Instruction newLdlocaInstruction = Ldloc2Ldloca(ILprocessorEx, LdlocInstruction, out n);

                        Instruction op_refInstruction = GetMethodRefOp(ILprocessorEx, callMethodRef, methodOpName, currentParamIdx);
                        if (op_refInstruction == null)
                        {
                            return(false);
                        }

                        Console.WriteLine(@"Patching " + callMethodRef.FullName + @" (0x" + callInstruction.Offset.ToString("X") + ")");
                        Console.WriteLine(@" ...into " + ((MethodReference)op_refInstruction.Operand).FullName);

                        // replace 'Ldloc' with 'Ldloca'
                        ILprocessorEx.Replace(LdlocInstruction, newLdlocaInstruction);
                        // replace 'vector2 Add(vector2,vector2)' with 'vector2 Add(vector2,vector2)'
                        ILprocessorEx.Replace(callInstruction, op_refInstruction);

                        return(true);
                    }
                    else if (Match_Ldarg(instruction))
                    {
                        Instruction LdargInstruction = instruction;
                        int         n;
                        Instruction newLdargaInstruction = Ldarg2Ldarga(ILprocessorEx, LdargInstruction, out n);

                        // check validity of parameter n
                        var targParam = currentMethod.Parameters[n];
                        if (targParam.ParameterType.IsByReference == true)
                        {
                            throw new InvalidOperationException();
                        }

                        Instruction op_refInstruction = GetMethodRefOp(ILprocessorEx, callMethodRef, methodOpName, currentParamIdx);
                        if (op_refInstruction == null)
                        {
                            return(false);
                        }

                        Console.WriteLine(@"Patching " + callMethodRef.FullName + @" (0x" + callInstruction.Offset.ToString("X") + ")");
                        Console.WriteLine(@" ...into " + ((MethodReference)op_refInstruction.Operand).FullName);

                        // replace 'Ldarg' with 'Ldarga'
                        ILprocessorEx.Replace(LdargInstruction, newLdargaInstruction);
                        // replace 'vector2 Add(vector2,vector2)' with 'vector2 Add(vector2, ref vector2)'
                        ILprocessorEx.Replace(callInstruction, op_refInstruction);

                        return(true);
                    }
                    else if (Match_Ldobj(instruction))
                    {
                        Instruction LdobjInstruction = instruction;

                        var ldtype = LdobjInstruction.Operand;
                        var type   = callMethodRef.Parameters[1];

                        if (Match_Ldarg(LdobjInstruction.Previous))
                        {
                            Instruction LdargInstruction = LdobjInstruction.Previous;

                            int         n;
                            Instruction newLdargaInstruction = Ldarg2Ldarga(ILprocessorEx, LdargInstruction, out n);

                            // check validity of parameter n
                            var targParam = currentMethod.Parameters[n];
                            if (targParam.ParameterType.IsByReference == false)
                            {
                                throw new InvalidOperationException();
                            }
                            Instruction op_refInstruction = GetMethodRefOp(ILprocessorEx, callMethodRef, methodOpName, currentParamIdx);
                            if (op_refInstruction == null)
                            {
                                return(false);
                            }

                            var callOffset = callInstruction.Offset;
                            Console.WriteLine(@"Patching " + callMethodRef.FullName + @" (0x" + callInstruction.Offset.ToString("X") + ")");
                            Console.WriteLine(@" ...into " + ((MethodReference)op_refInstruction.Operand).FullName);

                            ILprocessorEx.Remove(LdobjInstruction);
                            // replace 'vector2 Add(vector2,vector2)' with 'vector2 Add(vector2, ref vector2)'
                            ILprocessorEx.Replace(callInstruction, op_refInstruction);

                            return(true);
                        }
                    }
                    return(false);
                }
                else // (isCurrentParamByRef == true)
                {
                    if (Match_Ldloca(instruction))
                    {
                        Instruction LdlocaInstruction = instruction;

                        // argument sucesfully matched. Move to next argument.
                        if (currentParamIdx == 0)
                        {
                            // no more arguments to match.
                            return(false);
                        }
                        else
                        {
                            // Move to next argument.
                            currentParamIdx--;
                            currentParam        = callMethodRef.Parameters[currentParamIdx];
                            isCurrentParamByRef = currentParam.ParameterType.IsByReference;
                            continue;
                        }
                    }
                    return(false);
                }


                if (Match_Nop(instruction))
                {
                    continue;
                }
                if (Match_Break(instruction))
                {
                    continue;
                }
                // Unkwown instruction. quit
                break;
            }

            return(false);
        }