protected override void Execute(ConfuserContext context, ProtectionParameters parameters) {
				foreach (ModuleDef module in parameters.Targets.OfType<ModuleDef>()) {
					TypeRef attrRef = module.CorLibTypes.GetTypeRef("System.Runtime.CompilerServices", "SuppressIldasmAttribute");
					var ctorRef = new MemberRefUser(module, ".ctor", MethodSig.CreateInstance(module.CorLibTypes.Void), attrRef);

					var attr = new CustomAttribute(ctorRef);
					module.CustomAttributes.Add(attr);
				}
			}
示例#2
0
		public static void Run() {
			// Create a new module. The string passed in is the name of the module,
			// not the file name.
			ModuleDef mod = new ModuleDefUser("MyModule.exe");
			// It's a console application
			mod.Kind = ModuleKind.Console;

			// Add the module to an assembly
			AssemblyDef asm = new AssemblyDefUser("MyAssembly", new Version(1, 2, 3, 4), null, null);
			asm.Modules.Add(mod);

			// Add a .NET resource
			byte[] resourceData = Encoding.UTF8.GetBytes("Hello, world!");
			mod.Resources.Add(new EmbeddedResource("My.Resource", resourceData,
							ManifestResourceAttributes.Private));

			// Add the startup type. It derives from System.Object.
			TypeDef startUpType = new TypeDefUser("My.Namespace", "Startup", mod.CorLibTypes.Object.TypeDefOrRef);
			startUpType.Attributes = TypeAttributes.NotPublic | TypeAttributes.AutoLayout |
									TypeAttributes.Class | TypeAttributes.AnsiClass;
			// Add the type to the module
			mod.Types.Add(startUpType);

			// Create the entry point method
			MethodDef entryPoint = new MethodDefUser("Main",
				MethodSig.CreateStatic(mod.CorLibTypes.Int32, new SZArraySig(mod.CorLibTypes.String)));
			entryPoint.Attributes = MethodAttributes.Private | MethodAttributes.Static |
							MethodAttributes.HideBySig | MethodAttributes.ReuseSlot;
			entryPoint.ImplAttributes = MethodImplAttributes.IL | MethodImplAttributes.Managed;
			// Name the 1st argument (argument 0 is the return type)
			entryPoint.ParamDefs.Add(new ParamDefUser("args", 1));
			// Add the method to the startup type
			startUpType.Methods.Add(entryPoint);
			// Set module entry point
			mod.EntryPoint = entryPoint;

			// Create a TypeRef to System.Console
			TypeRef consoleRef = new TypeRefUser(mod, "System", "Console", mod.CorLibTypes.AssemblyRef);
			// Create a method ref to 'System.Void System.Console::WriteLine(System.String)'
			MemberRef consoleWrite1 = new MemberRefUser(mod, "WriteLine",
						MethodSig.CreateStatic(mod.CorLibTypes.Void, mod.CorLibTypes.String),
						consoleRef);

			// Add a CIL method body to the entry point method
			CilBody epBody = new CilBody();
			entryPoint.Body = epBody;
			epBody.Instructions.Add(OpCodes.Ldstr.ToInstruction("Hello World!"));
			epBody.Instructions.Add(OpCodes.Call.ToInstruction(consoleWrite1));
			epBody.Instructions.Add(OpCodes.Ldc_I4_0.ToInstruction());
			epBody.Instructions.Add(OpCodes.Ret.ToInstruction());

			// Save the assembly to a file on disk
			mod.Write(@"C:\saved-assembly.exe");
		}
