Ejemplo n.º 1
0
        /// <summary>
        /// Runs the specified cloaking task.
        /// </summary>
        /// <param name="context">The running context of this cloak job.</param>
        public void RunTask(ICloakContext context)
        {
            //Optimization on it's own will screw up our original changes so let's fix it up first
            context.ReloadAssemblyDefinitions();

            //Now get the dictionary and optimize
            var dictionary = context.GetAssemblyDefinitions();
            foreach (AssemblyDefinition assembly in dictionary.Values)
            {
                //We'll search methods only at this point
                foreach (ModuleDefinition moduleDefinition in assembly.Modules)
                {
                    //Go through each type
                    foreach (TypeDefinition typeDefinition in moduleDefinition.GetAllTypes())
                    {
                        //Go through each method
                        foreach (MethodDefinition methodDefinition in typeDefinition.Methods)
                        {
                            if (methodDefinition.HasBody)
                            {
                                OutputHelper.WriteMethod(typeDefinition, methodDefinition);
                                methodDefinition.Body.OptimizeMacros();
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Runs the specified cloaking task.
        /// </summary>
        /// <param name="context">The running context of this cloak job.</param>
        public void RunTask(ICloakContext context)
        {
            Dictionary <string, AssemblyDefinition> assemblyCache = context.GetAssemblyDefinitions();

            foreach (string assembly in assemblyCache.Keys)
            {
                AssemblyDefinition def = assemblyCache[assembly];
                Type            si     = typeof(SuppressIldasmAttribute);
                CustomAttribute found  = null;
                foreach (CustomAttribute attr in def.CustomAttributes)
                {
                    if (attr.Constructor.DeclaringType.FullName == si.FullName)
                    {
                        found = attr;
                        break;
                    }
                }

                //Only add if it's not there already
                if (found == null)
                {
                    //Add one
                    MethodReference constructor = def.MainModule.Import(typeof(SuppressIldasmAttribute).GetConstructor(Type.EmptyTypes));
                    CustomAttribute attr        = new CustomAttribute(constructor);
                    def.CustomAttributes.Add(attr);
                }
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Runs the specified cloaking task.
        /// </summary>
        /// <param name="context">The running context of this cloak job.</param>
        public void RunTask(ICloakContext context)
        {
            //Optimization on it's own will screw up our original changes so let's fix it up first
            context.ReloadAssemblyDefinitions();

            //Now get the dictionary and optimize
            var dictionary = context.GetAssemblyDefinitions();

            foreach (AssemblyDefinition assembly in dictionary.Values)
            {
                //We'll search methods only at this point
                foreach (ModuleDefinition moduleDefinition in assembly.Modules)
                {
                    //Go through each type
                    foreach (TypeDefinition typeDefinition in moduleDefinition.GetAllTypes())
                    {
                        //Go through each method
                        foreach (MethodDefinition methodDefinition in typeDefinition.Methods)
                        {
                            if (methodDefinition.HasBody)
                            {
                                OutputHelper.WriteMethod(typeDefinition, methodDefinition);
                                methodDefinition.Body.OptimizeMacros();
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Runs the specified cloaking task.
        /// </summary>
        /// <param name="context">The running context of this cloak job.</param>
        public void RunTask(ICloakContext context)
        {
            Dictionary<string, AssemblyDefinition> assemblyCache = context.GetAssemblyDefinitions();
            foreach (string assembly in assemblyCache.Keys)
            {
                AssemblyDefinition def = assemblyCache[assembly];
                Type si = typeof (SuppressIldasmAttribute);
                CustomAttribute found = null;
                foreach (CustomAttribute attr in def.CustomAttributes)
                {
                    if (attr.Constructor.DeclaringType.FullName == si.FullName)
                    {
                        found = attr;
                        break;
                    }
                }

                //Only add if it's not there already
                if (found == null)
                {
                    //Add one
                    MethodReference constructor = def.MainModule.Import(typeof (SuppressIldasmAttribute).GetConstructor(Type.EmptyTypes));
                    CustomAttribute attr = new CustomAttribute(constructor);
                    def.CustomAttributes.Add(attr);
                }
            }

        }
Ejemplo n.º 5
0
 /// <summary>
 /// Runs the specified cloaking task.
 /// </summary>
 public void RunTask(ICloakContext context)
 {
     //Loop through each assembly and obfuscate it
     foreach (AssemblyDefinition definition in context.GetAssemblyDefinitions().Values)
     {
         Obfuscate(context, definition);
     }
 }
Ejemplo n.º 6
0
 /// <summary>
 /// Runs the specified cloaking task.
 /// </summary>
 public void RunTask(ICloakContext context)
 {
     //Loop through each assembly and obfuscate it
     foreach (AssemblyDefinition definition in context.GetAssemblyDefinitions().Values)
     {
         Obfuscate(context, definition);
     }
 }
Ejemplo n.º 7
0
 /// <summary>
 /// Runs the specified cloaking task.
 /// </summary>
 /// <param name="context">The running context of this cloak job.</param>
 public void RunTask(ICloakContext context)
 {
     foreach (AssemblyDefinition assembly in context.GetAssemblyDefinitions().Values)
     {
         Simplify(assembly);
     }
     context.ReloadAssemblyDefinitions();
 }
Ejemplo n.º 8
0
 /// <summary>
 /// Runs the specified cloaking task.
 /// </summary>
 /// <param name="context">The running context of this cloak job.</param>
 public void RunTask(ICloakContext context)
 {
     foreach (AssemblyDefinition assembly in context.GetAssemblyDefinitions().Values)
     {
         Simplify(assembly);
     }
     context.ReloadAssemblyDefinitions();
 }
Ejemplo n.º 9
0
        /// <summary>
        /// Configures the specified context.
        /// </summary>
        /// <param name="context">The context.</param>
        public void Configure(ICloakContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            //Simplify the task
            RegisterTask <SimplifyTask>();

            //Encrypt strings before anything else
            if (context.Settings.EncryptStrings)
            {
                RegisterTask(new StringEncryptionTask(StringEncryptionMethod.Xor));
            }

            //Build up a mapping of the assembly and obfuscate
            if (!context.Settings.NoRename)
            {
                RegisterTask <MappingTask>();
                RegisterTask <ObfuscationTask>();
            }

            //Supress ILDASM decompilation
            if (context.Settings.SupressIldasm)
            {
                RegisterTask <SupressIldasmTask>();
            }

            //Try to confuse reflection
            if (context.Settings.ConfuseDecompilationMethod != ConfusionMethod.None)
            {
                RegisterTask(new ConfuseDecompilationTask(ConfusionMethod.InvalidIl));
            }

            //Optimize the assembly (turn into short codes where poss)
            if (context.Settings.ConfuseDecompilationMethod == ConfusionMethod.None) //HACK: The new Mono.Cecil doesn't like bad IL codes
            {
                RegisterTask <OptimizeTask>();
            }

            //TODO: Register methods here
            if (context.Settings.CombineLocals)
            {
                RegisterTask <CombineLocals>();
            }

            //Always last - output the assembly in the relevant format
            if (String.IsNullOrEmpty(context.Settings.TamperProofAssemblyName))
            {
                RegisterTask <OutputAssembliesTask>(); //Default
            }
            else
            {
                RegisterTask <TamperProofTask>(); //Tamper proofing combines all assemblies into one
            }
        }
Ejemplo n.º 10
0
 /// <summary>
 /// Runs the specified cloaking task.
 /// </summary>
 /// <param name="context">The running context of this cloak job.</param>
 public void RunTask(ICloakContext context)
 {
     //Go through each assembly and encrypt the strings 
     //for each assembly inject a decryption routine - we'll let the obfuscator hide it properly
     //Loop through each assembly and obfuscate it
     foreach (AssemblyDefinition definition in context.GetAssemblyDefinitions().Values)
     {
         EncryptStringsInAssembly(definition);
     }
 }
Ejemplo n.º 11
0
 public void RunTask(ICloakContext context)
 {
     //Go through each assembly
     //for each assembly inject a decryption routine - we'll let the obfuscator hide it properly
     //Loop through each assembly and obfuscate it
     foreach (AssemblyDefinition definition in context.GetAssemblyDefinitions().Values)
     {
         CombineLocalsInAssembly(definition);
     }
 }
Ejemplo n.º 12
0
        /// <summary>
        /// Updates the member type references.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="memberReference">The member reference.</param>
        private static void UpdateMemberTypeReferences(ICloakContext context, MemberReference memberReference)
        {
            //Get the type reference for this
            TypeReference methodType = memberReference.DeclaringType;

            //Get the assembly for this
            if (methodType.Scope is AssemblyNameReference)
            {
                string assemblyName = ((AssemblyNameReference)methodType.Scope).FullName;
                //Check if this needs to be updated
                if (context.MappingGraph.IsAssemblyMappingDefined(assemblyName))
                {
                    AssemblyMapping assemblyMapping = context.MappingGraph.GetAssemblyMapping(assemblyName);
                    TypeMapping     t = assemblyMapping.GetTypeMapping(methodType);
                    if (t == null)
                    {
                        return; //No type defined
                    }
                    //Update the type name
                    if (!String.IsNullOrEmpty(t.ObfuscatedTypeName))
                    {
                        methodType.Name = t.ObfuscatedTypeName;
                    }

                    //We can't change method specifications....
                    if (memberReference is MethodSpecification)
                    {
                        MethodSpecification specification = (MethodSpecification)memberReference;
                        MethodReference     meth          = specification.GetElementMethod();
                        //Update the method name also if available
                        if (t.HasMethodMapping(meth))
                        {
                            meth.Name = t.GetObfuscatedMethodName(meth);
                        }
                    }
                    else if (memberReference is FieldReference)
                    {
                        FieldReference fr = (FieldReference)memberReference;
                        if (t.HasFieldMapping(fr))
                        {
                            memberReference.Name = t.GetObfuscatedFieldName(fr);
                        }
                    }
                    else if (memberReference is MethodReference) //Is this ever used?? Used to be just an else without if
                    {
                        MethodReference mr = (MethodReference)memberReference;
                        //Update the method name also if available
                        if (t.HasMethodMapping(mr))
                        {
                            memberReference.Name = t.GetObfuscatedMethodName(mr);
                        }
                    }
                }
            }
        }
Ejemplo n.º 13
0
        private static void UpdateMethodReferences(ICloakContext context, MethodDefinition methodDefinition)
        {
            if (methodDefinition.HasBody)
            {
                foreach (Instruction instruction in methodDefinition.Body.Instructions)
                {
                    //Find the call statement
                    switch (instruction.OpCode.Name)
                    {
                    case "call":
                    case "callvirt":
                    case "newobj":
#if DEBUG
                        OutputHelper.WriteLine("Discovered {0} {1} ({2})", instruction.OpCode.Name, instruction.Operand, instruction.Operand.GetType().Name);
#endif

                        //Look at the operand
                        if (instruction.Operand is GenericInstanceMethod)     //We do this one first due to inheritance
                        {
                            GenericInstanceMethod genericInstanceMethod =
                                (GenericInstanceMethod)instruction.Operand;
                            //Update the standard naming
                            UpdateMemberTypeReferences(context, genericInstanceMethod);
                            //Update the generic types
                            foreach (TypeReference tr in genericInstanceMethod.GenericArguments)
                            {
                                UpdateTypeReferences(context, tr);
                            }
                        }
                        else if (instruction.Operand is MethodReference)
                        {
                            MethodReference methodReference = (MethodReference)instruction.Operand;
                            //Update the standard naming
                            UpdateMemberTypeReferences(context, methodReference);
                        }

                        break;

                    case "stfld":
                    case "ldfld":
#if DEBUG
                        OutputHelper.WriteLine("Discovered {0} {1} ({2})", instruction.OpCode.Name, instruction.Operand, instruction.Operand.GetType().Name);
#endif
                        //Look at the operand
                        FieldReference fieldReference = instruction.Operand as FieldReference;
                        if (fieldReference != null)
                        {
                            UpdateMemberTypeReferences(context, fieldReference);
                        }
                        break;
                    }
                }
            }
        }
Ejemplo n.º 14
0
 /// <summary>
 /// Runs the specified cloaking task.
 /// </summary>
 /// <param name="context">The running context of this cloak job.</param>
 public void RunTask(ICloakContext context)
 {
     Dictionary<string, AssemblyDefinition> assemblyCache = context.GetAssemblyDefinitions();
     foreach (string assembly in assemblyCache.Keys)
     {
         //Save the assembly
         string outputPath = Path.Combine(context.Settings.OutputDirectory, Path.GetFileName(assembly));
         OutputHelper.WriteLine("Outputting assembly to {0}", outputPath);
         assemblyCache[assembly].Write(outputPath);
     }
 }
Ejemplo n.º 15
0
        /// <summary>
        /// Runs the specified cloaking task.
        /// </summary>
        /// <param name="context">The running context of this cloak job.</param>
        public void RunTask(ICloakContext context)
        {
            Dictionary <string, AssemblyDefinition> assemblyCache = context.GetAssemblyDefinitions();

            foreach (string assembly in assemblyCache.Keys)
            {
                //Save the assembly
                string outputPath = Path.Combine(context.Settings.OutputDirectory, Path.GetFileName(assembly));
                OutputHelper.WriteLine("Outputting assembly to {0}", outputPath);
                assemblyCache[assembly].Write(outputPath);
            }
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Runs the specified cloaking task.
        /// </summary>
        /// <param name="context">The running context of this cloak job.</param>
        public void RunTask(ICloakContext context)
        {
            //Get out if rename is turned off
            if (context.Settings.NoRename)
                return;
            //Go through the members and build up a mapping graph
            //If this is done then the members in the graph will be obfuscated, otherwise we'll 
            //just obfuscate private members

            //Loop through each assembly and process it
            foreach (AssemblyDefinition definition in context.GetAssemblyDefinitions().Values)
            {
                ProcessAssembly(context, definition);
            }
        }
Ejemplo n.º 17
0
        /// <summary>
        /// Runs the specified cloaking task.
        /// </summary>
        /// <param name="context">The running context of this cloak job.</param>
        public void RunTask(ICloakContext context)
        {
            //Get out if rename is turned off
            if (context.Settings.NoRename)
            {
                return;
            }
            //Go through the members and build up a mapping graph
            //If this is done then the members in the graph will be obfuscated, otherwise we'll
            //just obfuscate private members

            //Loop through each assembly and process it
            foreach (AssemblyDefinition definition in context.GetAssemblyDefinitions().Values)
            {
                ProcessAssembly(context, definition);
            }
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Runs the specified cloaking task.
        /// </summary>
        /// <param name="context">The running context of this cloak job.</param>
        public void RunTask(ICloakContext context)
        {
            //We don't need to do this
            if (method == ConfusionMethod.None)
                return;

            //Go through each assembly
            foreach (AssemblyDefinition definition in context.GetAssemblyDefinitions().Values)
            {
                switch (method)
                {
                    case ConfusionMethod.InvalidIl:
                        ConfuseDecompilationWithInvalidIl(definition);
                        break;
                    default:
                        throw new ArgumentOutOfRangeException();
                }
            }
        }
Ejemplo n.º 19
0
        /// <summary>
        /// Runs the clock process.
        /// </summary>
        public void Run(ICloakContext context)
        {
            //Back stop - allows for tests to include only the relevant tasks
            if (cloakingTasks.Count == 0)
            {
                Configure(context);
            }

            //Make sure we have a context
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            //Run through each of our tasks
            foreach (ICloakTask task in cloakingTasks)
            {
                OutputHelper.WriteTask(task);
                task.RunTask(context);
            }
        }
Ejemplo n.º 20
0
        /// <summary>
        /// Runs the specified cloaking task.
        /// </summary>
        /// <param name="context">The running context of this cloak job.</param>
        public void RunTask(ICloakContext context)
        {
            //We don't need to do this
            if (method == ConfusionMethod.None)
            {
                return;
            }

            //Go through each assembly
            foreach (AssemblyDefinition definition in context.GetAssemblyDefinitions().Values)
            {
                switch (method)
                {
                case ConfusionMethod.InvalidIl:
                    ConfuseDecompilationWithInvalidIl(definition);
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }
        }
Ejemplo n.º 21
0
 /// <summary>
 /// Updates the type references.
 /// </summary>
 /// <param name="context">The context.</param>
 /// <param name="typeReference">The type reference.</param>
 private static void UpdateTypeReferences(ICloakContext context, TypeReference typeReference)
 {
     //Get the assembly for this
     if (typeReference.Scope is AssemblyNameReference)
     {
         string assemblyName = ((AssemblyNameReference)typeReference.Scope).FullName;
         //Check if this needs to be updated
         if (context.MappingGraph.IsAssemblyMappingDefined(assemblyName))
         {
             AssemblyMapping assemblyMapping = context.MappingGraph.GetAssemblyMapping(assemblyName);
             TypeMapping     t = assemblyMapping.GetTypeMapping(typeReference);
             if (t == null)
             {
                 return; //No type defined
             }
             //Update the type name
             if (!String.IsNullOrEmpty(t.ObfuscatedTypeName))
             {
                 typeReference.Name = t.ObfuscatedTypeName;
             }
         }
     }
 }
Ejemplo n.º 22
0
        /// <summary>
        /// Performs obfuscation on the specified assembly.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="definition">The assembly definition.</param>
        private static void Obfuscate(ICloakContext context, AssemblyDefinition definition)
        {
            //Get the assembly mapping information (if any)
            if (context.MappingGraph.IsAssemblyMappingDefined(definition))
            {
                //Get the mapping object
                AssemblyMapping assemblyMapping = context.MappingGraph.GetAssemblyMapping(definition);

                //Go through each module
                foreach (ModuleDefinition moduleDefinition in definition.Modules)
                {
                    //Go through each type
                    foreach (TypeDefinition typeDefinition in moduleDefinition.GetAllTypes())
                    {
                        //Get the type mapping
                        TypeMapping typeMapping = assemblyMapping.GetTypeMapping(typeDefinition);
                        if (typeMapping == null)
                            continue; //There is a problem....
                        //Rename if necessary
                        if (!String.IsNullOrEmpty(typeMapping.ObfuscatedTypeName))
                            typeDefinition.Name = typeMapping.ObfuscatedTypeName;

                        //Go through each method
                        foreach (MethodDefinition methodDefinition in typeDefinition.Methods)
                        {
                            //If this is an entry method then note it
                            //bool isEntry = false;
                            //if (definition.EntryPoint != null && definition.EntryPoint.Name == methodDefinition.Name)
                            //    isEntry = true;
                            if (typeMapping.HasMethodMapping(methodDefinition))
                                methodDefinition.Name = typeMapping.GetObfuscatedMethodName(methodDefinition);

                            //Dive into the method body
                            UpdateMethodReferences(context, methodDefinition);
                            //if (isEntry)
                            //    definition.EntryPoint = methodDefinition;
                        }

                        //Properties
                        foreach (PropertyDefinition propertyDefinition in typeDefinition.Properties)
                        {
                            if (typeMapping.HasPropertyMapping(propertyDefinition))
                                propertyDefinition.Name =
                                    typeMapping.GetObfuscatedPropertyName(propertyDefinition);

                            //Dive into the method body
                            if (propertyDefinition.GetMethod != null)
                                UpdateMethodReferences(context, propertyDefinition.GetMethod);
                            if (propertyDefinition.SetMethod != null)
                                UpdateMethodReferences(context, propertyDefinition.SetMethod);
                        }

                        //Fields
                        foreach (FieldDefinition fieldDefinition in typeDefinition.Fields)
                        {
                            if (typeMapping.HasFieldMapping(fieldDefinition))
                                fieldDefinition.Name = typeMapping.GetObfuscatedFieldName(fieldDefinition);
                        }

                    }
                }
            }
        }
Ejemplo n.º 23
0
        /// <summary>
        /// Updates the type references.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="typeReference">The type reference.</param>
        private static void UpdateTypeReferences(ICloakContext context, TypeReference typeReference)
        {
            //Get the assembly for this
            if (typeReference.Scope is AssemblyNameReference)
            {
                string assemblyName = ((AssemblyNameReference)typeReference.Scope).FullName;
                //Check if this needs to be updated
                if (context.MappingGraph.IsAssemblyMappingDefined(assemblyName))
                {
                    AssemblyMapping assemblyMapping = context.MappingGraph.GetAssemblyMapping(assemblyName);
                    TypeMapping t = assemblyMapping.GetTypeMapping(typeReference);
                    if (t == null)
                        return; //No type defined

                    //Update the type name
                    if (!String.IsNullOrEmpty(t.ObfuscatedTypeName))
                        typeReference.Name = t.ObfuscatedTypeName;
                }
            }
        }
Ejemplo n.º 24
0
        /// <summary>
        /// Updates the member type references.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="memberReference">The member reference.</param>
        private static void UpdateMemberTypeReferences(ICloakContext context, MemberReference memberReference)
        {
            //Get the type reference for this
            TypeReference methodType = memberReference.DeclaringType;
            //Get the assembly for this
            if (methodType.Scope is AssemblyNameReference)
            {
                string assemblyName = ((AssemblyNameReference) methodType.Scope).FullName;
                //Check if this needs to be updated
                if (context.MappingGraph.IsAssemblyMappingDefined(assemblyName))
                {
                    AssemblyMapping assemblyMapping = context.MappingGraph.GetAssemblyMapping(assemblyName);
                    TypeMapping t = assemblyMapping.GetTypeMapping(methodType);
                    if (t == null)
                        return; //No type defined

                    //Update the type name
                    if (!String.IsNullOrEmpty(t.ObfuscatedTypeName))
                        methodType.Name = t.ObfuscatedTypeName;

                    //We can't change method specifications....
                    if (memberReference is MethodSpecification)
                    {
                        MethodSpecification specification = (MethodSpecification)memberReference;
                        MethodReference meth = specification.GetElementMethod();
                        //Update the method name also if available
                        if (t.HasMethodMapping(meth))
                            meth.Name = t.GetObfuscatedMethodName(meth);
                    }
                    else if (memberReference is FieldReference)
                    {
                        FieldReference fr = (FieldReference) memberReference;
                        if (t.HasFieldMapping(fr))
                            memberReference.Name = t.GetObfuscatedFieldName(fr);
                    }
                    else if (memberReference is MethodReference) //Is this ever used?? Used to be just an else without if
                    {
                        MethodReference mr = (MethodReference) memberReference;
                        //Update the method name also if available
                        if (t.HasMethodMapping(mr))
                            memberReference.Name = t.GetObfuscatedMethodName(mr);
                    }
                }
            }
        }
Ejemplo n.º 25
0
        private static void UpdateMethodReferences(ICloakContext context, MethodDefinition methodDefinition)
        {
            if (methodDefinition.HasBody)
            {
                foreach (Instruction instruction in methodDefinition.Body.Instructions)
                {
                    //Find the call statement
                    switch (instruction.OpCode.Name)
                    {
                        case "call":
                        case "callvirt":
                        case "newobj":
#if DEBUG
                            OutputHelper.WriteLine("Discovered {0} {1} ({2})", instruction.OpCode.Name, instruction.Operand, instruction.Operand.GetType().Name);
#endif

                            //Look at the operand
                            if (instruction.Operand is GenericInstanceMethod) //We do this one first due to inheritance 
                            {
                                GenericInstanceMethod genericInstanceMethod =
                                    (GenericInstanceMethod) instruction.Operand;
                                //Update the standard naming
                                UpdateMemberTypeReferences(context, genericInstanceMethod);
                                //Update the generic types
                                foreach (TypeReference tr in genericInstanceMethod.GenericArguments)
                                    UpdateTypeReferences(context, tr);
                            }
                            else if (instruction.Operand is MethodReference)
                            {
                                MethodReference methodReference = (MethodReference)instruction.Operand;
                                //Update the standard naming
                                UpdateMemberTypeReferences(context, methodReference);
                            }

                            break;
                        case "stfld":
                        case "ldfld":
#if DEBUG
                            OutputHelper.WriteLine("Discovered {0} {1} ({2})", instruction.OpCode.Name, instruction.Operand, instruction.Operand.GetType().Name);
#endif
                            //Look at the operand
                            FieldReference fieldReference = instruction.Operand as FieldReference;
                            if (fieldReference != null)
                                UpdateMemberTypeReferences(context, fieldReference);
                            break;
                    }
                }
            }
        }
Ejemplo n.º 26
0
        /// <summary>
        /// Performs obfuscation on the specified assembly.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="definition">The assembly definition.</param>
        private static void Obfuscate(ICloakContext context, AssemblyDefinition definition)
        {
            //Get the assembly mapping information (if any)
            if (context.MappingGraph.IsAssemblyMappingDefined(definition))
            {
                //Get the mapping object
                AssemblyMapping assemblyMapping = context.MappingGraph.GetAssemblyMapping(definition);

                //Go through each module
                foreach (ModuleDefinition moduleDefinition in definition.Modules)
                {
                    //Go through each type
                    foreach (TypeDefinition typeDefinition in moduleDefinition.GetAllTypes())
                    {
                        //Get the type mapping
                        TypeMapping typeMapping = assemblyMapping.GetTypeMapping(typeDefinition);
                        if (typeMapping == null)
                        {
                            continue; //There is a problem....
                        }
                        //Rename if necessary
                        if (!String.IsNullOrEmpty(typeMapping.ObfuscatedTypeName))
                        {
                            typeDefinition.Name = typeMapping.ObfuscatedTypeName;
                        }

                        //Go through each method
                        foreach (MethodDefinition methodDefinition in typeDefinition.Methods)
                        {
                            //If this is an entry method then note it
                            //bool isEntry = false;
                            //if (definition.EntryPoint != null && definition.EntryPoint.Name == methodDefinition.Name)
                            //    isEntry = true;
                            if (typeMapping.HasMethodMapping(methodDefinition))
                            {
                                methodDefinition.Name = typeMapping.GetObfuscatedMethodName(methodDefinition);
                            }

                            //Dive into the method body
                            UpdateMethodReferences(context, methodDefinition);
                            //if (isEntry)
                            //    definition.EntryPoint = methodDefinition;
                        }

                        //Properties
                        foreach (PropertyDefinition propertyDefinition in typeDefinition.Properties)
                        {
                            if (typeMapping.HasPropertyMapping(propertyDefinition))
                            {
                                propertyDefinition.Name =
                                    typeMapping.GetObfuscatedPropertyName(propertyDefinition);
                            }

                            //Dive into the method body
                            if (propertyDefinition.GetMethod != null)
                            {
                                UpdateMethodReferences(context, propertyDefinition.GetMethod);
                            }
                            if (propertyDefinition.SetMethod != null)
                            {
                                UpdateMethodReferences(context, propertyDefinition.SetMethod);
                            }
                        }

                        //Fields
                        foreach (FieldDefinition fieldDefinition in typeDefinition.Fields)
                        {
                            if (typeMapping.HasFieldMapping(fieldDefinition))
                            {
                                fieldDefinition.Name = typeMapping.GetObfuscatedFieldName(fieldDefinition);
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 27
0
        /// <summary>
        /// Builds the load assemblies method.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="assembly">The assembly.</param>
        /// <param name="executingAssembly">The executing assembly.</param>
        /// <param name="loadAssembly">The load assembly.</param>
        /// <returns></returns>
        private static MethodDefinition BuildLoadAssembliesMethod(ICloakContext context, AssemblyDefinition assembly, FieldReference executingAssembly, MethodReference loadAssembly)
        {
#if USE_FRIENDLY_NAMING
            MethodDefinition method = new MethodDefinition("LoadAssemblies",
                                               MethodAttributes.Private | MethodAttributes.HideBySig, assembly.Import(typeof(void)));
#else
            MethodDefinition method = new MethodDefinition(context.NameManager.GenerateName(NamingTable.Method),
                                               MethodAttributes.Private | MethodAttributes.HideBySig, assembly.Import(typeof(void)));
#endif
            method.Body.InitLocals = true;
            method.Body.MaxStackSize = 2;
            method.AddLocal(assembly, typeof (string)); //Resource name
            method.AddLocal(assembly, typeof (string[])); //Foreach temp
            method.AddLocal(assembly, typeof (int)); //Loop counter
            method.AddLocal(assembly, typeof(bool));

            //Build the body
            var il = method.Body.GetILProcessor();
            InjectAntiReflectorCode(il, il.Create(OpCodes.Nop));
            il.Append(OpCodes.Nop);
            il.Append(OpCodes.Ldarg_0);
            il.Append(il.Create(OpCodes.Ldfld, executingAssembly));

            //Get the resources - foreach get's converted to a standard loop
            var resourcesMethod = typeof (Assembly).GetMethod("GetManifestResourceNames");
            il.Append(il.Create(OpCodes.Callvirt, assembly.Import(resourcesMethod)));
            il.Append(OpCodes.Stloc_1);

            //Initialise the loop counter
            il.Append(OpCodes.Ldc_I4_0);
            il.Append(OpCodes.Stloc_2);

            //For loop comparison (well create somewhere to jump to)
            var loopComparisonStart = il.Create(OpCodes.Ldloc_2);

            //Check the comparison now
            il.Append(il.Create(OpCodes.Br_S, loopComparisonStart));
            var startCode = il.Create(OpCodes.Ldloc_1);
            il.Append(startCode);
            il.Append(OpCodes.Ldloc_2);
            il.Append(OpCodes.Ldelem_Ref);
            il.Append(OpCodes.Stloc_0);
            il.Append(OpCodes.Nop);
            il.Append(OpCodes.Ldloc_0);

            //Make sure it doesn't end with .v0 or .e
            il.Append(il.Create(OpCodes.Ldstr, ".v0"));
            var endsWith = assembly.Import(typeof (String).GetMethod("EndsWith", new[] {typeof (string)}));
            il.Append(il.Create(OpCodes.Callvirt, endsWith));

            //Jump out as need be
            var load0 = il.Create(OpCodes.Ldc_I4_0);
            il.Append(il.Create(OpCodes.Brtrue_S, load0));
            il.Append(OpCodes.Ldloc_0);
            
            //Check the .e
            il.Append(il.Create(OpCodes.Ldstr, ".e"));
            il.Append(il.Create(OpCodes.Callvirt, endsWith));
            il.Append(OpCodes.Ldc_I4_0);
            il.Append(OpCodes.Ceq);
            var storeTempBool = il.Create(OpCodes.Stloc_3);
            il.Append(il.Create(OpCodes.Br_S, storeTempBool));
            il.Append(load0);
            il.Append(storeTempBool);
            il.Append(OpCodes.Ldloc_3);
            var loadArg0 = il.Create(OpCodes.Ldarg_0);
            il.Append(il.Create(OpCodes.Brtrue_S, loadArg0));
            var loadLoopCounter = il.Create(OpCodes.Ldloc_2);
            il.Append(il.Create(OpCodes.Br_S, loadLoopCounter));
            il.Append(loadArg0);
            il.Append(OpCodes.Ldloc_0);

            //Finally load the assembly
            il.Append(il.Create(OpCodes.Call, loadAssembly));
            il.Append(OpCodes.Pop);
            il.Append(OpCodes.Nop);
            
            //Loop counter
            il.Append(loadLoopCounter);
            il.Append(OpCodes.Ldc_I4_1);
            il.Append(OpCodes.Add);
            il.Append(OpCodes.Stloc_2);

            //Loop comparison
            il.Append(loopComparisonStart);
            il.Append(OpCodes.Ldloc_1);
            il.Append(OpCodes.Ldlen);
            il.Append(OpCodes.Conv_I4);
            il.Append(OpCodes.Clt);
            //Store the result
            il.Append(OpCodes.Stloc_3);
            //Load it and compare
            il.Append(OpCodes.Ldloc_3);
            il.Append(il.Create(OpCodes.Brtrue_S, startCode));
            il.Append(OpCodes.Ret);
            return method;
        }
Ejemplo n.º 28
0
        /// <summary>
        /// Builds the main entry point to the bootstrapper.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="assembly">The assembly.</param>
        /// <param name="passwordKey">The password key.</param>
        /// <param name="salt">The salt.</param>
        private static void BuildBootstrapper(ICloakContext context, AssemblyDefinition assembly, string passwordKey, Guid salt)
        {
            //See http://blog.paul-mason.co.nz/2010/02/tamper-proofing-implementation-part-2.html

            //First create the actual program runner
#if USE_FRIENDLY_NAMING
            TypeDefinition programType = new TypeDefinition("ProgramRunner",
                                                        "NCloak.Bootstrapper.Internal",
                                                        TypeAttributes.NotPublic | TypeAttributes.Class |
                                                        TypeAttributes.AutoClass | TypeAttributes.AnsiClass |
                                                        TypeAttributes.Serializable | TypeAttributes.BeforeFieldInit,
                                                        assembly.Import(typeof(object)));

#else
            TypeDefinition programType = new TypeDefinition(context.NameManager.GenerateName(NamingTable.Type),
                                                        context.NameManager.GenerateName(NamingTable.Type),
                                                        TypeAttributes.NotPublic | TypeAttributes.Class |
                                                        TypeAttributes.AutoClass | TypeAttributes.AnsiClass |
                                                        TypeAttributes.Serializable | TypeAttributes.BeforeFieldInit,
                                                        assembly.Import(typeof(object)));
#endif
            assembly.MainModule.Types.Add(programType);

            //Add the class level fields
#if USE_FRIENDLY_NAMING
            string assembliesLoadedVariableName = "assembliesLoaded";
            string assemblyLockVariableName = "assemblyLock";
            string executingAssemblyVariableName = "executingAssembly";
            string loadedAssembliesVariableName = "loadedAssemblies";
#else
            string assembliesLoadedVariableName = context.NameManager.GenerateName(NamingTable.Field);
            string assemblyLockVariableName = context.NameManager.GenerateName(NamingTable.Field);
            string executingAssemblyVariableName = context.NameManager.GenerateName(NamingTable.Field);
            string loadedAssembliesVariableName = context.NameManager.GenerateName(NamingTable.Field);
#endif
            var assembliesLoaded = new FieldDefinition(assembliesLoadedVariableName, FieldAttributes.Private, assembly.Import(typeof(bool)));
            var assemblyLock = new FieldDefinition(assemblyLockVariableName, FieldAttributes.Private | FieldAttributes.InitOnly, assembly.Import(typeof(object)));
            var executingAssembly = new FieldDefinition(executingAssemblyVariableName, FieldAttributes.Private | FieldAttributes.InitOnly, assembly.Import(typeof(Assembly)));
            var loadedAssemblies = new FieldDefinition(loadedAssembliesVariableName,FieldAttributes.Private | FieldAttributes.InitOnly, assembly.Import(typeof(Dictionary<string, Assembly>)));
            programType.Fields.Add(assembliesLoaded);
            programType.Fields.Add(assemblyLock);
            programType.Fields.Add(executingAssembly);
            programType.Fields.Add(loadedAssemblies);

            //Get some method references we share
            MethodReference currentDomain = assembly.Import(typeof(AppDomain).GetProperty("CurrentDomain").GetGetMethod());
            MethodReference eventHandler = assembly.Import(typeof(ResolveEventHandler).GetConstructor(new[] { typeof(object), typeof(IntPtr) }));
            MethodReference assemblyResolve = assembly.Import(typeof(AppDomain).GetEvent("AssemblyResolve").GetAddMethod());
            MethodReference getExecutingAssembly = assembly.Import(typeof(Assembly).GetMethod("GetExecutingAssembly"));

            //Define decrypt data method
            var decryptMethod = BuildDecryptMethod(context, assembly);
            programType.Methods.Add(decryptMethod);

            //Define hash data method
            var hashMethod = BuildHashMethod(context, assembly);
            programType.Methods.Add(hashMethod);

            //Define load assembly
            var loadAssemblyMethod = BuildLoadAssemblyMethod(context, assembly, loadedAssemblies, executingAssembly, decryptMethod, hashMethod, passwordKey, salt);
            programType.Methods.Add(loadAssemblyMethod);

            //Define load type method
            var loadTypeMethod = BuildLoadTypeMethod(context, assembly, loadAssemblyMethod);
            programType.Methods.Add(loadTypeMethod);

            //Define load assemblies method
            var loadAssembliesMethod = BuildLoadAssembliesMethod(context, assembly, executingAssembly, loadAssemblyMethod);
            programType.Methods.Add(loadAssembliesMethod);

            //Define resolve method
            var resolveMethod = BuildResolveMethod(context, assembly, assemblyLock, assembliesLoaded, loadAssembliesMethod);
            programType.Methods.Add(resolveMethod);

            //Define start method
            var startMethod = BuildStartMethod(context, assembly, executingAssembly, assembliesLoaded, loadTypeMethod, loadAssembliesMethod);
            programType.Methods.Add(startMethod);

            //Now define a constructor
            BuildProgramConstructor(assembly, programType, assemblyLock, executingAssembly, loadedAssemblies, currentDomain, eventHandler, assemblyResolve, getExecutingAssembly, resolveMethod);

            //Now create a type to hold the entry point
#if USE_FRIENDLY_NAMING
            TypeDefinition entryType = new TypeDefinition("Program",
                                            "NCloak.Bootstrapper",
                                            TypeAttributes.NotPublic | TypeAttributes.Class |
                                            TypeAttributes.AutoClass | TypeAttributes.AnsiClass |
                                            TypeAttributes.BeforeFieldInit,
                                            assembly.Import(typeof(object)));
#else
            TypeDefinition entryType = new TypeDefinition(context.NameManager.GenerateName(NamingTable.Type),
                                                        context.NameManager.GenerateName(NamingTable.Type),
                                                        TypeAttributes.NotPublic | TypeAttributes.Class |
                                                        TypeAttributes.AutoClass | TypeAttributes.AnsiClass |
                                                        TypeAttributes.BeforeFieldInit,
                                                        assembly.Import(typeof(object)));
#endif
            assembly.MainModule.Types.Add(entryType);

            //Create a default constructor
            var ctor = assembly.CreateDefaultConstructor(entryType);
            ctor.MaxStackSize = 8;
            var il = ctor.GetILProcessor();
            InjectAntiReflectorCode(il, il.Create(OpCodes.Ldarg_0));
            var objectCtor = assembly.Import(typeof (object).GetConstructor(Type.EmptyTypes));
            il.Append(il.Create(OpCodes.Call, objectCtor));
            il.Append(OpCodes.Ret);

            //Create an entry point
            var mainMethod = BuildMainMethod(assembly, context, programType, getExecutingAssembly, currentDomain, eventHandler, assemblyResolve, resolveMethod, startMethod);
            entryType.Methods.Add(mainMethod);
        }
Ejemplo n.º 29
0
        /// <summary>
        /// Builds the decrypt method.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="assembly">The assembly.</param>
        /// <returns></returns>
        private static MethodDefinition BuildDecryptMethod(ICloakContext context, AssemblyDefinition assembly)
        {
            var byteArrayType = assembly.Import(typeof (byte[]));
#if USE_FRIENDLY_NAMING
            MethodDefinition method = new MethodDefinition("DecryptData",
                                                           MethodAttributes.Private | MethodAttributes.HideBySig |
                                                           MethodAttributes.Static, byteArrayType);
#else
            MethodDefinition method = new MethodDefinition(context.NameManager.GenerateName(NamingTable.Method),
                                                           MethodAttributes.Private | MethodAttributes.HideBySig |
                                                           MethodAttributes.Static, assembly.Import(typeof(byte[])));
#endif
            method.Body.InitLocals = true;
            method.Body.MaxStackSize = 5;
            method.Parameters.Add(new ParameterDefinition(byteArrayType));
            method.Parameters.Add(new ParameterDefinition(byteArrayType));
            method.Parameters.Add(new ParameterDefinition(byteArrayType));

            //Declare the locals - first four have quick reference
            method.AddLocal(assembly, typeof(Rijndael));
            method.AddLocal(assembly, typeof(ICryptoTransform));
            method.AddLocal(assembly, typeof(MemoryStream));
            method.AddLocal(assembly, typeof(CryptoStream));
            var paddedPlain = method.AddLocal(assembly, typeof(byte[]));
            var length = method.AddLocal(assembly, typeof(int));
            var plain = method.AddLocal(assembly, typeof(byte[]));
            var returnArray = method.AddLocal(assembly, typeof(byte[]));
            var inferredBool = method.AddLocal(assembly, typeof(bool));

            //Add the body
            var il = method.Body.GetILProcessor();

            //Inject anti reflector code
            InjectAntiReflectorCode(il, il.Create(OpCodes.Nop));

            //Start the body
            var rijndaelCreate = typeof(Rijndael).GetMethod("Create", Type.EmptyTypes);
            il.Append(il.Create(OpCodes.Call, assembly.Import(rijndaelCreate)));
            il.Append(OpCodes.Stloc_0);
            il.Append(OpCodes.Ldloc_0);
            il.Append(OpCodes.Ldc_I4_1);
            var symmetricAlgMode = typeof(SymmetricAlgorithm).GetProperty("Mode");
            il.Append(il.Create(OpCodes.Callvirt, assembly.Import(symmetricAlgMode.GetSetMethod())));
            il.Append(OpCodes.Nop);
            il.Append(OpCodes.Ldloc_0);
            il.Append(OpCodes.Ldarg_1);
            il.Append(OpCodes.Ldarg_2);
            var createDecryptor = typeof(SymmetricAlgorithm).GetMethod("CreateDecryptor",
                                                                        new[] { typeof(byte[]), typeof(byte[]) });
            il.Append(il.Create(OpCodes.Callvirt, assembly.Import(createDecryptor)));
            il.Append(OpCodes.Stloc_1);
            var startOfThirdTry = il.Create(OpCodes.Nop);
            il.Append(startOfThirdTry);
            il.Append(OpCodes.Ldarg_0);

            //New memory stream
            var memoryStreamCtor = typeof(MemoryStream).GetConstructor(new [] { typeof(byte[]) });
            il.Append(il.Create(OpCodes.Newobj, assembly.Import(memoryStreamCtor)));
            il.Append(OpCodes.Stloc_2);
            var startOfSecondTry = il.Create(OpCodes.Nop);
            il.Append(startOfSecondTry);
            il.Append(OpCodes.Ldloc_2);
            il.Append(OpCodes.Ldloc_1);
            il.Append(OpCodes.Ldc_I4_0);

            //New crypto stream
            var cryptoStreamCtor =
                typeof(CryptoStream).GetConstructor(new[]
                                                                     {
                                                                         typeof (Stream), typeof (ICryptoTransform),
                                                                         typeof (CryptoStreamMode)
                                                                     });
            il.Append(il.Create(OpCodes.Newobj, assembly.Import(cryptoStreamCtor)));
            il.Append(OpCodes.Stloc_3);
            var startOfFirstTry = il.Create(OpCodes.Nop);
            il.Append(startOfFirstTry);
            il.Append(OpCodes.Ldarg_0);
            il.Append(OpCodes.Ldlen);
            il.Append(OpCodes.Conv_I4);
            il.Append(il.Create(OpCodes.Newarr, assembly.Import(typeof(byte))));
            il.Append(il.Create(OpCodes.Stloc_S, paddedPlain));
            il.Append(OpCodes.Ldloc_3);
            il.Append(il.Create(OpCodes.Ldloc_S, paddedPlain));
            il.Append(OpCodes.Ldc_I4_0);
            il.Append(il.Create(OpCodes.Ldloc_S, paddedPlain));
            il.Append(OpCodes.Ldlen);
            il.Append(OpCodes.Conv_I4);

            //Get the read method and read into this byte array (full length)
            var read = typeof(Stream).GetMethod("Read", new[] { typeof(byte[]), typeof(int), typeof(int) });
            il.Append(il.Create(OpCodes.Callvirt, assembly.Import(read)));
            il.Append(il.Create(OpCodes.Stloc_S, length));
            il.Append(il.Create(OpCodes.Ldloc_S, length));
            il.Append(il.Create(OpCodes.Newarr, assembly.Import(typeof(byte))));
            il.Append(il.Create(OpCodes.Stloc_S, plain));
            il.Append(il.Create(OpCodes.Ldloc_S, paddedPlain));
            il.Append(OpCodes.Ldc_I4_0);
            il.Append(il.Create(OpCodes.Ldloc_S, plain));
            il.Append(OpCodes.Ldc_I4_0);
            il.Append(il.Create(OpCodes.Ldloc_S, length));

            //Array::Copy
            var arrayCopy = typeof(Array).GetMethod("Copy",
                                                     new[]
                                                                     {
                                                                         typeof (Array), typeof (int), typeof (Array), typeof (int),
                                                                         typeof (int)
                                                                     });
            il.Append(il.Create(OpCodes.Call, assembly.Import(arrayCopy)));
            il.Append(OpCodes.Nop);//padding
            il.Append(il.Create(OpCodes.Ldloc_S, plain));
            il.Append(il.Create(OpCodes.Stloc_S, returnArray));

            //Now it gets a bit confusing as we need to do a few jumps (OO and all...)
            var endNop = il.Create(OpCodes.Nop);
            il.Append(il.Create(OpCodes.Leave_S, endNop));

            //First finally
            var firstStartFinally = il.Create(OpCodes.Ldloc_3);
            il.Append(firstStartFinally);
            il.Append(OpCodes.Ldnull);
            il.Append(OpCodes.Ceq);
            il.Append(il.Create(OpCodes.Stloc_S, inferredBool));
            il.Append(il.Create(OpCodes.Ldloc_S, inferredBool));
            var firstEndFinally = il.Create(OpCodes.Endfinally);
            il.Append(il.Create(OpCodes.Brtrue_S, firstEndFinally));
            il.Append(OpCodes.Ldloc_3);
            //Get the disposable virtual method
            var dispose = assembly.Import(typeof(IDisposable).GetMethod("Dispose"));
            il.Append(il.Create(OpCodes.Callvirt, dispose));
            il.Append(OpCodes.Nop);
            il.Append(firstEndFinally);

            //Second finally
            var secondStartFinally = il.Create(OpCodes.Ldloc_2);
            il.Append(secondStartFinally);
            il.Append(OpCodes.Ldnull);
            il.Append(OpCodes.Ceq);
            il.Append(il.Create(OpCodes.Stloc_S, inferredBool));
            il.Append(il.Create(OpCodes.Ldloc_S, inferredBool));
            var secondEndFinally = il.Create(OpCodes.Endfinally);
            il.Append(il.Create(OpCodes.Brtrue_S, secondEndFinally));
            il.Append(OpCodes.Ldloc_2);
            il.Append(il.Create(OpCodes.Callvirt, dispose));
            il.Append(OpCodes.Nop);
            il.Append(secondEndFinally);

            //Third finally
            var thirdStartFinally = il.Create(OpCodes.Ldloc_1);
            il.Append(thirdStartFinally);
            il.Append(OpCodes.Ldnull);
            il.Append(OpCodes.Ceq);
            il.Append(il.Create(OpCodes.Stloc_S, inferredBool));
            il.Append(il.Create(OpCodes.Ldloc_S, inferredBool));
            var thirdEndFinally = il.Create(OpCodes.Endfinally);
            il.Append(il.Create(OpCodes.Brtrue_S, thirdEndFinally));
            il.Append(OpCodes.Ldloc_1);
            il.Append(il.Create(OpCodes.Callvirt, dispose));
            il.Append(OpCodes.Nop);
            il.Append(thirdEndFinally);

            //Clean up and return
            il.Append(endNop);
            il.Append(il.Create(OpCodes.Ldloc_S, returnArray));
            il.Append(OpCodes.Ret);

            //Add the try/finally handlers
            var handler1 = new ExceptionHandler(ExceptionHandlerType.Finally);
            handler1.TryStart = startOfFirstTry;
            handler1.TryEnd = firstStartFinally;
            handler1.HandlerStart = firstStartFinally;
            handler1.HandlerEnd = secondStartFinally;
            method.Body.ExceptionHandlers.Add(handler1);

            var handler2 = new ExceptionHandler(ExceptionHandlerType.Finally);
            handler2.TryStart = startOfSecondTry;
            handler2.TryEnd = secondStartFinally;
            handler2.HandlerStart = secondStartFinally;
            handler2.HandlerEnd = thirdStartFinally;
            method.Body.ExceptionHandlers.Add(handler2);

            var handler3 = new ExceptionHandler(ExceptionHandlerType.Finally);
            handler3.TryStart = startOfThirdTry;
            handler3.TryEnd = thirdStartFinally;
            handler3.HandlerStart = thirdStartFinally;
            handler3.HandlerEnd = endNop;
            method.Body.ExceptionHandlers.Add(handler3);

            return method;
        }
Ejemplo n.º 30
0
        /// <summary>
        /// Builds the hash method.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="assembly">The assembly.</param>
        /// <returns></returns>
        private static MethodDefinition BuildHashMethod(ICloakContext context, AssemblyDefinition assembly)
        {
#if USE_FRIENDLY_NAMING
            MethodDefinition method = new MethodDefinition("Hash",
                                               MethodAttributes.Private | MethodAttributes.HideBySig |
                                               MethodAttributes.Static, assembly.Import(typeof(string)));
#else
            MethodDefinition method = new MethodDefinition(context.NameManager.GenerateName(NamingTable.Method),
                                               MethodAttributes.Private | MethodAttributes.HideBySig |
                                               MethodAttributes.Static, assembly.Import(typeof(string)));
#endif
            method.Parameters.Add(new ParameterDefinition(assembly.Import(typeof(byte[]))));
            method.Body.InitLocals = true;
            method.Body.MaxStackSize = 2;
            method.AddLocal(assembly, typeof(SHA256));
            method.AddLocal(assembly, typeof(string));

            //Easy method to output
            var il = method.Body.GetILProcessor();

            //Inject some anti reflector stuff
            InjectAntiReflectorCode(il, il.Create(OpCodes.Nop));

            //Create the SHA256 object
            var sha256Create = typeof(SHA256).GetMethod("Create", Type.EmptyTypes);
            il.Append(il.Create(OpCodes.Call, assembly.Import(sha256Create)));
            il.Append(OpCodes.Stloc_0);
            il.Append(OpCodes.Ldloc_0);
            il.Append(OpCodes.Ldarg_0);
            //Call the compute method
            var compute = typeof(HashAlgorithm).GetMethod("ComputeHash", new[] { typeof(byte[]) });
            il.Append(il.Create(OpCodes.Callvirt, assembly.Import(compute)));
            //Finally, convert to base 64
            var toBase64 = typeof(Convert).GetMethod("ToBase64String", new[] { typeof(byte[]) });
            il.Append(il.Create(OpCodes.Call, assembly.Import(toBase64)));
            il.Append(OpCodes.Stloc_1);
            var retVar = il.Create(OpCodes.Ldloc_1);
            il.Append(il.Create(OpCodes.Br_S, retVar));
            il.Append(retVar);
            il.Append(OpCodes.Ret);
            return method;
        }
Ejemplo n.º 31
0
        /// <summary>
        /// Builds the load type method.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="assembly">The assembly.</param>
        /// <param name="loadAssembly">The load assembly.</param>
        /// <returns></returns>
        private static MethodDefinition BuildLoadTypeMethod(ICloakContext context, AssemblyDefinition assembly, MethodReference loadAssembly)
        {
#if USE_FRIENDLY_NAMING
            MethodDefinition method = new MethodDefinition("LoadType",
                       MethodAttributes.Private | MethodAttributes.HideBySig, assembly.Import(typeof(Type)));
#else
            MethodDefinition method = new MethodDefinition(context.NameManager.GenerateName(NamingTable.Method),
                                   MethodAttributes.Private | MethodAttributes.HideBySig, assembly.Import(typeof(Type)));
#endif

            //Declare the resource parameter
            method.Parameters.Add(new ParameterDefinition(assembly.Import(typeof(string))));
            method.Parameters.Add(new ParameterDefinition(assembly.Import(typeof(string))));
            
            method.Body.InitLocals = true;
            method.Body.MaxStackSize = 2;
            method.AddLocal(assembly, typeof(Assembly)); //Assembly
            method.AddLocal(assembly, typeof(Type)); //Temp variable for return type
            method.AddLocal(assembly, typeof(bool)); //Temp variable for comparison

            //Start with injection
            var il = method.Body.GetILProcessor();
            InjectAntiReflectorCode(il, il.Create(OpCodes.Nop));

            //Start the code
            il.Append(OpCodes.Ldarg_0);
            il.Append(OpCodes.Ldarg_1);
            il.Append(il.Create(OpCodes.Call, loadAssembly));
            il.Append(OpCodes.Stloc_0);
            il.Append(OpCodes.Ldloc_0);
            il.Append(OpCodes.Ldnull);
            il.Append(OpCodes.Ceq);
            il.Append(OpCodes.Ldc_I4_0);
            il.Append(OpCodes.Ceq);
            il.Append(OpCodes.Stloc_2);
            il.Append(OpCodes.Ldloc_2);

            //Get type
            var getType = il.Create(OpCodes.Ldloc_0);
            il.Append(il.Create(OpCodes.Brtrue_S, getType));
            il.Append(OpCodes.Ldnull);
            il.Append(OpCodes.Stloc_1);

            //Prepare to return the temp type
            var returnType = il.Create(OpCodes.Ldloc_1);

            //Jump to it
            il.Append(il.Create(OpCodes.Br_S, returnType));
            il.Append(getType);
            il.Append(OpCodes.Ldarg_2);
            var getTypeMethod = typeof (Assembly).GetMethod("GetType", new[] {typeof (string)});
            il.Append(il.Create(OpCodes.Callvirt, assembly.Import(getTypeMethod)));
            il.Append(OpCodes.Stloc_1);
            il.Append(il.Create(OpCodes.Br_S, returnType));
            il.Append(returnType);
            il.Append(OpCodes.Ret);
            return method;
        }
Ejemplo n.º 32
0
        /// <summary>
        /// Runs the specified cloaking task.
        /// </summary>
        /// <param name="context">The running context of this cloak job.</param>
        public void RunTask(ICloakContext context)
        {
            //WARNING: This task may potentially break complex applications. Please test this
            //thorougly before deployment.
            //
            //This task must be run last (in place of OutputAssembliesTask) as it does the following
            //  1. Encrypts all obfuscated assemblies supplied to this program
            //  2. Calculates the hash of each of the obfuscated assemblies (as opposed to encrypted)
            //  3. Creates a bootstrapper assembly including each of the assemblies as resources
            //     - The bootstrapper essentially extracts each of it's contents into memory (n.b. attack point)
            //       It then checks the hash of the bytes and if successful, loads the bytes into the current AppDomain.
            //

            //So getting down to business... the first think we need to do is go through each assembly and 
            //encrypt using Symmetric encryption
            //Lets generate a password
            string passwordKey = Guid.NewGuid().ToString();
            Guid salt = Guid.NewGuid();
            Rfc2898DeriveBytes password = new Rfc2898DeriveBytes(passwordKey, salt.ToByteArray(), PasswordIterations);
            //Get the key bytes and initialisation vector
            byte[] keyBytes = password.GetBytes(KeySize / 8);
            byte[] initVector = password.GetBytes(InitVectorSize);

            //Go through each assembly, calculate the hash and encrypt
            Dictionary<string, byte[]> encryptedAssemblies = new Dictionary<string, byte[]>();
            Dictionary<string, byte[]> hashedAssemblies = new Dictionary<string, byte[]>();
            Dictionary<string, AssemblyDefinition> assemblies = context.GetAssemblyDefinitions();
            foreach (string assembly in assemblies.Keys)
            {
                //Get the raw data of the assembly
                byte[] assemblyRawData;
                using (MemoryStream ms = new MemoryStream())
                {
                    assemblies[assembly].Write(ms);
                    assemblyRawData = ms.ToArray();
                }
#if OUTPUT_PRE_TAMPER
                File.WriteAllBytes(context.Settings.OutputDirectory + "\\" + Path.GetFileName(assembly), assemblyRawData);
#endif

                //Calculate the hash
                hashedAssemblies.Add(assembly, HashData(assemblyRawData));

                //Now encrypt it
                encryptedAssemblies.Add(assembly, EncryptData(assemblyRawData, keyBytes, initVector));
            }

            //Now we've got that information - it's up to us to generate a bootstrapper assembly
            //We'll do this by starting from scratch
            
            AssemblyDefinition bootstrapperAssembly =
                AssemblyDefinition.CreateAssembly(new AssemblyNameDefinition(context.Settings.TamperProofAssemblyName, new Version(1, 0)), null,
                context.Settings.TamperProofAssemblyType == AssemblyType.Windows ? ModuleKind.Windows : ModuleKind.Console);

            //Add some resources - encrypted assemblies
#if USE_FRIENDLY_NAMING
            const string resourceNamespace = "Resources";
#else
            string resourceNamespace = context.NameManager.GenerateName(NamingTable.Type);
#endif
            foreach (string assembly in encryptedAssemblies.Keys)
            {
                //We'll randomise the names using the type table
#if USE_FRIENDLY_NAMING
                string resourceName = resourceNamespace + "." + Path.GetFileName(assembly);
#else
                string resourceName = resourceNamespace + "." + context.NameManager.GenerateName(NamingTable.Type);
#endif
                string hashName = resourceName + ".v0";
                bootstrapperAssembly.MainModule.Resources.Add(new EmbeddedResource(resourceName,
                                                                                   ManifestResourceAttributes.Private,
                                                                                   encryptedAssemblies[assembly]));
                bootstrapperAssembly.MainModule.Resources.Add(new EmbeddedResource(
                                                                  hashName,
                                                                  ManifestResourceAttributes.Private,
                                                                  hashedAssemblies[assembly]));

                //If it has an entry point then save this as well
                AssemblyDefinition def = assemblies[assembly];
                if (def.EntryPoint != null)
                {
                    StringBuilder entryPointHelper = new StringBuilder();
                    entryPointHelper.AppendLine(resourceName);
                    entryPointHelper.AppendLine(def.EntryPoint.DeclaringType.Namespace + "." + def.EntryPoint.DeclaringType.Name);
                    entryPointHelper.AppendLine(def.EntryPoint.Name);
                    bootstrapperAssembly.MainModule.Resources.Add(new EmbeddedResource(
                                                                  resourceName + ".e",
                                                                  ManifestResourceAttributes.Private,
                                                                  Encoding.Unicode.GetBytes(entryPointHelper.ToString())));
                }
            }

            //Now make it do something
            BuildBootstrapper(context, bootstrapperAssembly, passwordKey, salt);

            //Finally save this assembly to our output path
            string outputPath = Path.Combine(context.Settings.OutputDirectory, context.Settings.TamperProofAssemblyName + ".exe");
            OutputHelper.WriteLine("Outputting assembly to {0}", outputPath);
            bootstrapperAssembly.Write(outputPath);
        }
Ejemplo n.º 33
0
        /// <summary>
        /// Builds the load assembly method.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="assembly">The assembly.</param>
        /// <param name="loadedAssemblies">The loaded assemblies.</param>
        /// <param name="executingAssembly">The executing assembly.</param>
        /// <param name="decryptData">The decrypt data.</param>
        /// <param name="hashData">The hash data.</param>
        /// <param name="passwordKey">The password key.</param>
        /// <param name="salt">The salt.</param>
        /// <returns></returns>
        private static MethodDefinition BuildLoadAssemblyMethod(ICloakContext context, AssemblyDefinition assembly, FieldReference loadedAssemblies, FieldReference executingAssembly, MethodReference decryptData, MethodReference hashData, string passwordKey, Guid salt)
        {
#if USE_FRIENDLY_NAMING
            MethodDefinition method = new MethodDefinition("LoadAssembly",
                       MethodAttributes.Private | MethodAttributes.HideBySig, assembly.Import(typeof(Assembly)));
#else
            MethodDefinition method = new MethodDefinition(context.NameManager.GenerateName(NamingTable.Method),
                                   MethodAttributes.Private | MethodAttributes.HideBySig, assembly.Import(typeof(Assembly)));
#endif

            //Declare the resource parameter
            method.Parameters.Add(new ParameterDefinition(assembly.Import(typeof(string))));

            method.Body.InitLocals = true;
            method.Body.MaxStackSize = 4;
            method.AddLocal(assembly, typeof(string)); //Hash
            method.AddLocal(assembly, typeof(Stream)); //Stream for loading
            method.AddLocal(assembly, typeof(byte[])); //Hash data
            method.AddLocal(assembly, typeof(byte[])); //Data
            var password = method.AddLocal(assembly, typeof(Rfc2898DeriveBytes)); //Password
            var keyBytes = method.AddLocal(assembly, typeof(byte[])); //Key bytes
            var initVector = method.AddLocal(assembly, typeof(byte[])); //Init vector
            var rawAssembly = method.AddLocal(assembly, typeof(byte[])); //Assembly raw bytes
            var actualAssembly = method.AddLocal(assembly, typeof(Assembly)); //Actual Assembly
            var tempAssembly = method.AddLocal(assembly, typeof(Assembly)); //Temp Assembly
            var tempBool = method.AddLocal(assembly, typeof(bool)); //Temp bool

            //Build the body
            var il = method.Body.GetILProcessor();
            InjectAntiReflectorCode(il, il.Create(OpCodes.Nop));

#if VERBOSE_OUTPUT
            DebugLine(assembly, il, "Loading ", il.Create(OpCodes.Ldarg_1));
#endif

            //Check the cache first
            il.Append(OpCodes.Ldarg_0);
            il.Append(il.Create(OpCodes.Ldfld, loadedAssemblies));
            il.Append(OpCodes.Ldarg_1);
            var containsKey = typeof (Dictionary<string, Assembly>).GetMethod("ContainsKey");
            il.Append(il.Create(OpCodes.Callvirt, assembly.Import(containsKey)));
            il.Append(OpCodes.Ldc_I4_0);
            il.Append(OpCodes.Ceq);
            il.Append(il.Create(OpCodes.Stloc_S, tempBool));
            il.Append(il.Create(OpCodes.Ldloc_S, tempBool));
            //Jump if we don't have it, other wise return it
            var startFindType = il.Create(OpCodes.Ldarg_0);
            il.Append(il.Create(OpCodes.Brtrue_S, startFindType));
            
            //Otherwise return the cached assembly
            il.Append(OpCodes.Ldarg_0);
            il.Append(il.Create(OpCodes.Ldfld, loadedAssemblies));
            il.Append(OpCodes.Ldarg_1);
            //We are retrieving the name item
            var getItem = typeof (Dictionary<string, Assembly>).GetProperty("Item");
            il.Append(il.Create(OpCodes.Callvirt, assembly.Import(getItem.GetGetMethod())));
            //Store the variable in our return arg
            il.Append(il.Create(OpCodes.Stloc_S, tempAssembly));
            //Branch to our return routine
            var returnSequence = il.Create(OpCodes.Nop);
            il.Append(il.Create(OpCodes.Br, returnSequence));

            //Back to finding our type
            //Let's check the hash first
            il.Append(startFindType);
            il.Append(il.Create(OpCodes.Ldfld, executingAssembly));
            il.Append(OpCodes.Ldarg_1);
            il.Append(il.Create(OpCodes.Ldstr, ".v0"));
            //Concat the arg1 (resourceName) and v0
            var concat = assembly.Import(typeof (String).GetMethod("Concat", new[] {typeof (string), typeof (string)}));
            il.Append(il.Create(OpCodes.Call, concat));
            //Now get this from the manifest
            var getManifest = assembly.Import(typeof (Assembly).GetMethod("GetManifestResourceStream", new[] {typeof (string)}));
            il.Append(il.Create(OpCodes.Callvirt, getManifest));
            //Store the result in our temp local
            il.Append(OpCodes.Stloc_1);
            var try1Start = il.Create(OpCodes.Nop);
            il.Append(try1Start);
            //Make sure it's not null
            il.Append(OpCodes.Ldloc_1);
            il.Append(OpCodes.Ldnull);
            il.Append(OpCodes.Ceq);
            il.Append(OpCodes.Ldc_I4_0);
            il.Append(OpCodes.Ceq);
            il.Append(il.Create(OpCodes.Stloc_S, tempBool));
            il.Append(il.Create(OpCodes.Ldloc_S, tempBool));
            //Return null if it is
            var startDeclareArray = il.Create(OpCodes.Ldloc_1);
            il.Append(il.Create(OpCodes.Brtrue_S, startDeclareArray));
            //Load null into our return variable
            il.Append(OpCodes.Ldnull); 
            il.Append(il.Create(OpCodes.Stloc_S, tempAssembly));
            //Jump to the return routine
            il.Append(il.Create(OpCodes.Leave, returnSequence)); //Leave as in try
            //Carry on and declare a buffer
            il.Append(startDeclareArray);
            var getLength = assembly.Import(typeof (Stream).GetProperty("Length").GetGetMethod());
            il.Append(il.Create(OpCodes.Callvirt, getLength));
            il.Append(OpCodes.Conv_Ovf_I);
            il.Append(il.Create(OpCodes.Newarr, assembly.Import(typeof(byte))));
            //Now read it in
            il.Append(OpCodes.Stloc_2);
            il.Append(OpCodes.Ldloc_1);
            il.Append(OpCodes.Ldloc_2);
            il.Append(OpCodes.Ldc_I4_0);
            il.Append(OpCodes.Ldloc_2);
            il.Append(OpCodes.Ldlen);
            il.Append(OpCodes.Conv_I4);
            var readMethod =
                assembly.Import(typeof (Stream).GetMethod("Read", new[] {typeof (byte[]), typeof (int), typeof (int)}));
            il.Append(il.Create(OpCodes.Callvirt, readMethod));

            //Get the result
            il.Append(OpCodes.Pop);
            il.Append(OpCodes.Ldloc_2);
            //Convert it to base 64
            var base64String = assembly.Import(typeof (Convert).GetMethod("ToBase64String", new[] {typeof (byte[])}));
            il.Append(il.Create(OpCodes.Call, base64String));
            //Get the result
            il.Append(OpCodes.Stloc_0);
            il.Append(OpCodes.Nop);
            
            //Read the assembly
            var startReadAssembly = il.Create(OpCodes.Nop);
            il.Append(il.Create(OpCodes.Leave_S, startReadAssembly));
            
            //Dispose of appropriately
            var try1End = il.Create(OpCodes.Ldloc_1);
            il.Append(try1End);
            il.Append(OpCodes.Ldnull);
            il.Append(OpCodes.Ceq);
            il.Append(il.Create(OpCodes.Stloc_S, tempBool));
            il.Append(il.Create(OpCodes.Ldloc_S, tempBool));
            var endFinally1 = il.Create(OpCodes.Endfinally);
            il.Append(il.Create(OpCodes.Brtrue_S, endFinally1));
            il.Append(OpCodes.Ldloc_1);
            //Dispose
            var disposeMethod = assembly.Import(typeof (IDisposable).GetMethod("Dispose"));
            il.Append(il.Create(OpCodes.Callvirt, disposeMethod));
            il.Append(OpCodes.Nop);
            il.Append(endFinally1);
            
            //Start the read assembly
            il.Append(startReadAssembly);
            il.Append(OpCodes.Ldarg_0);
            il.Append(il.Create(OpCodes.Ldfld, executingAssembly));
            il.Append(OpCodes.Ldarg_1);
            il.Append(il.Create(OpCodes.Callvirt, getManifest));
            il.Append(OpCodes.Stloc_1);
            var try2Start = il.Create(OpCodes.Nop);
            il.Append(try2Start);
            il.Append(OpCodes.Ldloc_1);
            il.Append(OpCodes.Ldnull);
            il.Append(OpCodes.Ceq);
            il.Append(OpCodes.Ldc_I4_0);
            il.Append(OpCodes.Ceq);
            il.Append(il.Create(OpCodes.Stloc_S, tempBool));
            il.Append(il.Create(OpCodes.Ldloc_S, tempBool));
            //Check if it is null
            var startReadAssembly2 = il.Create(OpCodes.Ldloc_1);
            il.Append(il.Create(OpCodes.Brtrue_S, startReadAssembly2));
            il.Append(OpCodes.Ldnull);
            il.Append(il.Create(OpCodes.Stloc_S, tempAssembly));
            il.Append(il.Create(OpCodes.Leave, returnSequence)); //Leave as in try
            //Read the assembly
            il.Append(startReadAssembly2);
            il.Append(il.Create(OpCodes.Callvirt, getLength));
            il.Append(OpCodes.Conv_Ovf_I);
            il.Append(il.Create(OpCodes.Newarr, assembly.Import(typeof(byte))));
            //Now read it in
            il.Append(OpCodes.Stloc_3);
            il.Append(OpCodes.Ldloc_1);
            il.Append(OpCodes.Ldloc_3);
            il.Append(OpCodes.Ldc_I4_0);
            il.Append(OpCodes.Ldloc_3);
            il.Append(OpCodes.Ldlen);
            il.Append(OpCodes.Conv_I4);
            il.Append(il.Create(OpCodes.Callvirt, readMethod));

            //Get the result and clean up
            il.Append(OpCodes.Pop);
            il.Append(OpCodes.Nop);

            var startCheck = il.Create(OpCodes.Nop);
            il.Append(il.Create(OpCodes.Leave_S, startCheck));
            var try2End = il.Create(OpCodes.Ldloc_1);
            il.Append(try2End);
            il.Append(OpCodes.Ldnull);
            il.Append(OpCodes.Ceq);
            il.Append(il.Create(OpCodes.Stloc_S, tempBool));
            il.Append(il.Create(OpCodes.Ldloc_S, tempBool));
            var endFinally2 = il.Create(OpCodes.Endfinally);
            il.Append(il.Create(OpCodes.Brtrue_S, endFinally2));
            il.Append(OpCodes.Ldloc_1);
            //Dispose
            il.Append(il.Create(OpCodes.Callvirt, disposeMethod)); 
            il.Append(OpCodes.Nop);
            il.Append(endFinally2);
            il.Append(startCheck);

            //We need to load in both the salt, and the password key
            il.Append(il.Create(OpCodes.Ldstr, passwordKey));
            il.Append(il.Create(OpCodes.Ldstr, Convert.ToBase64String(salt.ToByteArray())));
            var fromBase64String = assembly.Import(typeof (Convert).GetMethod("FromBase64String"));
            il.Append(il.Create(OpCodes.Call, fromBase64String));
            //Set these into an rfc 2898 object
            il.Append(OpCodes.Ldc_I4_2);
            //RFC2898 ctor
            var rfcCtor =
                assembly.Import(
                    typeof (Rfc2898DeriveBytes).GetConstructor(new[] {typeof (string), typeof (byte[]), typeof (int)}));
            il.Append(il.Create(OpCodes.Newobj, rfcCtor));
            //Store this object
            il.Append(il.Create(OpCodes.Stloc_S, password));

            //Get the key bytes
            il.Append(il.Create(OpCodes.Ldloc_S, password));
            il.Append(il.Create(OpCodes.Ldc_I4_S, (sbyte)0x20));
            var getBytes = assembly.Import(typeof (DeriveBytes).GetMethod("GetBytes", new[] {typeof (int)}));
            il.Append(il.Create(OpCodes.Callvirt, getBytes));
            il.Append(il.Create(OpCodes.Stloc_S, keyBytes));

            //Init vector
            il.Append(il.Create(OpCodes.Ldloc_S, password));
            il.Append(il.Create(OpCodes.Ldc_I4_S, (sbyte)0x10));
            il.Append(il.Create(OpCodes.Callvirt, getBytes));
            il.Append(il.Create(OpCodes.Stloc_S, initVector));

            //Now decrypt the data
            il.Append(OpCodes.Ldloc_3);
            il.Append(il.Create(OpCodes.Ldloc_S, keyBytes));
            il.Append(il.Create(OpCodes.Ldloc_S, initVector));
            il.Append(il.Create(OpCodes.Call, decryptData));
            il.Append(il.Create(OpCodes.Stloc_S, rawAssembly));

            //Get the "real" hash
            il.Append(OpCodes.Ldloc_0);
            il.Append(il.Create(OpCodes.Ldloc_S, rawAssembly));
            il.Append(il.Create(OpCodes.Call, hashData));
            //Run the inequality operator
            var inequality =
                assembly.Import(typeof (String).GetMethod("op_Inequality", new[] {typeof (string), typeof (string)}));
            il.Append(il.Create(OpCodes.Call, inequality));
            il.Append(OpCodes.Ldc_I4_0);
            il.Append(OpCodes.Ceq);
            il.Append(il.Create(OpCodes.Stloc_S, tempBool));
            il.Append(il.Create(OpCodes.Ldloc_S, tempBool));

            //Return null if it's not a match
            var startLoadAssembly = il.Create(OpCodes.Ldloc_S, rawAssembly);
            il.Append(il.Create(OpCodes.Brtrue_S, startLoadAssembly));
            il.Append(OpCodes.Ldnull);
            il.Append(il.Create(OpCodes.Stloc_S, tempAssembly));
            il.Append(il.Create(OpCodes.Br_S, returnSequence));
            il.Append(startLoadAssembly);

            var assemblyLoad = assembly.Import(typeof (Assembly).GetMethod("Load", new[] {typeof (byte[])}));
            il.Append(il.Create(OpCodes.Call, assemblyLoad));
            il.Append(il.Create(OpCodes.Stloc_S, actualAssembly));
            
            //Check if it is null
            il.Append(il.Create(OpCodes.Ldloc_S, actualAssembly));
            il.Append(OpCodes.Ldnull);
            il.Append(OpCodes.Ceq);
            il.Append(OpCodes.Ldc_I4_0);
            il.Append(OpCodes.Ceq);
            il.Append(il.Create(OpCodes.Stloc_S, tempBool));
            il.Append(il.Create(OpCodes.Ldloc_S, tempBool));
            var startCache = il.Create(OpCodes.Ldarg_0);
            il.Append(il.Create(OpCodes.Brtrue_S, startCache));
            il.Append(OpCodes.Ldnull);
            il.Append(il.Create(OpCodes.Stloc_S, tempAssembly));
            il.Append(il.Create(OpCodes.Br_S, returnSequence));

            //Cache before returning
            il.Append(startCache);
            il.Append(il.Create(OpCodes.Ldfld, loadedAssemblies));
            il.Append(OpCodes.Ldarg_1);
            il.Append(il.Create(OpCodes.Ldloc_S, actualAssembly));
            var addMethod = assembly.Import(typeof (Dictionary<string, Assembly>).GetMethod("Add"));            
            il.Append(il.Create(OpCodes.Callvirt, addMethod));
            il.Append(OpCodes.Nop);
            //Move it to our temp return var
            il.Append(il.Create(OpCodes.Ldloc_S, actualAssembly));
            il.Append(il.Create(OpCodes.Stloc_S, tempAssembly));
            il.Append(il.Create(OpCodes.Br_S, returnSequence)); //Need this?
            //Return sequence
            il.Append(returnSequence);
#if VERBOSE_OUTPUT
            DebugLine(assembly, il, "Successfully loaded");
#endif
            /*
            il.Append(il.Create(OpCodes.Ldstr, "Load assembly "));
            il.Append(OpCodes.Ldarg_1);
            il.Append(il.Create(OpCodes.Call, concat));
            il.Append(OpCodes.Stloc_0);
            il.Append(OpCodes.Ldloc_0);
            var wl = assembly.Import(typeof(Console).GetMethod("WriteLine", new[] { typeof(string) }));
            il.Append(il.Create(OpCodes.Call, wl));
             */

            il.Append(il.Create(OpCodes.Ldloc_S, tempAssembly));
            il.Append(OpCodes.Ret);

            //Last but not least, add our try/finally's (i.e. usings)
            ExceptionHandler finally1 = new ExceptionHandler(ExceptionHandlerType.Finally);
            finally1.TryStart = try1Start;
            finally1.TryEnd = try1End;
            finally1.HandlerStart = try1End;
            finally1.HandlerEnd = startReadAssembly;
            method.Body.ExceptionHandlers.Add(finally1);
            ExceptionHandler finally2 = new ExceptionHandler(ExceptionHandlerType.Finally);
            finally2.TryStart = try2Start;
            finally2.TryEnd = try2End;
            finally2.HandlerStart = try2End;
            finally2.HandlerEnd = startCheck;
            method.Body.ExceptionHandlers.Add(finally2);
            return method;
        }
Ejemplo n.º 34
0
        /// <summary>
        /// Processes the assembly - goes through each member and applies a mapping.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="definition">The assembly definition.</param>
        private static void ProcessAssembly(ICloakContext context, AssemblyDefinition definition)
        {
            //Store whether to obfuscate all members
            bool obfuscateAll = context.Settings.ObfuscateAllModifiers;

            //Set up the mapping graph
            AssemblyMapping assemblyMapping = context.MappingGraph.AddAssembly(definition);

            //Get a reference to the name manager
            NameManager nameManager = context.NameManager;

            //Go through each module
            foreach (ModuleDefinition moduleDefinition in definition.Modules)
            {
                //Go through each type
                foreach (TypeDefinition typeDefinition in moduleDefinition.GetAllTypes())
                {
                    //First of all - see if we've declared it already - if so get the existing reference
                    TypeMapping typeMapping = assemblyMapping.GetTypeMapping(typeDefinition);
                    if (typeMapping == null)
                    {
                        //We don't have it - get it
                        if (obfuscateAll)
                        {
                            typeMapping = assemblyMapping.AddType(typeDefinition,
                                                                  nameManager.GenerateName(NamingTable.Type));
                        }
                        else
                        {
                            typeMapping = assemblyMapping.AddType(typeDefinition, null);
                        }
                    }

                    //Go through each method
                    foreach (MethodDefinition methodDefinition in typeDefinition.Methods)
                    {
                        //First of all - check if we've obfuscated it already - if we have then don't bother
                        if (typeMapping.HasMethodBeenObfuscated(methodDefinition.Name))
                        {
                            continue;
                        }

                        //We won't do constructors - causes issues
                        if (methodDefinition.IsConstructor)
                        {
                            continue;
                        }

                        //We haven't - let's work out the obfuscated name
                        if (obfuscateAll)
                        {
                            //Take into account whether this is overriden, or an interface implementation
                            if (methodDefinition.IsVirtual)
                            {
                                //We handle this differently - rather than creating a new name each time we need to reuse any already generated names
                                //We do this by firstly finding the root interface or object
                                TypeDefinition baseType = FindBaseTypeDeclaration(typeDefinition, methodDefinition);
                                if (baseType != null)
                                {
                                    //Find it in the mappings
                                    TypeMapping baseTypeMapping = assemblyMapping.GetTypeMapping(baseType);
                                    if (baseTypeMapping != null)
                                    {
                                        //We found the type mapping - look up the name it uses for this method and use that
                                        if (baseTypeMapping.HasMethodMapping(methodDefinition))
                                        {
                                            typeMapping.AddMethodMapping(methodDefinition, baseTypeMapping.GetObfuscatedMethodName(methodDefinition));
                                        }
                                        else
                                        {
                                            //That's strange... we shouldn't get into here - but if we ever do then
                                            //we'll add the type mapping into both
                                            string obfuscatedName = nameManager.GenerateName(NamingTable.Method);
                                            typeMapping.AddMethodMapping(methodDefinition, obfuscatedName);
                                            baseTypeMapping.AddMethodMapping(methodDefinition, obfuscatedName);
                                        }
                                    }
                                    else
                                    {
                                        //Otherwise add it into our list manually
                                        //at the base level first off
                                        baseTypeMapping = assemblyMapping.AddType(baseType,
                                                                                  nameManager.GenerateName(NamingTable.Type));
                                        string obfuscatedName = nameManager.GenerateName(NamingTable.Method);
                                        baseTypeMapping.AddMethodMapping(methodDefinition, obfuscatedName);
                                        //Now at our implemented level
                                        typeMapping.AddMethodMapping(methodDefinition, obfuscatedName);
                                    }
                                }
                                else
                                {
                                    //We must be at the base already - add normally
                                    typeMapping.AddMethodMapping(methodDefinition,
                                                                 nameManager.GenerateName(NamingTable.Method));
                                }
                            }
                            else //Add normally
                            {
                                typeMapping.AddMethodMapping(methodDefinition,
                                                             nameManager.GenerateName(NamingTable.Method));
                            }
                        }
                        else if (methodDefinition.IsPrivate)
                        {
                            typeMapping.AddMethodMapping(methodDefinition, nameManager.GenerateName(NamingTable.Method));
                        }
                    }

                    //Properties
                    foreach (PropertyDefinition propertyDefinition in typeDefinition.Properties)
                    {
                        //First of all - check if we've obfuscated it already - if we have then don't bother
                        if (typeMapping.HasPropertyBeenObfuscated(propertyDefinition.Name))
                        {
                            continue;
                        }

                        //Go through the old fashioned way
                        if (obfuscateAll)
                        {
                            if ((propertyDefinition.GetMethod != null && propertyDefinition.GetMethod.IsVirtual) ||
                                (propertyDefinition.SetMethod != null && propertyDefinition.SetMethod.IsVirtual))
                            {
                                //We handle this differently - rather than creating a new name each time we need to reuse any already generated names
                                //We do this by firstly finding the root interface or object
                                TypeDefinition baseType = FindBaseTypeDeclaration(typeDefinition, propertyDefinition);
                                if (baseType != null)
                                {
                                    //Find it in the mappings
                                    TypeMapping baseTypeMapping = assemblyMapping.GetTypeMapping(baseType);
                                    if (baseTypeMapping != null)
                                    {
                                        //We found the type mapping - look up the name it uses for this property and use that
                                        if (baseTypeMapping.HasPropertyMapping(propertyDefinition))
                                        {
                                            typeMapping.AddPropertyMapping(propertyDefinition, baseTypeMapping.GetObfuscatedPropertyName(propertyDefinition));
                                        }
                                        else
                                        {
                                            //That's strange... we shouldn't get into here - but if we ever do then
                                            //we'll add the type mapping into both
                                            string obfuscatedName = nameManager.GenerateName(NamingTable.Property);
                                            typeMapping.AddPropertyMapping(propertyDefinition, obfuscatedName);
                                            baseTypeMapping.AddPropertyMapping(propertyDefinition, obfuscatedName);
                                        }
                                    }
                                    else
                                    {
                                        //Otherwise add it into our list manually
                                        //at the base level first off
                                        baseTypeMapping = assemblyMapping.AddType(baseType,
                                                                                  nameManager.GenerateName(NamingTable.Type));
                                        string obfuscatedName = nameManager.GenerateName(NamingTable.Property);
                                        baseTypeMapping.AddPropertyMapping(propertyDefinition, obfuscatedName);
                                        //Now at our implemented level
                                        typeMapping.AddPropertyMapping(propertyDefinition, obfuscatedName);
                                    }
                                }
                                else
                                {
                                    //We must be at the base already - add normally
                                    typeMapping.AddPropertyMapping(propertyDefinition,
                                                                   nameManager.GenerateName(NamingTable.Property));
                                }
                            }
                            else
                            {
                                typeMapping.AddPropertyMapping(propertyDefinition,
                                                               nameManager.GenerateName(NamingTable.Property));
                            }
                        }
                        else if (propertyDefinition.GetMethod != null && propertyDefinition.SetMethod != null)
                        {
                            //Both parts need to be private
                            if (propertyDefinition.GetMethod.IsPrivate && propertyDefinition.SetMethod.IsPrivate)
                            {
                                typeMapping.AddPropertyMapping(propertyDefinition, nameManager.GenerateName(NamingTable.Property));
                            }
                        }
                        else if (propertyDefinition.GetMethod != null)
                        {
                            //Only the get is present - make sure it is private
                            if (propertyDefinition.GetMethod.IsPrivate)
                            {
                                typeMapping.AddPropertyMapping(propertyDefinition, nameManager.GenerateName(NamingTable.Property));
                            }
                        }
                        else if (propertyDefinition.SetMethod != null)
                        {
                            //Only the set is present - make sure it is private
                            if (propertyDefinition.SetMethod.IsPrivate)
                            {
                                typeMapping.AddPropertyMapping(propertyDefinition, nameManager.GenerateName(NamingTable.Property));
                            }
                        }
                    }

                    //Fields
                    foreach (FieldDefinition fieldDefinition in typeDefinition.Fields)
                    {
                        //First of all - check if we've obfuscated it already - if we have then don't bother
                        if (typeMapping.HasFieldBeenObfuscated(fieldDefinition.Name))
                        {
                            continue;
                        }

                        if (obfuscateAll)
                        {
                            typeMapping.AddFieldMapping(fieldDefinition, nameManager.GenerateName(NamingTable.Field));
                        }
                        else if (fieldDefinition.IsPrivate)
                        {
                            //Rename if private
                            typeMapping.AddFieldMapping(fieldDefinition, nameManager.GenerateName(NamingTable.Field));
                        }
                    }
                }
            }
        }
Ejemplo n.º 35
0
        /// <summary>
        /// Builds the start method.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="assembly">The assembly.</param>
        /// <param name="executingAssembly">The executing assembly.</param>
        /// <param name="assembliesLoaded">The assemblies loaded.</param>
        /// <param name="loadType">Type of the load.</param>
        /// <param name="loadAssemblies">The load assemblies.</param>
        /// <returns></returns>
        private static MethodDefinition BuildStartMethod(ICloakContext context, AssemblyDefinition assembly, FieldReference executingAssembly, FieldReference assembliesLoaded, MethodReference loadType, MethodReference loadAssemblies)
        {
#if USE_FRIENDLY_NAMING
            MethodDefinition method = new MethodDefinition("Start",
                       MethodAttributes.Public | MethodAttributes.HideBySig, assembly.Import(typeof(void)));
#else
            MethodDefinition method = new MethodDefinition(context.NameManager.GenerateName(NamingTable.Method),
                                   MethodAttributes.Public | MethodAttributes.HideBySig, assembly.Import(typeof(void)));
#endif

            method.Body.InitLocals = true;
            method.Body.MaxStackSize = 3;
            method.AddLocal(assembly, typeof(string));   //entryAssemblyResource
            method.AddLocal(assembly, typeof(string));   //entryType
            method.AddLocal(assembly, typeof(string));   //entryMethod
            method.AddLocal(assembly, typeof(string));   //resourceName
            var s = method.AddLocal(assembly, typeof(Stream));   //s
            var sr = method.AddLocal(assembly, typeof(StreamReader));   //sr
            var type = method.AddLocal(assembly, typeof(Type));   //type
            var methodInfo = method.AddLocal(assembly, typeof(MethodInfo));   //method
            var tempStringArray = method.AddLocal(assembly, typeof (string[]));
            var tempInt = method.AddLocal(assembly, typeof(int));
            var tempBool = method.AddLocal(assembly, typeof(bool));

            //Get the il builder
            var il = method.Body.GetILProcessor();

            //Inject the anti reflector code
            InjectAntiReflectorCode(il, il.Create(OpCodes.Nop));

            //Start it off - declare some variables
            il.Append(OpCodes.Ldnull);
            il.Append(OpCodes.Stloc_0);
            il.Append(OpCodes.Ldnull);
            il.Append(OpCodes.Stloc_1);
            il.Append(OpCodes.Ldnull);
            il.Append(OpCodes.Stloc_2);
            il.Append(OpCodes.Nop);
            il.Append(OpCodes.Ldarg_0);

            //We need to find the entry point so start a loop to find
            il.Append(il.Create(OpCodes.Ldfld, executingAssembly));
            var getManifestResourceNames = assembly.Import(typeof (Assembly).GetMethod("GetManifestResourceNames"));
            il.Append(il.Create(OpCodes.Callvirt, getManifestResourceNames));
            il.Append(il.Create(OpCodes.Stloc_S, tempStringArray));

            //Init the loop counter
            il.Append(OpCodes.Ldc_I4_0);
            il.Append(il.Create(OpCodes.Stloc_S, tempInt));
            //Jump to the loop comparison
            var startLoopComparison = il.Create(OpCodes.Ldloc_S, tempInt);
            il.Append(il.Create(OpCodes.Br, startLoopComparison));

            //Load the current item in a temp variable
            var getTempVar = il.Create(OpCodes.Ldloc_S, tempStringArray);
            il.Append(getTempVar);
            il.Append(il.Create(OpCodes.Ldloc_S, tempInt));
            il.Append(OpCodes.Ldelem_Ref);
            il.Append(OpCodes.Stloc_3);

            //Now start the actual body
            il.Append(OpCodes.Nop);
            il.Append(OpCodes.Ldloc_3);
            il.Append(il.Create(OpCodes.Ldstr, ".e"));
            var endsWith = assembly.Import(typeof (String).GetMethod("EndsWith", new[] {typeof (string)}));
            il.Append(il.Create(OpCodes.Callvirt, endsWith));
            il.Append(OpCodes.Ldc_I4_0); 
            il.Append(OpCodes.Ceq);
            il.Append(il.Create(OpCodes.Stloc_S, tempBool));
            il.Append(il.Create(OpCodes.Ldloc_S, tempBool));

            //Branch to increment statement if not true (i.e. equal to 0/false)
            var startIncrement = il.Create(OpCodes.Nop);
            il.Append(il.Create(OpCodes.Brtrue, startIncrement));
            //Get the stream
            il.Append(OpCodes.Nop);
            il.Append(OpCodes.Ldarg_0);
            il.Append(il.Create(OpCodes.Ldfld, executingAssembly));
            il.Append(OpCodes.Ldloc_3);
            var getManifestResourceStream =
                assembly.Import(typeof (Assembly).GetMethod("GetManifestResourceStream", new[] {typeof (string)}));
            il.Append(il.Create(OpCodes.Callvirt, getManifestResourceStream));
            il.Append(il.Create(OpCodes.Stloc_S, s));
            //Make sure it's not null
            il.Append(il.Create(OpCodes.Ldloc_S, s));
            il.Append(OpCodes.Ldnull);
            il.Append(OpCodes.Ceq);
            il.Append(OpCodes.Ldc_I4_0);
            il.Append(OpCodes.Ceq);
            il.Append(il.Create(OpCodes.Stloc_S, tempBool));
            il.Append(il.Create(OpCodes.Ldloc_S, tempBool));
            //Branch to read it if necessary
            var startUnpack = il.Create(OpCodes.Ldloc_S, s);
            il.Append(il.Create(OpCodes.Brtrue_S, startUnpack));
            var startIncrement2 = il.Create(OpCodes.Ldloc_S, tempInt);
            il.Append(il.Create(OpCodes.Br_S, startIncrement2));
            il.Append(startUnpack);
            //It's all in unicode
            var unicode = assembly.Import(typeof (Encoding).GetProperty("Unicode").GetGetMethod());
            il.Append(il.Create(OpCodes.Call, unicode));
            //Create a new stream reader to read it
            var streamReaderCtor =
                assembly.Import(typeof (StreamReader).GetConstructor(new[] {typeof (Stream), typeof (Encoding)}));
            il.Append(il.Create(OpCodes.Newobj, streamReaderCtor));
            il.Append(il.Create(OpCodes.Stloc_S, sr));

            //Try start
            var tryStart = il.Create(OpCodes.Nop);
            il.Append(tryStart);

            //Load the current bootstrapper namespace
            //il.Append(il.Create(OpCodes.Ldstr, resourceNamespace + "."));
            il.Append(il.Create(OpCodes.Ldloc_S, sr));
            //Read in a line or two
            var readLine = assembly.Import(typeof (TextReader).GetMethod("ReadLine"));
            il.Append(il.Create(OpCodes.Callvirt, readLine));
            //Joing the strings
            //var stringConcat =
            //    assembly.Import(typeof (String).GetMethod("Concat", new[] {typeof (string), typeof (string)}));
            //il.Append(il.Create(OpCodes.Call, stringConcat));
            il.Append(OpCodes.Stloc_0);
            il.Append(il.Create(OpCodes.Ldloc_S, sr));
            il.Append(il.Create(OpCodes.Callvirt, readLine));
            il.Append(OpCodes.Stloc_1);
            il.Append(il.Create(OpCodes.Ldloc_S, sr));
            il.Append(il.Create(OpCodes.Callvirt, readLine));
            il.Append(OpCodes.Stloc_2);

            //HACK - load all assemblies here
            il.Append(OpCodes.Ldarg_0);
            il.Append(OpCodes.Ldc_I4_1);
            il.Append(il.Create(OpCodes.Stfld, assembliesLoaded));
            il.Append(OpCodes.Ldarg_0);
            il.Append(il.Create(OpCodes.Call, loadAssemblies));
            //END HACK

            il.Append(OpCodes.Nop);

            var afterFinally = il.Create(OpCodes.Nop);
            il.Append(il.Create(OpCodes.Leave_S, afterFinally));
            var tryEnd = il.Create(OpCodes.Ldloc_S, sr);
            il.Append(tryEnd);
            il.Append(OpCodes.Ldnull);
            il.Append(OpCodes.Ceq);
            il.Append(il.Create(OpCodes.Stloc_S, tempBool));
            il.Append(il.Create(OpCodes.Ldloc_S, tempBool));
            var endFinally = il.Create(OpCodes.Endfinally);
            il.Append(il.Create(OpCodes.Brtrue_S, endFinally));
            il.Append(il.Create(OpCodes.Ldloc_S, sr));
            //dispose it
            var dispose = assembly.Import(typeof (IDisposable).GetMethod("Dispose"));
            il.Append(il.Create(OpCodes.Callvirt, dispose));
            il.Append(OpCodes.Nop);
            il.Append(endFinally);
            il.Append(afterFinally);

            //Make sure nothing is null
            il.Append(OpCodes.Ldloc_0);
            var isNullOrEmpty = assembly.Import(typeof (string).GetMethod("IsNullOrEmpty", new[] {typeof (string)}));
            il.Append(il.Create(OpCodes.Call, isNullOrEmpty));
            var exitCheck = il.Create(OpCodes.Ldc_I4_1);
            il.Append(il.Create(OpCodes.Brtrue_S, exitCheck));
            il.Append(OpCodes.Ldloc_1);
            il.Append(il.Create(OpCodes.Call, isNullOrEmpty));
            il.Append(il.Create(OpCodes.Brtrue_S, exitCheck));
            il.Append(OpCodes.Ldloc_2);
            il.Append(il.Create(OpCodes.Call, isNullOrEmpty));
            var doCheck = il.Create(OpCodes.Stloc_S, tempBool);
            il.Append(il.Create(OpCodes.Br_S, doCheck));
            il.Append(exitCheck);
            il.Append(doCheck);
            il.Append(il.Create(OpCodes.Ldloc_S, tempBool));
            var startIncrement3 = il.Create(OpCodes.Nop);
            il.Append(il.Create(OpCodes.Brtrue_S, startIncrement3));

            //Jump to check if the entry exists
            var checkEntryExists = il.Create(OpCodes.Ldloc_0);
            il.Append(il.Create(OpCodes.Br_S, checkEntryExists));
            il.Append(startIncrement3);
            il.Append(startIncrement);
            il.Append(startIncrement2);
            il.Append(OpCodes.Ldc_I4_1);
            il.Append(OpCodes.Add);
            il.Append(il.Create(OpCodes.Stloc_S, tempInt));

            //Comparison
            il.Append(startLoopComparison);
            il.Append(il.Create(OpCodes.Ldloc_S, tempStringArray));
            il.Append(OpCodes.Ldlen);
            il.Append(OpCodes.Conv_I4);
            il.Append(OpCodes.Clt);
            il.Append(il.Create(OpCodes.Stloc_S, tempBool));
            il.Append(il.Create(OpCodes.Ldloc_S, tempBool));
            il.Append(il.Create(OpCodes.Brtrue, getTempVar));

            //Check the entry exists to start the program
            il.Append(checkEntryExists);
            il.Append(il.Create(OpCodes.Call, isNullOrEmpty));
            var failedProgram = il.Create(OpCodes.Ldc_I4_0);
            il.Append(il.Create(OpCodes.Brtrue_S, failedProgram));
            il.Append(OpCodes.Ldloc_1);
            il.Append(il.Create(OpCodes.Call, isNullOrEmpty));
            il.Append(il.Create(OpCodes.Brtrue_S, failedProgram));
            il.Append(OpCodes.Ldloc_2);
            il.Append(il.Create(OpCodes.Call, isNullOrEmpty));
            il.Append(OpCodes.Ldc_I4_0);
            il.Append(OpCodes.Ceq);
            var checkIfShouldStart = il.Create(OpCodes.Stloc_S, tempBool);
            il.Append(il.Create(OpCodes.Br_S, checkIfShouldStart));
            il.Append(failedProgram);
            il.Append(checkIfShouldStart);

            il.Append(il.Create(OpCodes.Ldloc_S, tempBool));
            var startLoad = il.Create(OpCodes.Ldarg_0);
            il.Append(il.Create(OpCodes.Brtrue_S, startLoad));
            var ret = il.Create(OpCodes.Ret);
            il.Append(il.Create(OpCodes.Br_S, ret));

            //Start the load type
            il.Append(startLoad);
            il.Append(OpCodes.Ldloc_0);
            il.Append(OpCodes.Ldloc_1);
            il.Append(il.Create(OpCodes.Call, loadType));
            il.Append(il.Create(OpCodes.Stloc_S, type));

#if VERBOSE_OUTPUT
            DebugLine(assembly, il, "Loading type: ", il.Create(OpCodes.Ldloc_0), il.Create(OpCodes.Ldloc_1));
#endif
            //Check it was found
            il.Append(il.Create(OpCodes.Ldloc_S, type));
            il.Append(OpCodes.Ldnull);
            il.Append(OpCodes.Ceq);
            il.Append(OpCodes.Ldc_I4_0);
            il.Append(OpCodes.Ceq);
            il.Append(il.Create(OpCodes.Stloc_S, tempBool));
            il.Append(il.Create(OpCodes.Ldloc_S, tempBool));
            var startFindMethod = il.Create(OpCodes.Ldloc_S, type);
            il.Append(il.Create(OpCodes.Brtrue_S, startFindMethod));
            il.Append(il.Create(OpCodes.Br_S, ret));
            il.Append(startFindMethod);
            il.Append(OpCodes.Ldloc_2);
            il.Append(il.Create(OpCodes.Ldc_I4_S, (sbyte)0x38));
            var getMethod =
                assembly.Import(typeof (Type).GetMethod("GetMethod", new[] {typeof (string), typeof (BindingFlags)}));
            il.Append(il.Create(OpCodes.Callvirt, getMethod));
            il.Append(il.Create(OpCodes.Stloc_S, methodInfo));
#if VERBOSE_OUTPUT
            DebugLine(assembly, il, "Get Method has been called");
#endif

            
            //Check it isn't null
            il.Append(il.Create(OpCodes.Ldloc_S, methodInfo));
            il.Append(OpCodes.Ldnull);
            il.Append(OpCodes.Ceq);
            il.Append(OpCodes.Ldc_I4_0);
            il.Append(OpCodes.Ceq);
            il.Append(il.Create(OpCodes.Stloc_S, tempBool));
            il.Append(il.Create(OpCodes.Ldloc_S, tempBool));
            var invokeMethodBlock = il.Create(OpCodes.Ldloc_S, methodInfo);
            il.Append(il.Create(OpCodes.Brtrue_S, invokeMethodBlock));
            il.Append(il.Create(OpCodes.Br_S, ret));
            
            //Invoke the method
            il.Append(invokeMethodBlock);
            il.Append(OpCodes.Ldnull);
            il.Append(OpCodes.Ldnull);
            var invoke =
                assembly.Import(typeof (MethodBase).GetMethod("Invoke", new[] {typeof (object), typeof (object[])}));
            il.Append(il.Create(OpCodes.Callvirt, invoke));
            il.Append(OpCodes.Pop);
#if VERBOSE_OUTPUT
            DebugLine(assembly, il, "Invoke called");
#endif
            il.Append(ret);

            //Try/Finally
            ExceptionHandler finallyBlock = new ExceptionHandler(ExceptionHandlerType.Finally);
            finallyBlock.TryStart = tryStart;
            finallyBlock.TryEnd = tryEnd;
            finallyBlock.HandlerStart = tryEnd;
            finallyBlock.HandlerEnd = afterFinally;
            method.Body.ExceptionHandlers.Add(finallyBlock);
            return method;
        }
Ejemplo n.º 36
0
        /// <summary>
        /// Processes the assembly - goes through each member and applies a mapping.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="definition">The assembly definition.</param>
        private static void ProcessAssembly(ICloakContext context, AssemblyDefinition definition)
        {
            //Store whether to obfuscate all members
            bool obfuscateAll = context.Settings.ObfuscateAllModifiers;

            //Set up the mapping graph
            AssemblyMapping assemblyMapping = context.MappingGraph.AddAssembly(definition);

            //Get a reference to the name manager
            NameManager nameManager = context.NameManager;

            //Go through each module
            foreach (ModuleDefinition moduleDefinition in definition.Modules)
            {
                //Go through each type
                foreach (TypeDefinition typeDefinition in moduleDefinition.GetAllTypes())
                {
                    //First of all - see if we've declared it already - if so get the existing reference
                    TypeMapping typeMapping = assemblyMapping.GetTypeMapping(typeDefinition);
                    if (typeMapping == null)
                    {
                        //We don't have it - get it
                        if (obfuscateAll)
                            typeMapping = assemblyMapping.AddType(typeDefinition,
                                                                  nameManager.GenerateName(NamingTable.Type));
                        else
                            typeMapping = assemblyMapping.AddType(typeDefinition, null);
                    }

                    //Go through each method
                    foreach (MethodDefinition methodDefinition in typeDefinition.Methods)
                    {
                        //First of all - check if we've obfuscated it already - if we have then don't bother
                        if (typeMapping.HasMethodBeenObfuscated(methodDefinition.Name))
                            continue;

                        //We won't do constructors - causes issues
                        if (methodDefinition.IsConstructor)
                            continue;

                        //We haven't - let's work out the obfuscated name
                        if (obfuscateAll)
                        {
                            //Take into account whether this is overriden, or an interface implementation
                            if (methodDefinition.IsVirtual)
                            {
                                //We handle this differently - rather than creating a new name each time we need to reuse any already generated names
                                //We do this by firstly finding the root interface or object
                                TypeDefinition baseType = FindBaseTypeDeclaration(typeDefinition, methodDefinition);
                                if (baseType != null)
                                {
                                    //Find it in the mappings 
                                    TypeMapping baseTypeMapping = assemblyMapping.GetTypeMapping(baseType);
                                    if (baseTypeMapping != null)
                                    {
                                        //We found the type mapping - look up the name it uses for this method and use that
                                        if (baseTypeMapping.HasMethodMapping(methodDefinition))
                                            typeMapping.AddMethodMapping(methodDefinition, baseTypeMapping.GetObfuscatedMethodName(methodDefinition));
                                        else
                                        {
                                            //That's strange... we shouldn't get into here - but if we ever do then
                                            //we'll add the type mapping into both
                                            string obfuscatedName = nameManager.GenerateName(NamingTable.Method);
                                            typeMapping.AddMethodMapping(methodDefinition, obfuscatedName);
                                            baseTypeMapping.AddMethodMapping(methodDefinition, obfuscatedName);
                                        }
                                    }
                                    else
                                    {
                                        //Otherwise add it into our list manually
                                        //at the base level first off
                                        baseTypeMapping = assemblyMapping.AddType(baseType,
                                                                  nameManager.GenerateName(NamingTable.Type));
                                        string obfuscatedName = nameManager.GenerateName(NamingTable.Method);
                                        baseTypeMapping.AddMethodMapping(methodDefinition, obfuscatedName);
                                        //Now at our implemented level
                                        typeMapping.AddMethodMapping(methodDefinition, obfuscatedName);
                                    }
                                }
                                else
                                {
                                    //We must be at the base already - add normally
                                    typeMapping.AddMethodMapping(methodDefinition,
                                                         nameManager.GenerateName(NamingTable.Method));
                                }
                            }
                            else //Add normally
                                typeMapping.AddMethodMapping(methodDefinition,
                                                         nameManager.GenerateName(NamingTable.Method));
                        }
                        else if (methodDefinition.IsPrivate)
                            typeMapping.AddMethodMapping(methodDefinition, nameManager.GenerateName(NamingTable.Method));
                    }

                    //Properties
                    foreach (PropertyDefinition propertyDefinition in typeDefinition.Properties)
                    {
                        //First of all - check if we've obfuscated it already - if we have then don't bother
                        if (typeMapping.HasPropertyBeenObfuscated(propertyDefinition.Name))
                            continue;

                        //Go through the old fashioned way
                        if (obfuscateAll)
                        {
                            if ((propertyDefinition.GetMethod != null && propertyDefinition.GetMethod.IsVirtual) || 
                                (propertyDefinition.SetMethod != null && propertyDefinition.SetMethod.IsVirtual))
                            {
                                //We handle this differently - rather than creating a new name each time we need to reuse any already generated names
                                //We do this by firstly finding the root interface or object
                                TypeDefinition baseType = FindBaseTypeDeclaration(typeDefinition, propertyDefinition);
                                if (baseType != null)
                                {
                                    //Find it in the mappings 
                                    TypeMapping baseTypeMapping = assemblyMapping.GetTypeMapping(baseType);
                                    if (baseTypeMapping != null)
                                    {
                                        //We found the type mapping - look up the name it uses for this property and use that
                                        if (baseTypeMapping.HasPropertyMapping(propertyDefinition))
                                            typeMapping.AddPropertyMapping(propertyDefinition, baseTypeMapping.GetObfuscatedPropertyName(propertyDefinition));
                                        else
                                        {
                                            //That's strange... we shouldn't get into here - but if we ever do then
                                            //we'll add the type mapping into both
                                            string obfuscatedName = nameManager.GenerateName(NamingTable.Property);
                                            typeMapping.AddPropertyMapping(propertyDefinition, obfuscatedName);
                                            baseTypeMapping.AddPropertyMapping(propertyDefinition, obfuscatedName);
                                        }
                                    }
                                    else
                                    {
                                        //Otherwise add it into our list manually
                                        //at the base level first off
                                        baseTypeMapping = assemblyMapping.AddType(baseType,
                                                                  nameManager.GenerateName(NamingTable.Type));
                                        string obfuscatedName = nameManager.GenerateName(NamingTable.Property);
                                        baseTypeMapping.AddPropertyMapping(propertyDefinition, obfuscatedName);
                                        //Now at our implemented level
                                        typeMapping.AddPropertyMapping(propertyDefinition, obfuscatedName);
                                    }
                                }
                                else
                                {
                                    //We must be at the base already - add normally
                                    typeMapping.AddPropertyMapping(propertyDefinition,
                                                         nameManager.GenerateName(NamingTable.Property));
                                }
                            }
                            else
                                typeMapping.AddPropertyMapping(propertyDefinition,
                                                           nameManager.GenerateName(NamingTable.Property));
                        }
                        else if (propertyDefinition.GetMethod != null && propertyDefinition.SetMethod != null)
                        {
                            //Both parts need to be private
                            if (propertyDefinition.GetMethod.IsPrivate && propertyDefinition.SetMethod.IsPrivate)
                                typeMapping.AddPropertyMapping(propertyDefinition, nameManager.GenerateName(NamingTable.Property));
                        }
                        else if (propertyDefinition.GetMethod != null)
                        {
                            //Only the get is present - make sure it is private
                            if (propertyDefinition.GetMethod.IsPrivate)
                                typeMapping.AddPropertyMapping(propertyDefinition, nameManager.GenerateName(NamingTable.Property));
                        }
                        else if (propertyDefinition.SetMethod != null)
                        {
                            //Only the set is present - make sure it is private
                            if (propertyDefinition.SetMethod.IsPrivate)
                                typeMapping.AddPropertyMapping(propertyDefinition, nameManager.GenerateName(NamingTable.Property));
                        }
                    }

                    //Fields
                    foreach (FieldDefinition fieldDefinition in typeDefinition.Fields)
                    {
                        //First of all - check if we've obfuscated it already - if we have then don't bother
                        if (typeMapping.HasFieldBeenObfuscated(fieldDefinition.Name))
                            continue;

                        if (obfuscateAll)
                            typeMapping.AddFieldMapping(fieldDefinition, nameManager.GenerateName(NamingTable.Field));
                        else if (fieldDefinition.IsPrivate)
                        {
                            //Rename if private
                            typeMapping.AddFieldMapping(fieldDefinition, nameManager.GenerateName(NamingTable.Field));
                        }
                    }
                }
            }
        }
Ejemplo n.º 37
0
        /// <summary>
        /// Builds the main method.
        /// </summary>
        /// <param name="assembly">The assembly.</param>
        /// <param name="context">The context.</param>
        /// <param name="programType">Type of the program.</param>
        /// <param name="getExecutingAssembly">The get executing assembly.</param>
        /// <param name="currentDomain">The current domain.</param>
        /// <param name="eventHandler">The event handler.</param>
        /// <param name="assemblyResolve">The assembly resolve.</param>
        /// <param name="resolveMethod">The resolve method.</param>
        /// <param name="startMethod">The start method.</param>
        /// <returns></returns>
        private static MethodDefinition BuildMainMethod(AssemblyDefinition assembly, ICloakContext context, TypeDefinition programType, MethodReference getExecutingAssembly, MethodReference currentDomain, MethodReference eventHandler, MethodReference assemblyResolve, MethodReference resolveMethod, MethodReference startMethod)
        {
#if USE_FRIENDLY_NAMING
            MethodDefinition entryPoint =
                new MethodDefinition("Main",
                                     MethodAttributes.Private | MethodAttributes.Static |
                                     MethodAttributes.HideBySig, assembly.Import(typeof(void)));
#else
            MethodDefinition entryPoint =
                new MethodDefinition(context.NameManager.GenerateName(NamingTable.Method),
                                     MethodAttributes.Private | MethodAttributes.Static |
                                     MethodAttributes.HideBySig, assembly.Import(typeof(void)));
#endif
            entryPoint.Body.InitLocals = true;
            entryPoint.Body.MaxStackSize = 4;

#if USE_APPDOMAIN
            //Initialise some locals
            entryPoint.AddLocal(assembly, typeof(AppDomain));
            entryPoint.AddLocal(assembly, typeof(Assembly));
#endif
            VariableDefinition result = new VariableDefinition(programType);
            entryPoint.Body.Variables.Add(result);

            //Add the method
            assembly.EntryPoint = entryPoint;

            //Declare the il to build the code
            ILProcessor il = entryPoint.Body.GetILProcessor();

            //First of all add the anti reflector code
            InjectAntiReflectorCode(il, il.Create(OpCodes.Nop));

            //Now output the code - essentially:
            /*
            AppDomain domain = AppDomain.CreateDomain("App");
            Assembly executingAssembly = Assembly.GetExecutingAssembly();
            ProgramRunner runner = (ProgramRunner)domain.CreateInstanceAndUnwrap(executingAssembly.FullName, "TestBootstrapper.ProgramRunner");
            AppDomain.CurrentDomain.AssemblyResolve += runner.ResolveAssembly;
            runner.Start();
             */
#if USE_APPDOMAIN
#if USE_FRIENDLY_NAMING
            il.Append(il.Create(OpCodes.Ldstr, "AppDomainName"));
#else
            il.Append(il.Create(OpCodes.Ldstr, context.NameManager.GenerateName(NamingTable.Type)));
#endif

            //Get the AppDomain::Create(string) method
            var appDomainCreate = assembly.Import(typeof(AppDomain).GetMethod("CreateDomain", new[] { typeof(string) }));
            il.Append(il.Create(OpCodes.Call, appDomainCreate));
            il.Append(OpCodes.Stloc_0);

            //Get the Assembly::GetExecutingAssembly() method
            il.Append(il.Create(OpCodes.Call, getExecutingAssembly));

            il.Append(OpCodes.Stloc_1);
            il.Append(OpCodes.Ldloc_0);
            il.Append(OpCodes.Ldloc_1);

            //Assembly::get_FullName()
            var getFullName = typeof(Assembly).GetProperty("FullName");
            il.Append(il.Create(OpCodes.Callvirt, assembly.Import(getFullName.GetGetMethod())));

            il.Append(il.Create(OpCodes.Ldstr,
                                String.Format("{0}.{1}", programType.Namespace, programType.Name)));

            //AppDomain::CreateInstanceAndUnwrap(string, string)
            var createInstanceAndUnwrap = typeof(AppDomain).GetMethod("CreateInstanceAndUnwrap",
                                                                       new[]
                                                                                       {
                                                                                           typeof (string), typeof (string)
                                                                                       });
            il.Append(il.Create(OpCodes.Callvirt, assembly.Import(createInstanceAndUnwrap)));
            il.Append(il.Create(OpCodes.Castclass, programType));
            il.Append(OpCodes.Stloc_2);

            //AppDomain::get_CurrentDomain
            il.Append(il.Create(OpCodes.Call, currentDomain));
            il.Append(OpCodes.Ldloc_2);

            //Get the function
            il.Append(il.Create(OpCodes.Ldftn, resolveMethod));
            il.Append(il.Create(OpCodes.Newobj, eventHandler));
            il.Append(il.Create(OpCodes.Callvirt, assemblyResolve));

            il.Append(OpCodes.Nop);
            il.Append(OpCodes.Ldloc_2);
#else
            il.Append(il.Create(OpCodes.Newobj, programType.Constructors[0]));
            il.Append(OpCodes.Stloc_0);
            il.Append(OpCodes.Ldloc_0);
#endif
            //Start the program
            il.Append(il.Create(OpCodes.Callvirt, startMethod));
            il.Append(OpCodes.Nop);
            il.Append(OpCodes.Ret);
            return entryPoint;
        }
Ejemplo n.º 38
0
        /// <summary>
        /// Builds the resolve method.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="assembly">The definition.</param>
        /// <param name="assemblyLock">The assembly lock.</param>
        /// <param name="assembliesLoaded">The assemblies loaded.</param>
        /// <param name="loadAssemblies">The load assemblies.</param>
        /// <returns></returns>
        private static MethodDefinition BuildResolveMethod(ICloakContext context, AssemblyDefinition assembly, FieldReference assemblyLock, FieldReference assembliesLoaded, MethodReference loadAssemblies)
        {
#if USE_FRIENDLY_NAMING
            MethodDefinition method = new MethodDefinition("ResolveAssembly",
                                   MethodAttributes.Public | MethodAttributes.HideBySig, assembly.Import(typeof(Assembly)));
#else
            MethodDefinition method = new MethodDefinition(context.NameManager.GenerateName(NamingTable.Method),
                                   MethodAttributes.Public | MethodAttributes.HideBySig, assembly.Import(typeof(Assembly)));
#endif

            //Declare the resource parameter
            method.Parameters.Add(new ParameterDefinition("sender", Mono.Cecil.ParameterAttributes.None, assembly.Import(typeof(object))));
            method.Parameters.Add(new ParameterDefinition(assembly.Import(typeof(ResolveEventArgs))));
            
            method.Body.InitLocals = true;
            method.Body.MaxStackSize = 2;
            method.AddLocal(assembly, typeof(Assembly[])); //currentAssemblies
            method.AddLocal(assembly, typeof(Assembly));   //a
            method.AddLocal(assembly, typeof(Assembly));   //temp assembly
            method.AddLocal(assembly, typeof (object));    //temp object
            var tempBool = method.AddLocal(assembly, typeof (bool)); //temp bool
            var tempAssemblyArray = method.AddLocal(assembly, typeof(Assembly[])); //temp assembly array
            var tempInt = method.AddLocal(assembly, typeof (int)); //temp int
        
            //Get the il builder
            var il = method.Body.GetILProcessor();

            //Inject the anti reflector code
            InjectAntiReflectorCode(il, il.Create(OpCodes.Nop));
#if VERBOSE_OUTPUT
            DebugLine(assembly, il, "Resolving");
#endif

            //Start a lock
            il.Append(OpCodes.Ldarg_0);
            il.Append(il.Create(OpCodes.Ldfld, assemblyLock));
            il.Append(OpCodes.Dup);
            il.Append(OpCodes.Stloc_3);
            var monitorEnter = assembly.Import(typeof (Monitor).GetMethod("Enter", new[] {typeof (object)}));
            il.Append(il.Create(OpCodes.Call, monitorEnter));
            il.Append(OpCodes.Nop);
            var tryStart = il.Create(OpCodes.Nop);
            il.Append(tryStart);
            //Check if the assemblies are loaded
            il.Append(OpCodes.Ldarg_0);
            il.Append(il.Create(OpCodes.Ldfld, assembliesLoaded));
            il.Append(il.Create(OpCodes.Stloc_S, tempBool));
            il.Append(il.Create(OpCodes.Ldloc_S, tempBool));

            //If it is set, skip to searching the current appdomain
            var startSearchingCurrentAppDomain = il.Create(OpCodes.Nop);
            il.Append(il.Create(OpCodes.Brtrue_S, startSearchingCurrentAppDomain));
            il.Append(OpCodes.Nop);
            il.Append(OpCodes.Ldarg_0);
            il.Append(OpCodes.Ldc_I4_1);
            il.Append(il.Create(OpCodes.Stfld, assembliesLoaded));
            il.Append(OpCodes.Ldarg_0);
            il.Append(il.Create(OpCodes.Call, loadAssemblies));
            il.Append(OpCodes.Nop);
            il.Append(OpCodes.Nop);
            il.Append(startSearchingCurrentAppDomain);
            //After the finally
            var afterFinally = il.Create(OpCodes.Nop);
            //Exit the finally
            il.Append(il.Create(OpCodes.Leave_S, afterFinally));
            //We're in the finally now
            var finallyStart = il.Create(OpCodes.Ldloc_3);
            il.Append(finallyStart);
            var monitorExit = assembly.Import(typeof (Monitor).GetMethod("Exit", new[] {typeof (object)}));
            il.Append(il.Create(OpCodes.Call, monitorExit));
            il.Append(OpCodes.Nop);
            il.Append(OpCodes.Endfinally);
            il.Append(afterFinally);

            //Get the current domains assemblies
            var currentDomain = assembly.Import(typeof (AppDomain).GetProperty("CurrentDomain").GetGetMethod());
            il.Append(il.Create(OpCodes.Call, currentDomain));
            var getAssemblies = assembly.Import(typeof (AppDomain).GetMethod("GetAssemblies"));
            il.Append(il.Create(OpCodes.Callvirt, getAssemblies));
            il.Append(OpCodes.Stloc_0);
            il.Append(OpCodes.Nop);

            //Lets start a loop in lieu of foreach
            il.Append(OpCodes.Ldloc_0);
            il.Append(il.Create(OpCodes.Stloc_S, tempAssemblyArray));
            il.Append(OpCodes.Ldc_I4_0);
            il.Append(il.Create(OpCodes.Stloc_S, tempInt));

            //Loop Condition
            var loopCondition = il.Create(OpCodes.Ldloc_S, tempInt);
            il.Append(il.Create(OpCodes.Br_S, loopCondition));
            var startLoopBody = il.Create(OpCodes.Ldloc_S, tempAssemblyArray);
            il.Append(startLoopBody);
            il.Append(il.Create(OpCodes.Ldloc_S, tempInt));
            il.Append(OpCodes.Ldelem_Ref);
            il.Append(OpCodes.Stloc_1);
            il.Append(OpCodes.Nop);
            il.Append(OpCodes.Ldloc_1);

            //Check the name
            var getFullName = assembly.Import(typeof (Assembly).GetProperty("FullName").GetGetMethod());
            il.Append(il.Create(OpCodes.Callvirt, getFullName));
            il.Append(OpCodes.Ldarg_2);
            var getName = assembly.Import(typeof (ResolveEventArgs).GetProperty("Name").GetGetMethod());
            il.Append(il.Create(OpCodes.Callvirt, getName));
            //Check if equal
            var stringEquality =
                assembly.Import(typeof (String).GetMethod("op_Equality", new[] {typeof (string), typeof (string)}));
            il.Append(il.Create(OpCodes.Call, stringEquality));
            il.Append(OpCodes.Ldc_I4_0);
            il.Append(OpCodes.Ceq);
            il.Append(il.Create(OpCodes.Stloc_S, tempBool));
            il.Append(il.Create(OpCodes.Ldloc_S, tempBool));

            //Branch to increment block if necessary
            var incrementBlock = il.Create(OpCodes.Nop);
            il.Append(il.Create(OpCodes.Brtrue_S, incrementBlock));
            il.Append(OpCodes.Ldloc_1);
            il.Append(OpCodes.Stloc_2);
            var returnBlock = il.Create(OpCodes.Nop);
            il.Append(il.Create(OpCodes.Leave_S, returnBlock));
            //i++
            il.Append(incrementBlock);
            il.Append(il.Create(OpCodes.Ldloc_S, tempInt));
            il.Append(OpCodes.Ldc_I4_1);
            il.Append(OpCodes.Add);
            il.Append(il.Create(OpCodes.Stloc_S, tempInt));

            //The comparison block
            il.Append(loopCondition);
            il.Append(il.Create(OpCodes.Ldloc_S, tempAssemblyArray));
            il.Append(OpCodes.Ldlen);
            il.Append(OpCodes.Conv_I4);
            il.Append(OpCodes.Clt);
            il.Append(il.Create(OpCodes.Stloc_S, tempBool));
            il.Append(il.Create(OpCodes.Ldloc_S, tempBool));
            il.Append(il.Create(OpCodes.Brtrue_S, startLoopBody));
            //Not found block
            il.Append(OpCodes.Ldnull);
            il.Append(OpCodes.Stloc_2);
            il.Append(il.Create(OpCodes.Br_S, returnBlock));
            il.Append(returnBlock);
            il.Append(OpCodes.Ldloc_2);
            il.Append(OpCodes.Ret);

            //Finally do the try/finally
            ExceptionHandler finallyBlock = new ExceptionHandler(ExceptionHandlerType.Finally); //the lock
            finallyBlock.TryStart = tryStart;
            finallyBlock.TryEnd = finallyStart;
            finallyBlock.HandlerStart = finallyStart;
            finallyBlock.HandlerEnd = afterFinally;
            method.Body.ExceptionHandlers.Add(finallyBlock);
            
            //Return the method
            return method;
        }