Ejemplo n.º 1
0
        private int ProcessMethod(MethodDef md)
        {
            List <MathInfo> Patched = new List <MathInfo>();

            for (int i = 0; i < md.Body.Instructions.Count; i++)
            {
                Instruction inst = md.Body.Instructions[i];

                if (inst.OpCode == OpCodes.Call && inst.Operand is MemberRef)
                {
                    MemberRef mRef = inst.Operand as MemberRef;

                    if (mRef.DeclaringType.FullName != "System.Math")
                    {
                        continue;
                    }

                    if (IgnoredMethods.Any(x => mRef.Name == x))
                    {
                        Logger.Log(this, string.Format("Skipping {0} since it is ignored", mRef.Name));
                        continue;
                    }
                    // Find insts to remove
                    // Find args
                    MathInfo mInf = new MathInfo();

                    mInf.Method       = mRef.Name;
                    mInf.CallingInst  = inst;
                    mInf.ParentMethod = md;

                    List <Instruction> paramVals = FindParamValues(i, md, mRef.MethodSig.Params.Count);
                    paramVals.Reverse();

                    if (paramVals.Count == 0)
                    {
                        // Do something
                        continue;
                    }
                    mInf.Param1 = (double)paramVals[0].Operand;
                    if (paramVals.Count > 1)
                    {
                        mInf.Param2 = (double)paramVals[1].Operand;
                    }

                    if (paramVals.Count < mRef.MethodSig.Params.Count)
                    {
                    }

                    if (paramVals.Contains(inst))
                    {
                        paramVals.Remove(inst);
                    }

                    mInf.Remove.AddRange(paramVals);

                    Logger.Log(this, string.Format("Solving {0}({1}{2})", mInf.Method, mInf.Param1, !double.IsNaN(mInf.Param2) ? ", " + mInf.Param2.ToString() : ""));
                    // I have to do this immediately after so I can solve for the next call if they are packed together.
                    if (Solve(mInf, md))
                    {
                        Logger.Log(this, string.Format("Solved {0}({1}{2})", mInf.Method, mInf.Param1, !double.IsNaN(mInf.Param2) ? ", " + mInf.Param2.ToString() : ""));
                        Patched.Add(mInf);
                    }
                    else
                    {
                        Logger.Log(this, string.Format("Failed to solve {0}({1}{2})", mInf.Method, mInf.Param1, !double.IsNaN(mInf.Param2) ? ", " + mInf.Param2.ToString() : ""));
                    }
                }
            }

            return(Patched.Count);
        }
Ejemplo n.º 2
0
        private bool Solve(MathInfo inf, MethodDef md)
        {
            if (double.IsNaN(inf.Param1) && double.IsNaN(inf.Param2))
            {
                return(false);
            }


            double mResult = double.NaN;
            bool   usedTwo = false;

            try
            {
                if (!double.IsNaN(inf.Param2) && !double.IsNaN(inf.Param1))
                {
                    if (inf.Method == "Pow")
                    {
                        mResult = Pow(inf.Param1, inf.Param2);
                    }
                    else
                    {
                        mResult = GetMathResult(inf.Param1, inf.Param2, inf.Method);
                    }
                    usedTwo = true;
                }
                else if (!double.IsNaN(inf.Param1) && double.IsNaN(inf.Param2))
                {
                    mResult = GetMathResult(inf.Param1, inf.Method);
                }
            }
            catch (Exception)
            {
            }

            if (double.IsNaN(mResult) || double.IsInfinity(mResult))
            {
                return(false);
            }

            int cIndex = md.Body.Instructions.IndexOf(inf.CallingInst);

            if (cIndex == -1)
            {
                return(false);
            }

            if (md.Body.Instructions[cIndex].OpCode != inf.CallingInst.OpCode)
            {
                Logger.Log(this, string.Format("Original Instruction was not {0} but {1}", inf.CallingInst.OpCode, md.Body.Instructions[cIndex].OpCode));
                return(false);
            }
            double rounded = Math.Round(mResult, DecimalPlaces);

            md.Body.Instructions[cIndex].OpCode  = GetNumberType(inf.Converter); //OpCodes.Ldc_R8;
            md.Body.Instructions[cIndex].Operand = Round ? rounded : mResult;

            md.Body.UpdateInstructionOffsets();

            foreach (Instruction rem in inf.Remove)
            {
                int index = md.Body.Instructions.IndexOf(rem);
                if (index == -1)
                {
                    continue;
                }
                md.Body.Instructions[index].OpCode  = OpCodes.Nop;
                md.Body.Instructions[index].Operand = null;
                md.Body.UpdateInstructionOffsets();
            }
            return(true);
        }