示例#3
0
		/// <summary>
		/// Resolve an IField from its name and a declaring TypeSpec.
		/// </summary>
		/// <param name="declaringType">Declaring TypeSpec</param>
		/// <param name="fieldName">Field name</param>
		/// <returns>IField, or null if none found</returns>
		public IField ResolveField(TypeSpec declaringType, String fieldName)
		{
			TypeDef typeDef = declaringType.ResolveTypeDef();
			if (typeDef == null)
				return null;

			FieldDef fieldDef = typeDef.FindField(fieldName);
			if (fieldDef == null)
				return null;

			MemberRef memberRef = new MemberRefUser(_module, fieldDef.Name, fieldDef.FieldSig, declaringType);
			return this.Importer.Import(memberRef);
		}
		void InitializeCtors(TypeDef manager, MethodDefAndDeclaringTypeDict<IMethod> ctors) {
			if (manager == null)
				return;

			foreach (var ctor in manager.Methods) {
				if (ctor.Name != ".ctor")
					continue;

				var newCtor = new MemberRefUser(module, ctor.Name, ctor.MethodSig.Clone(), manager.BaseType);
				module.UpdateRowId(newCtor);
				ctors.Add(ctor, newCtor);
			}
		}
		IMDTokenProvider Create_SystemArray_get_Length()
		{
			if (Create_SystemArray_get_Length_result_initd)
				return Create_SystemArray_get_Length_result;
			Create_SystemArray_get_Length_result_initd = true;

			var module = GetModule();
			if (module == null)
				return null;

			const string propName = "Length";
			var type = module.CorLibTypes.GetTypeRef("System", "Array");
			var retType = module.CorLibTypes.Int32;
			var mr = new MemberRefUser(module, "get_" + propName, MethodSig.CreateInstance(retType), type);
			Create_SystemArray_get_Length_result = mr;
			var md = mr.ResolveMethod();
			if (md == null || md.DeclaringType == null)
				return mr;
			var prop = md.DeclaringType.FindProperty(propName);
			if (prop == null)
				return mr;

			Create_SystemArray_get_Length_result = prop;
			return prop;
		}
示例#6
0
        IMethod ResolveMethod_NoLock(TypeSpec declaringSpec, MethodData data)
        {
            // Find a method that matches the signature (factoring in possible generic vars/mvars)
            MethodSig matchedSig = null;
            MethodDef method = FindMethodCheckBaseType(declaringSpec, data, out matchedSig);

            if (matchedSig == null || method == null)
            {
                throw new Exception(String.Format(
                    "Unable to find generic method from the declaring/base types: DeclaringType={0}, MethodName={1}",
                    declaringSpec.ReflectionFullName, data.Name));
            }

            MemberRef memberRef = new MemberRefUser(this.Module, method.Name, matchedSig, declaringSpec);
            if (data.HasGenericArguments)
                return this.Importer.Import(new MethodSpecUser(memberRef, ToGenericInstMethodSig(data)));
            else
                return this.Importer.Import(memberRef);
        }
示例#7
0
		public IMethod ReadMethodRef() {
			var babelMethodRef = new MethodRefReader(this, reader).Read();

			var method = GetMethodRef(babelMethodRef);
			if (method == null) {
				throw new ApplicationException(string.Format("Could not find method '{0}' in type '{1}'",
							Utils.RemoveNewlines(babelMethodRef.Name),
							Utils.RemoveNewlines(babelMethodRef.DeclaringType)));
			}

			var git = babelMethodRef.DeclaringType.ToGenericInstSig();
			if (git == null)
				return method;

			var mr = new MemberRefUser(module, method.Name, method.MethodSig.Clone(), babelMethodRef.DeclaringType.ToTypeDefOrRef());
			return module.UpdateRowId(mr);
		}
示例#8
0
		IMDTokenProvider Create_SystemType_get_TypeHandle()
		{
			if (Create_SystemType_get_TypeHandle_initd)
				return Create_SystemType_get_TypeHandle_result;
			Create_SystemType_get_TypeHandle_initd = true;

			const string propName = "TypeHandle";
			var type = corLib.GetTypeRef("System", "Type");
			var retType = new ValueTypeSig(corLib.GetTypeRef("System", "RuntimeTypeHandle"));
			var mr = new MemberRefUser(methodDef.Module, "get_" + propName, MethodSig.CreateInstance(retType), type);
			Create_SystemType_get_TypeHandle_result = mr;
			var md = mr.ResolveMethod();
			if (md == null || md.DeclaringType == null)
				return mr;
			var prop = md.DeclaringType.FindProperty(propName);
			if (prop == null)
				return mr;

			Create_SystemType_get_TypeHandle_result = prop;
			return prop;
		}
