Esempio n. 1
0
        /// <summary>
        /// Builds the program constructor.
        /// </summary>
        /// <param name="assembly">The assembly.</param>
        /// <param name="programType">Type of the program.</param>
        /// <param name="assemblyLock">The assembly lock.</param>
        /// <param name="executingAssembly">The executing assembly.</param>
        /// <param name="loadedAssemblies">The loaded assemblies.</param>
        /// <param name="currentDomain">The current domain.</param>
        /// <param name="eventHandler">The event handler.</param>
        /// <param name="assemblyResolve">The assembly resolve.</param>
        /// <param name="getExecutingAssembly">The get executing assembly.</param>
        /// <param name="resolveMethod">The resolve method.</param>
        private static void BuildProgramConstructor(AssemblyDefinition assembly, TypeDefinition programType, FieldReference assemblyLock, FieldReference executingAssembly, FieldReference loadedAssemblies, MethodReference currentDomain, MethodReference eventHandler, MethodReference assemblyResolve, MethodReference getExecutingAssembly, MethodReference resolveMethod)
        {
            var body = assembly.CreateDefaultConstructor(programType);
            body.MaxStackSize = 4;
            body.InitLocals = true;
            body.Variables.Add(new VariableDefinition(assembly.Import(typeof(AppDomain))));
            var il = body.GetILProcessor();

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

            //define the assembly lock
            var objConstructor = assembly.Import(typeof(object).GetConstructor(Type.EmptyTypes));
            il.Append(il.Create(OpCodes.Newobj, objConstructor));
            il.Append(il.Create(OpCodes.Stfld, assemblyLock));
            il.Append(OpCodes.Ldarg_0);
            il.Append(il.Create(OpCodes.Call, objConstructor));
            il.Append(OpCodes.Nop);
            il.Append(OpCodes.Nop);
            il.Append(OpCodes.Ldarg_0);
            var cacheConstructor = assembly.Import(typeof(Dictionary<string, Assembly>).GetConstructor(Type.EmptyTypes));
            il.Append(il.Create(OpCodes.Newobj, cacheConstructor));
            il.Append(il.Create(OpCodes.Stfld, loadedAssemblies));
            il.Append(OpCodes.Ldarg_0);
            il.Append(il.Create(OpCodes.Call, getExecutingAssembly));
            il.Append(il.Create(OpCodes.Stfld, executingAssembly));
            il.Append(il.Create(OpCodes.Call, currentDomain));
            il.Append(OpCodes.Stloc_0);
            il.Append(OpCodes.Ldloc_0);
            il.Append(OpCodes.Ldarg_0);
            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.Nop);
            il.Append(OpCodes.Ret);
        }
Esempio n. 2
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);
        }