Example #1
0
 public bool Initialize(ClarifierContext ctx)
 {
     injectHelper = new ClarifierInjectHelper(ctx);
     staticProtectionsManager.AddPatternMatchingMethod("Confuser.Runtime.Constant", "Get");
     staticProtectionsManager.AddPatternMatchingMethod("Confuser.Runtime.Constant", "Initialize");
     return(staticProtectionsManager.LoadTypes());
 }
Example #2
0
        public bool PerformRemoval(ClarifierContext ctx)
        {
            ClarifierInjectHelper inject = new ClarifierInjectHelper(ctx);
            object instantiatedObject    = inject.CloneAndInstantiateType(ctx.CurrentModule.GlobalType);
            Type   dummyType             = instantiatedObject.GetType();

            Dictionary <string, MethodInfo> mapNewMethodsToName = new Dictionary <string, MethodInfo>();
            List <MethodDef> onlyMethodsToSubstitute            = staticProtectionsManager.DestinationMap.Where(x => x.name == "Get").First().matchingMethods;

            foreach (var v in staticProtectionsManager.DestinationMap)
            {
                foreach (var vv in v.matchingMethods)
                {
                    mapNewMethodsToName[vv.Name] = dummyType.GetMethod(vv.Name);
                }
            }

            foreach (var currentMethod in ctx.CurrentModule.GetMethods())
            {
                if (onlyMethodsToSubstitute.Exists(x => x == currentMethod))
                {
                    continue;
                }

                if (!currentMethod.HasBody)
                {
                    continue;
                }

                // Look for calls to blacklisted methods
                for (var i = 0; i < currentMethod.Body.Instructions.Count; ++i)
                {
                    Instruction currentInstruction = currentMethod.Body.Instructions[i];

                    if (currentInstruction.OpCode != OpCodes.Call)
                    {
                        continue;
                    }

                    IMethod    targetMethod = (IMethod)currentInstruction.Operand;
                    MethodInfo methodToInvoke;

                    if (!onlyMethodsToSubstitute.Exists(x => x.Name == targetMethod.Name))
                    {
                        continue;
                    }

                    if (mapNewMethodsToName.TryGetValue(targetMethod.Name, out methodToInvoke))
                    {
                        // Here we are sure we are in presence of a call to a blacklisted methods;
                        // Kill ye olde damn bastard!
                        int      inputParameters = methodToInvoke.GetParameters().Count();
                        object[] parameters      = new object[inputParameters];

                        // Close the generic type before invoking
                        if (methodToInvoke.IsGenericMethod)
                        {
                            MethodSpec genericMethod = (MethodSpec)targetMethod;
                            Type[]     genericTypes  = genericMethod.GenericInstMethodSig.GenericArguments.Select(x => Type.GetType(x.ReflectionFullName)).ToArray();
                            methodToInvoke = methodToInvoke.MakeGenericMethod(genericTypes);
                        }

                        // Iterate backward in order to retrieve input parameters and removing instructions.
                        int j = i;
                        for (; j > i - inputParameters; j--)
                        {
                            Type   targetType = methodToInvoke.GetParameters()[parameters.Length - (i - j) - 1].ParameterType;
                            object operand    = currentMethod.Body.Instructions[j - 1].Operand;

                            if (targetType.IsValueType)
                            {
                                try
                                {
                                    // Most common situation here is that the operand is an uint.
                                    // dnlib fail to assign the right type (int instead of uint)
                                    // so we force the cast...
                                    parameters[parameters.Length - (i - j) - 1] = (uint)(int)operand;
                                }
                                catch
                                {
                                    // ...If the cast fail we try a conversion with value semantic. If even
                                    // this cast fail, we lift the white flag.
                                    parameters[parameters.Length - (i - j) - 1] = Convert.ChangeType(operand, targetType);
                                }
                            }
                            else
                            {
                                parameters[parameters.Length - (i - j) - 1] = operand;
                            }

                            currentMethod.Body.Instructions.RemoveAt(j - 1);
                        }
                        i = j;

                        object returnedObject = methodToInvoke.Invoke(null, parameters);
                        Type   returnedType   = returnedObject.GetType();

                        if (returnedType == typeof(string))
                        {
                            currentMethod.Body.Instructions[i] = new Instruction(OpCodes.Ldstr, returnedObject);
                        }
                        else if (returnedType.IsArray)
                        {
                            ITypeDefOrRef arrayType   = null;
                            int           elementSize = 0;
                            if (returnedType.Name == typeof(int[]).Name || returnedType.Name == typeof(float[]).Name)
                            {
                                elementSize = 4;
                                if (returnedType.Name == typeof(int[]).Name)
                                {
                                    arrayType = ctx.CurrentModule.CorLibTypes.Int32.TypeDefOrRef;
                                }
                                else
                                {
                                    arrayType = ctx.CurrentModule.CorLibTypes.Double.TypeDefOrRef;
                                }
                            }
                            else if (returnedType.Name == typeof(long[]).Name || returnedType.Name == typeof(double[]).Name)
                            {
                                elementSize = 8;

                                if (returnedType.Name == typeof(long[]).Name)
                                {
                                    arrayType = ctx.CurrentModule.CorLibTypes.Int64.TypeDefOrRef;
                                }
                                else
                                {
                                    arrayType = ctx.CurrentModule.CorLibTypes.Double.TypeDefOrRef;
                                }
                            }
                            else if (returnedType.Name == typeof(char[]).Name)
                            {
                                elementSize = 2;
                                arrayType   = ctx.CurrentModule.CorLibTypes.Char.TypeDefOrRef;
                            }
                            else
                            {
                                Debugger.Break();
                            }

                            injectHelper.InjectArray((Array)returnedObject, currentMethod, arrayType, elementSize, i);
                        }
                        else
                        {
                            Debugger.Break();
                        }
                    }
                }
            }

            return(true);
        }