示例#9
0
		public static void Run() {
			// This is the file that will be created
			string newFileName = @"C:\ctor-test.exe";

			// Create the module
			var mod = new ModuleDefUser("ctor-test", Guid.NewGuid(),
				new AssemblyRefUser(new AssemblyNameInfo(typeof(int).Assembly.GetName().FullName)));
			// It's a console app
			mod.Kind = ModuleKind.Console;
			// Create the assembly and add the created module to it
			new AssemblyDefUser("ctor-test", new Version(1, 2, 3, 4)).Modules.Add(mod);

			// Create System.Console type reference
			var systemConsole = mod.CorLibTypes.GetTypeRef("System", "Console");
			// Create 'void System.Console.WriteLine(string,object)' method reference
			var writeLine2 = new MemberRefUser(mod, "WriteLine",
							MethodSig.CreateStatic(mod.CorLibTypes.Void, mod.CorLibTypes.String,
												mod.CorLibTypes.Object),
							systemConsole);
			// Create System.Object::.ctor method reference. This is the default constructor
			var objectCtor = new MemberRefUser(mod, ".ctor",
							MethodSig.CreateInstance(mod.CorLibTypes.Void),
							mod.CorLibTypes.Object.TypeDefOrRef);

			CilBody body;
			// Create the base class
			var bclass = new TypeDefUser("Ctor.Test", "BaseClass", mod.CorLibTypes.Object.TypeDefOrRef);
			// Add it to the module
			mod.Types.Add(bclass);
			// Create Ctor.Test.BaseClass constructor: BaseClass()
			var bctor = new MethodDefUser(".ctor", MethodSig.CreateInstance(mod.CorLibTypes.Void),
							MethodImplAttributes.IL | MethodImplAttributes.Managed,
							MethodAttributes.Public |
							MethodAttributes.SpecialName | MethodAttributes.RTSpecialName);
			// Add the method to BaseClass
			bclass.Methods.Add(bctor);
			// Create method body and add a few instructions
			bctor.Body = body = new CilBody();
			// Make sure we call the base class' constructor
			body.Instructions.Add(OpCodes.Ldarg_0.ToInstruction());
			body.Instructions.Add(OpCodes.Call.ToInstruction(objectCtor));
			body.Instructions.Add(OpCodes.Ldstr.ToInstruction("BaseClass: Default .ctor called"));
			body.Instructions.Add(OpCodes.Ldnull.ToInstruction());
			body.Instructions.Add(OpCodes.Call.ToInstruction(writeLine2));
			body.Instructions.Add(OpCodes.Ret.ToInstruction());

			// Create the Ctor.Test.Main type which derives from Ctor.Test.BaseClass
			var main = new TypeDefUser("Ctor.Test", "Main", bclass);
			// Add it to the module
			mod.Types.Add(main);
			// Create the static 'void Main()' method
			var entryPoint = new MethodDefUser("Main", MethodSig.CreateStatic(mod.CorLibTypes.Void),
							MethodImplAttributes.IL | MethodImplAttributes.Managed,
							MethodAttributes.Public | MethodAttributes.Static);
			// Set entry point to entryPoint and add it as a Ctor.Test.Main method
			mod.EntryPoint = entryPoint;
			main.Methods.Add(entryPoint);

			// Create first Ctor.Test.Main constructor: Main()
			var ctor0 = new MethodDefUser(".ctor", MethodSig.CreateInstance(mod.CorLibTypes.Void),
							MethodImplAttributes.IL | MethodImplAttributes.Managed,
							MethodAttributes.Public |
							MethodAttributes.SpecialName | MethodAttributes.RTSpecialName);
			// Add the method to Main
			main.Methods.Add(ctor0);
			// Create method body and add a few instructions
			ctor0.Body = body = new CilBody();
			// Make sure we call the base class' constructor
			body.Instructions.Add(OpCodes.Ldarg_0.ToInstruction());
			body.Instructions.Add(OpCodes.Call.ToInstruction(bctor));
			body.Instructions.Add(OpCodes.Ldstr.ToInstruction("Default .ctor called"));
			body.Instructions.Add(OpCodes.Ldnull.ToInstruction());
			body.Instructions.Add(OpCodes.Call.ToInstruction(writeLine2));
			body.Instructions.Add(OpCodes.Ret.ToInstruction());

			// Create second Ctor.Test.Main constructor: Main(int,string)
			var ctor1 = new MethodDefUser(".ctor", MethodSig.CreateInstance(mod.CorLibTypes.Void, mod.CorLibTypes.Int32, mod.CorLibTypes.String),
							MethodImplAttributes.IL | MethodImplAttributes.Managed,
							MethodAttributes.Public |
							MethodAttributes.SpecialName | MethodAttributes.RTSpecialName);
			// Add the method to Main
			main.Methods.Add(ctor1);
			// Create names for the arguments. This is optional. Since this is an instance method
			// (it's a constructor), the first arg is the 'this' pointer. The normal arguments
			// begin at index 1.
			ctor1.Parameters[1].CreateParamDef();
			ctor1.Parameters[1].ParamDef.Name = "count";
			ctor1.Parameters[2].CreateParamDef();
			ctor1.Parameters[2].ParamDef.Name = "name";
			// Create method body and add a few instructions
			ctor1.Body = body = new CilBody();
			// Make sure we call the base class' constructor
			body.Instructions.Add(OpCodes.Ldarg_0.ToInstruction());
			body.Instructions.Add(OpCodes.Call.ToInstruction(bctor));
			body.Instructions.Add(OpCodes.Ldstr.ToInstruction(".ctor(Int32) called with arg {0}"));
			body.Instructions.Add(OpCodes.Ldarg_1.ToInstruction());
			body.Instructions.Add(OpCodes.Box.ToInstruction(mod.CorLibTypes.Int32));
			body.Instructions.Add(OpCodes.Call.ToInstruction(writeLine2));
			body.Instructions.Add(OpCodes.Ret.ToInstruction());

			// Create the entry point method body and add instructions to allocate a new Main()
			// object and call the two created ctors.
			entryPoint.Body = body = new CilBody();
			body.Instructions.Add(OpCodes.Newobj.ToInstruction(ctor0));
			body.Instructions.Add(OpCodes.Pop.ToInstruction());
			body.Instructions.Add(OpCodes.Ldc_I4.ToInstruction(12345));
			body.Instructions.Add(OpCodes.Ldnull.ToInstruction());
			body.Instructions.Add(OpCodes.Newobj.ToInstruction(ctor1));
			body.Instructions.Add(OpCodes.Pop.ToInstruction());
			body.Instructions.Add(OpCodes.Ret.ToInstruction());

			// Save the assembly
			mod.Write(newFileName);
		}
示例#10
0
        public static void Run()
        {
            // This is the file that will be created
            string newFileName = @"GenericExample1.exe";

            // Create the module
            var mod = new ModuleDefUser("GenericExample1", Guid.NewGuid(),
                new AssemblyRefUser(new AssemblyNameInfo(typeof(int).Assembly.GetName().FullName)));
            // It's a console app
            mod.Kind = ModuleKind.Console;
            // Create the assembly and add the created module to it
            new AssemblyDefUser("GenericExample1", new Version(1, 2, 3, 4)).Modules.Add(mod);

            // Add the startup type. It derives from System.Object.
            TypeDef startUpType = new TypeDefUser("My.Namespace", "Startup", mod.CorLibTypes.Object.TypeDefOrRef);
            startUpType.Attributes = TypeAttributes.NotPublic | TypeAttributes.AutoLayout |
                                    TypeAttributes.Class | TypeAttributes.AnsiClass;
            // Add the type to the module
            mod.Types.Add(startUpType);

            // Create the entry point method
            MethodDef entryPoint = new MethodDefUser("Main",
                MethodSig.CreateStatic(mod.CorLibTypes.Int32, new SZArraySig(mod.CorLibTypes.String)));
            entryPoint.Attributes = MethodAttributes.Private | MethodAttributes.Static |
                            MethodAttributes.HideBySig | MethodAttributes.ReuseSlot;
            entryPoint.ImplAttributes = MethodImplAttributes.IL | MethodImplAttributes.Managed;
            // Name the 1st argument (argument 0 is the return type)
            entryPoint.ParamDefs.Add(new ParamDefUser("args", 1));
            // Add the method to the startup type
            startUpType.Methods.Add(entryPoint);
            // Set module entry point
            mod.EntryPoint = entryPoint;

            // Create System.Console type reference
            var systemConsole = mod.CorLibTypes.GetTypeRef("System", "Console");
            // Create 'void System.Console.WriteLine(string,object)' method reference
            var writeLine2 = new MemberRefUser(mod, "WriteLine",
                            MethodSig.CreateStatic(mod.CorLibTypes.Void, mod.CorLibTypes.String,
                                mod.CorLibTypes.Object),
                            systemConsole);

            //
            // Method 1: Create List<String> inst signature by importing (easy way)
            // --------------------------------------------------------------------
            //Importer importer = new Importer(mod);
            //var listGenericInstSig = importer.ImportAsTypeSig(typeof(System.Collections.Generic.List<String>));

            //
            // Method 2: Create List<String> inst signature manually (harder way)
            // ------------------------------------------------------------------
            var assemblyRef = mod.CorLibTypes.AssemblyRef;
            var listRef = new TypeRefUser(mod, @"System.Collections.Generic", "List`1", assemblyRef);
            // Create the GenericInstSig from a ClassSig with <String> generic arg
            var listGenericInstSig = new GenericInstSig(new ClassSig(listRef), mod.CorLibTypes.String);

            // Create TypeSpec from GenericInstSig
            var listTypeSpec = new TypeSpecUser(listGenericInstSig);
            // Create System.Collections.Generic.List<String>::.ctor method reference
            var listCtor = new MemberRefUser(mod, ".ctor", MethodSig.CreateInstance(mod.CorLibTypes.Void),
                listTypeSpec);

            // Create Add(!0) method reference, !0 signifying first generic argument of declaring type
            // In this case, would be Add(String item)
            // (GenericMVar would be used for method generic argument, such as Add<!!0>(!!0))
            var listAdd = new MemberRefUser(mod, "Add",
                MethodSig.CreateInstance(mod.CorLibTypes.Void, new GenericVar(0)),
                listTypeSpec);

            var listGetCount = new MemberRefUser(mod, "get_Count",
                MethodSig.CreateInstance(mod.CorLibTypes.Int32),
                listTypeSpec);

            IList<Local> locals = new List<Local>();
            locals.Add(new Local(listGenericInstSig)); // local[0]: class [mscorlib]System.Collections.Generic.List`1<string>

            var body = new CilBody(true, new List<Instruction>(), new List<ExceptionHandler>(), locals);
            // Call the list .ctor
            body.Instructions.Add(OpCodes.Newobj.ToInstruction(listCtor));
            body.Instructions.Add(OpCodes.Stloc_0.ToInstruction()); // Store list to local[0]

            // list.Add("Item 1")
            body.Instructions.Add(OpCodes.Ldloc_0.ToInstruction());
            body.Instructions.Add(OpCodes.Ldstr.ToInstruction("Item 1"));
            body.Instructions.Add(OpCodes.Callvirt.ToInstruction(listAdd));

            // WriteLine("Array: {0}", list.ToArray());
            //body.Instructions.Add(OpCodes.Ldstr.ToInstruction("Array: {0}"));
            //body.Instructions.Add(OpCodes.Ldloc_0.ToInstruction()); // Load list from local[0]
            //body.Instructions.Add(OpCodes.Callvirt.ToInstruction(listToArray));
            //body.Instructions.Add(OpCodes.Call.ToInstruction(writeLine2));

            // WriteLine("Count: {0}", list.Count)
            body.Instructions.Add(OpCodes.Ldstr.ToInstruction("Count: {0}"));
            body.Instructions.Add(OpCodes.Ldloc_0.ToInstruction()); // Load list from local[0]
            body.Instructions.Add(OpCodes.Callvirt.ToInstruction(listGetCount));
            body.Instructions.Add(OpCodes.Box.ToInstruction(mod.CorLibTypes.Int32));
            body.Instructions.Add(OpCodes.Call.ToInstruction(writeLine2));

            // return 0;
            body.Instructions.Add(OpCodes.Ldc_I4_0.ToInstruction());
            body.Instructions.Add(OpCodes.Ret.ToInstruction());

            entryPoint.Body = body;

            // Save the assembly
            mod.Write(newFileName);
        }
示例#11
0
		MemberRef SimpleClone(MethodDef methodRef, ITypeDefOrRef declaringType) {
			if (module == null)
				return new MemberRefUser(null, methodRef.Name, methodRef.MethodSig, declaringType);
			var mr = new MemberRefUser(module.ModuleDefMD, methodRef.Name, methodRef.MethodSig, declaringType);
			return module.ModuleDefMD.UpdateRowId(mr);
		}
 public MemberRef CreateInitializeArrayMethod()
 {
     if (_initializeArrayMethod == null)
     {
         var runtimeHelpersType = FindOrCreateTypeRef(_module, _module.CorLibTypes.AssemblyRef, "System.Runtime.CompilerServices", "RuntimeHelpers", false);
         var systemArrayType = FindOrCreateTypeRef(_module, _module.CorLibTypes.AssemblyRef, "System", "Array", false);
         var runtimeFieldHandleType = FindOrCreateTypeRef(_module, _module.CorLibTypes.AssemblyRef, "System", "RuntimeFieldHandle", true);
         var methodSig = MethodSig.CreateStatic(_module.CorLibTypes.Void, systemArrayType, runtimeFieldHandleType);
         _initializeArrayMethod = _module.UpdateRowId(new MemberRefUser(_module, "InitializeArray", methodSig, runtimeHelpersType.TypeDefOrRef));
     }
     return _initializeArrayMethod;
 }
示例#13
0
        private void pasteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            int instructionIndex = dgBody.SelectedRows.TopmostRow().Index + 1;

            foreach (Instruction instruction in _copiedInstructions.OrderByDescending(i => i.Offset))
            {
                var newInstruction = new Instruction(instruction.OpCode);

                if (instruction.Operand != null)
                    switch (instruction.OpCode.OperandType)
                    {
                        case OperandType.InlineField:
                            var field = instruction.Operand as IField;
                            if (field.DeclaringType.DefinitionAssembly != CurrentAssembly.ManifestModule.Assembly ||
                                field.Module != CurrentAssembly.ManifestModule)
                            {
                                var fieldRef = new MemberRefUser(field.Module, field.Name, field.FieldSig,
                                    field.DeclaringType);

                                newInstruction.Operand = CurrentAssembly.ManifestModule.Import(fieldRef);
                            }
                            else
                            {
                                newInstruction.Operand = CurrentAssembly.ManifestModule.ResolveField(field.Rid);
                            }
                            break;

                        case OperandType.InlineMethod:
                            var method = instruction.Operand as IMethod;
                            if (method.DeclaringType.DefinitionAssembly != CurrentAssembly.ManifestModule.Assembly ||
                                method.Module != CurrentAssembly.ManifestModule)
                            {
                                var methodRef = new MemberRefUser(method.Module, method.Name, method.MethodSig,
                                    method.DeclaringType);

                                newInstruction.Operand = CurrentAssembly.ManifestModule.Import(methodRef);
                            }
                            else
                            {
                                newInstruction.Operand = CurrentAssembly.ManifestModule.ResolveMethod(method.Rid);
                            }
                            break;

                        case OperandType.InlineType:
                            var type = instruction.Operand as ITypeDefOrRef;

                            if (type.DefinitionAssembly != CurrentAssembly.ManifestModule.Assembly ||
                                type.Module != CurrentAssembly.ManifestModule)
                            {
                                var typeRef = new TypeRefUser(type.Module, type.Namespace, type.Name,
                                    CurrentAssembly.ManifestModule.CorLibTypes.AssemblyRef);

                                newInstruction.Operand = CurrentAssembly.ManifestModule.Import(typeRef);
                            }
                            else
                            {
                                newInstruction.Operand = CurrentAssembly.ManifestModule.ResolveTypeDefOrRef(type.Rid);
                            }
                            break;
                        default:
                            newInstruction.Operand = instruction.Operand;
                            break;
                    }

                CurrentAssembly.Method.Body.Instructions.Insert(instructionIndex, newInstruction);
            }
            FixBranches();

            CurrentAssembly.Method.Body.Instructions.UpdateInstructionOffsets();
            DataGridViewHandler.ReadMethod(CurrentAssembly.Method);
        }
示例#14
0
        public static void Run()
        {
            // This is the file that will be created
            string newFileName = @"GenericExample2.exe";

            // Create the module
            var mod = new ModuleDefUser("GenericExample2", Guid.NewGuid(),
                new AssemblyRefUser(new AssemblyNameInfo(typeof(int).Assembly.GetName().FullName)));
            // It's a console app
            mod.Kind = ModuleKind.Console;
            // Create the assembly and add the created module to it
            new AssemblyDefUser("GenericExample2", new Version(1, 2, 3, 4)).Modules.Add(mod);

            // Add the startup type. It derives from System.Object.
            TypeDef startUpType = new TypeDefUser("My.Namespace", "Startup", mod.CorLibTypes.Object.TypeDefOrRef);
            startUpType.Attributes = TypeAttributes.NotPublic | TypeAttributes.AutoLayout |
                                    TypeAttributes.Class | TypeAttributes.AnsiClass;
            // Add the type to the module
            mod.Types.Add(startUpType);

            // Create the entry point method
            MethodDef entryPoint = new MethodDefUser("Main",
                MethodSig.CreateStatic(mod.CorLibTypes.Int32, new SZArraySig(mod.CorLibTypes.String)));
            entryPoint.Attributes = MethodAttributes.Private | MethodAttributes.Static |
                            MethodAttributes.HideBySig | MethodAttributes.ReuseSlot;
            entryPoint.ImplAttributes = MethodImplAttributes.IL | MethodImplAttributes.Managed;
            // Name the 1st argument (argument 0 is the return type)
            entryPoint.ParamDefs.Add(new ParamDefUser("args", 1));
            // Add the method to the startup type
            startUpType.Methods.Add(entryPoint);
            // Set module entry point
            mod.EntryPoint = entryPoint;

            // Create System.Console type reference
            var systemConsole = mod.CorLibTypes.GetTypeRef("System", "Console");
            // Create 'void System.Console.WriteLine(string,object)' method reference
            var writeLine2 = new MemberRefUser(mod, "WriteLine",
                            MethodSig.CreateStatic(mod.CorLibTypes.Void, mod.CorLibTypes.String,
                                mod.CorLibTypes.Object),
                            systemConsole);

            var assemblyRef = mod.CorLibTypes.AssemblyRef;
            // Create 'System.Collections.ObjectModel.ReadOnlyCollection`1' type ref
            var roCollectionRef = new TypeRefUser(mod, "System.Collections.ObjectModel", "ReadOnlyCollection`1", assemblyRef);
            // Create 'ReadOnlyCollection<!!0>' signature for return type
            var roCollectionSig = new GenericInstSig(new ClassSig(roCollectionRef), new GenericMVar(0)); // Return type

            // Create 'ReadOnlyCollection<Int32>' type spec
            var roCollectionTypeSpec = new TypeSpecUser(new GenericInstSig(new ClassSig(roCollectionRef), mod.CorLibTypes.Int32));
            // Create 'ReadOnlyCollection<Int32>.get_Count()' method reference
            var roCollectionGetCount = new MemberRefUser(mod, "get_Count",
                MethodSig.CreateInstance(mod.CorLibTypes.Int32),
                roCollectionTypeSpec);

            // Create 'System.Array' type ref
            var arrayRef = new TypeRefUser(mod, "System", "Array", assemblyRef);
            // Create 'ReadOnlyCollection<T> Array.AsReadOnly<T>(T[] array)' method reference
            // Apparently CreateStaticGeneric should be used only if at least one GenericMVar is used? Not 100% certain.
            var asReadOnly = new MemberRefUser(mod, "AsReadOnly",
                            MethodSig.CreateStaticGeneric(1, roCollectionSig, new SZArraySig(new GenericMVar(0))),
                            arrayRef);
            // Create 'Array.AsReadOnly<Int32>' method spec
            var asReadOnlySpec = new MethodSpecUser(asReadOnly,
                new GenericInstMethodSig(mod.CorLibTypes.Int32));

            // Create 'ReadOnlyCollection<Int32>' signature for local
            var roCollectionInt32 = roCollectionTypeSpec.TryGetGenericInstSig();

            // Method body locals
            IList<Local> locals = new List<Local>();
            locals.Add(new Local(new SZArraySig(mod.CorLibTypes.Int32))); // local[0]: Int32[]
            locals.Add(new Local(roCollectionInt32)); // local[1]: class [mscorlib]System.Collections.ObjectModel.ReadOnlyCollection`1<Int32>

            var body = new CilBody(true, new List<Instruction>(), new List<ExceptionHandler>(), locals);

            // array = new Int32[2];
            body.Instructions.Add(OpCodes.Ldc_I4_2.ToInstruction());
            body.Instructions.Add(OpCodes.Newarr.ToInstruction(mod.CorLibTypes.Int32));
            body.Instructions.Add(OpCodes.Stloc_0.ToInstruction()); // Store array to local[0]

            // array[0] = 5;
            body.Instructions.Add(OpCodes.Ldloc_0.ToInstruction());
            body.Instructions.Add(OpCodes.Ldc_I4_0.ToInstruction());
            body.Instructions.Add(OpCodes.Ldc_I4_5.ToInstruction());
            body.Instructions.Add(OpCodes.Stelem_I4.ToInstruction());

            // array[1] = 111;
            body.Instructions.Add(OpCodes.Ldloc_0.ToInstruction());
            body.Instructions.Add(OpCodes.Ldc_I4_1.ToInstruction());
            body.Instructions.Add(OpCodes.Ldc_I4.ToInstruction(111));
            body.Instructions.Add(OpCodes.Stelem_I4.ToInstruction());

            // collection = Array.AsReadOnly<Int32>(array)
            body.Instructions.Add(OpCodes.Ldloc_0.ToInstruction());
            body.Instructions.Add(OpCodes.Call.ToInstruction(asReadOnlySpec));
            body.Instructions.Add(OpCodes.Stloc_1.ToInstruction());

            // Console.WriteLine("Count: {0}", collection.Count)
            body.Instructions.Add(OpCodes.Ldstr.ToInstruction("Count: {0}"));
            body.Instructions.Add(OpCodes.Ldloc_1.ToInstruction());
            body.Instructions.Add(OpCodes.Callvirt.ToInstruction(roCollectionGetCount));
            body.Instructions.Add(OpCodes.Box.ToInstruction(mod.CorLibTypes.Int32));
            body.Instructions.Add(OpCodes.Call.ToInstruction(writeLine2));

            // return 0;
            body.Instructions.Add(OpCodes.Ldc_I4_0.ToInstruction());
            body.Instructions.Add(OpCodes.Ret.ToInstruction());

            entryPoint.Body = body;

            // Save the assembly
            mod.Write(newFileName);
        }
		/// <summary>
		/// Creates a custom ObfuscationAttribute that can be added to a method.
		/// </summary>
		/// <param name="module">Module</param>
		/// <param name="feature">Obfuscation feature name</param>
		/// <param name="exclude">true if exclude, false if include</param>
		/// <returns>CustomAttribute</returns>
		CustomAttribute CreateAttribute(ModuleDef module, String feature, Boolean exclude)
		{
			TypeSig stringSig = module.CorLibTypes.String;
			TypeSig booleanSig = module.CorLibTypes.Boolean;

			CANamedArgument[] args = new CANamedArgument[] {
				// Feature
				new CANamedArgument(
					false,
					stringSig,
					"Feature",
					new CAArgument(stringSig, feature)),

				// Exclude
				new CANamedArgument(
					false,
					booleanSig,
					"Exclude",
					new CAArgument(booleanSig, exclude))
			};

			TypeRef obfuscationRef = new TypeRefUser(
				module, "System.Reflection", "ObfuscationAttribute", module.CorLibTypes.AssemblyRef);

			MemberRef obfuscationCtor = new MemberRefUser(module, ".ctor",
						MethodSig.CreateInstance(module.CorLibTypes.Void),
						obfuscationRef);

			CustomAttribute attr = new CustomAttribute(
				obfuscationCtor,
				new CAArgument[0],
				args
			);

			return attr;
		}
		/// <summary>
		/// Calli.
		/// </summary>
		/// <param name="module">Module</param>
		/// <param name="mainType">Main type</param>
		/// <returns>Instructions</returns>
		static IList<Instruction> GetCalliInstructions(ModuleDef module, TypeDef mainType)
		{
			TypeRef consoleRef = new TypeRefUser(module, "System", "Console", module.CorLibTypes.AssemblyRef);
			MemberRef consoleWrite0 = new MemberRefUser(module, "WriteLine",
						MethodSig.CreateStatic(module.CorLibTypes.Void),
						consoleRef);

			var all = new List<Instruction>();
			all.Add(OpCodes.Ldftn.ToInstruction(consoleWrite0));
			all.Add(OpCodes.Calli.ToInstruction(consoleWrite0.MethodSig));
			all.Add(OpCodes.Ret.ToInstruction());
			return all;
		}