Beispiel #1
0
        static void mergeClassWithAllAncestors(NamespaceTypeDefinition mergeTargetClass, PeReader.DefaultHost host)
        {
            List <NamespaceTypeDefinition> ancestorClasses = new List <NamespaceTypeDefinition>();

            ancestorClasses.Add(mergeTargetClass);

            NamespaceTypeDefinition currentClass  = mergeTargetClass;
            NamespaceTypeDefinition ancestorClass = null;


            while (true)
            {
                // get class from which was inherited
                if (currentClass.BaseClasses.Count() == 1)
                {
                    // only add base classes of type NamespaceTypeDefinition
                    if (currentClass.BaseClasses.ElementAt(0) as NamespaceTypeDefinition != null)
                    {
                        ancestorClass = (currentClass.BaseClasses.ElementAt(0) as NamespaceTypeDefinition);
                    }
                    // ignore ancestor that are not of type NamespaceTypeDefinition
                    else
                    {
                        break;
                    }
                }
                else
                {
                    throw new ArgumentException("Do not know how to handle multiple inheritance.");
                }

                // add ancestor class to list of ancestor classes
                globalLog.writeLine("Found ancestor: " + ancestorClass.ToString());
                ancestorClasses.Add(ancestorClass);

                currentClass = ancestorClass;
            }

            // mrge class with ancenstor (start with the "highest" ancestor)
            for (int i = (ancestorClasses.Count - 1); i >= 0; i--)
            {
                globalLog.writeLine("Merge class \"" + ancestorClasses[i].ToString() + "\" with ancestor");
                mergeClassWithAncestor(ancestorClasses[i], host);
                globalLog.writeLine("");
            }
        }
        // adds the given interface to the given class
        public void addInterface(NamespaceTypeDefinition addTargetClass, ITypeDefinition interfaceToAdd)
        {
            // add interface to target class
            if (addTargetClass.Interfaces != null)
            {
                // check if interface is already implemented by class
                if (addTargetClass.Interfaces.Contains(interfaceToAdd))
                {
                    this.logger.writeLine("Class \"" + addTargetClass.ToString() + "\" already implements interface \"" + interfaceToAdd.ToString() + "\"");
                    return;
                }
                else
                {
                    this.logger.writeLine("Add interface \"" + interfaceToAdd.ToString() + "\" to class \"" + addTargetClass.ToString() + "\"");
                    addTargetClass.Interfaces.Add(interfaceToAdd);
                }
            }
            else
            {
                List <ITypeReference> interfaceList = new List <ITypeReference>();
                interfaceList.Add(interfaceToAdd);
                addTargetClass.Interfaces = interfaceList;
            }

            // copy all attributes from the interface to the target class
            if (interfaceToAdd.Fields != null)
            {
                foreach (FieldDefinition field in interfaceToAdd.Fields)
                {
                    FieldDefinition copy = new FieldDefinition();
                    this.helperClass.copyField(copy, field);
                    copy.ContainingTypeDefinition = addTargetClass;

                    // set intern factory of the copied field to the one of the class
                    // (without it, the generated binary file will have strange results like use only the same field)
                    copy.InternFactory = addTargetClass.InternFactory;

                    addTargetClass.Fields.Add(copy);
                }
            }

            // copy all methods from the interface to the target class
            if (interfaceToAdd.Methods != null)
            {
                foreach (IMethodDefinition method in interfaceToAdd.Methods)
                {
                    // search through all methods in the target class
                    // to see if this method was already added
                    bool foundMethod = false;
                    foreach (IMethodDefinition tempMethod in addTargetClass.Methods)
                    {
                        // skip constructors
                        if (tempMethod.IsConstructor)
                        {
                            continue;
                        }

                        // check if the number of parameters are the same
                        if (tempMethod.ParameterCount == method.ParameterCount)
                        {
                            // check if the parameters have the same type in the same order
                            bool parameterCorrect = true;
                            for (int i = 0; i < method.ParameterCount; i++)
                            {
                                if (method.Parameters.ElementAt(i).Type != tempMethod.Parameters.ElementAt(i).Type)
                                {
                                    parameterCorrect = false;
                                    break;
                                }
                            }

                            // check if the return type is the same
                            bool returnTypeCorrect = false;
                            if (method.Type.Equals(tempMethod.Type))
                            {
                                returnTypeCorrect = true;
                            }

                            // check if both methods are static
                            // (c# compiler does not allow static + non-static function with
                            // same signature in same class, but CIL does)
                            bool bothStatic = false;
                            if (method.IsStatic == tempMethod.IsStatic)
                            {
                                bothStatic = true;
                            }

                            // if the parameters and return type are correct => check the name
                            if (parameterCorrect && returnTypeCorrect && bothStatic)
                            {
                                if (method.Name.Equals(tempMethod.Name))
                                {
                                    // if name is the same => method already added
                                    foundMethod = true;
                                    break;
                                }
                            }
                        }
                    }
                    // skip if method was already added
                    if (foundMethod)
                    {
                        this.logger.writeLine("Method \"" + method.Name.ToString() + "\" already exists");
                        continue;
                    }

                    this.logger.writeLine("Add method: " + method.Name.ToString());

                    // copy method
                    MethodDefinition copy = new MethodDefinition();
                    this.helperClass.copyMethod(copy, method);
                    copy.ContainingTypeDefinition = addTargetClass;


                    // generate random dead code for newly created method
                    ILGenerator ilGenerator = new ILGenerator(host, method);
                    foreach (IOperation tempOperation in CodeGenerator.generateDeadCode(true))
                    {
                        ilGenerator.Emit(tempOperation.OperationCode, tempOperation.Value);
                    }
                    IMethodBody newBody = new ILGeneratorMethodBody(ilGenerator, true, 8, method, Enumerable <ILocalDefinition> .Empty, Enumerable <ITypeDefinition> .Empty);
                    copy.Body = newBody;



                    // set intern factory of the copied method to the one of the class
                    // (without it, the generated binary file will have strange results like call always the same method)
                    copy.InternFactory = addTargetClass.InternFactory;

                    // set method to not abstract
                    copy.IsAbstract = false;

                    // set method to not external
                    copy.IsExternal = false;

                    // set intern factory of the copied method to the one of the class
                    // (without it, the generating of the binary file will have strange results)
                    copy.InternFactory = addTargetClass.InternFactory;

                    // add method to the class
                    addTargetClass.Methods.Add(copy);
                }
            }
        }
        // adds the given interface to the given class
        public void addInterface(NamespaceTypeDefinition addTargetClass, ITypeDefinition interfaceToAdd) {
       

            // add interface to target class
            if (addTargetClass.Interfaces != null) {

                // check if interface is already implemented by class
                if (addTargetClass.Interfaces.Contains(interfaceToAdd)) {
                    this.logger.writeLine("Class \"" + addTargetClass.ToString() + "\" already implements interface \"" + interfaceToAdd.ToString() + "\"");
                    return;
                }
                else {
                    this.logger.writeLine("Add interface \"" + interfaceToAdd.ToString() + "\" to class \"" + addTargetClass.ToString() + "\"");
                    addTargetClass.Interfaces.Add(interfaceToAdd);
                }
            }      
            else {
                List<ITypeReference> interfaceList = new List<ITypeReference>();
                interfaceList.Add(interfaceToAdd);
                addTargetClass.Interfaces = interfaceList;
            }

            // copy all attributes from the interface to the target class
            if (interfaceToAdd.Fields != null) {
                foreach (FieldDefinition field in interfaceToAdd.Fields) {
                    FieldDefinition copy = new FieldDefinition();
                    this.helperClass.copyField(copy, field);
                    copy.ContainingTypeDefinition = addTargetClass;

                    // set intern factory of the copied field to the one of the class
                    // (without it, the generated binary file will have strange results like use only the same field)
                    copy.InternFactory = addTargetClass.InternFactory;

                    addTargetClass.Fields.Add(copy);
                }
            }

            // copy all methods from the interface to the target class
            if (interfaceToAdd.Methods != null) {
                foreach (IMethodDefinition method in interfaceToAdd.Methods) {

                    // search through all methods in the target class
                    // to see if this method was already added
                    bool foundMethod = false;
                    foreach (IMethodDefinition tempMethod in addTargetClass.Methods) {

                        // skip constructors
                        if (tempMethod.IsConstructor) {
                            continue;
                        }

                        // check if the number of parameters are the same
                        if (tempMethod.ParameterCount == method.ParameterCount) {

                            // check if the parameters have the same type in the same order
                            bool parameterCorrect = true;
                            for (int i = 0; i < method.ParameterCount; i++) {
                                if (method.Parameters.ElementAt(i).Type != tempMethod.Parameters.ElementAt(i).Type) {
                                    parameterCorrect = false;
                                    break;
                                }
                            }

                            // check if the return type is the same
                            bool returnTypeCorrect = false;
                            if (method.Type.Equals(tempMethod.Type)) {
                                returnTypeCorrect = true;
                            }

                            // check if both methods are static
                            // (c# compiler does not allow static + non-static function with
                            // same signature in same class, but CIL does)
                            bool bothStatic = false;
                            if (method.IsStatic == tempMethod.IsStatic) {
                                bothStatic = true;
                            }

                            // if the parameters and return type are correct => check the name
                            if (parameterCorrect && returnTypeCorrect && bothStatic) {
                                if (method.Name.Equals(tempMethod.Name)) {

                                    // if name is the same => method already added
                                    foundMethod = true;
                                    break;
                                }
                            }
                        }
                    }
                    // skip if method was already added
                    if (foundMethod) {
                        this.logger.writeLine("Method \"" + method.Name.ToString() + "\" already exists");
                        continue;
                    }

                    this.logger.writeLine("Add method: " + method.Name.ToString());

                    // copy method
                    MethodDefinition copy = new MethodDefinition();
                    this.helperClass.copyMethod(copy, method);
                    copy.ContainingTypeDefinition = addTargetClass;


                    // generate random dead code for newly created method
                    ILGenerator ilGenerator = new ILGenerator(host, method);
                    foreach (IOperation tempOperation in CodeGenerator.generateDeadCode(true)) {
                        ilGenerator.Emit(tempOperation.OperationCode, tempOperation.Value);
                    }
                    IMethodBody newBody = new ILGeneratorMethodBody(ilGenerator, true, 8, method, Enumerable<ILocalDefinition>.Empty, Enumerable<ITypeDefinition>.Empty);
                    copy.Body = newBody;



                    // set intern factory of the copied method to the one of the class
                    // (without it, the generated binary file will have strange results like call always the same method)
                    copy.InternFactory = addTargetClass.InternFactory;

                    // set method to not abstract
                    copy.IsAbstract = false;

                    // set method to not external
                    copy.IsExternal = false;

                    // set intern factory of the copied method to the one of the class
                    // (without it, the generating of the binary file will have strange results)
                    copy.InternFactory = addTargetClass.InternFactory;

                    // add method to the class
                    addTargetClass.Methods.Add(copy);
                }
            }
        }
Beispiel #4
0
        static void Main(string[] args)
        {
            String inputFile;
            String targetFile;
            String targetNamespace;
            String targetClass;
            String targetMethod;
            int    depth;
            int    dimension;
            int    numberValidPaths;
            int    duplicateBasicBlockWeight;
            int    duplicateBasicBlockCorrectionValue;
            int    stateChangeWeight;
            int    stateChangeCorrectionValue;
            int    insertOpaquePredicateWeight;
            int    seed;

            // Add debugging code into the obfuscated method (dump obfuscation graphs and so on)
            bool graphTransformerDebug = false;

            // Should the obfuscated code contain information to trace the control flow?
            bool basicBlockTrace = false;

            // When debugging is active, should the whole obfuscation graph be dumped or only the vpaths in it?
            bool graphOnlyDumpVPaths = true;

            // The number of random interfaces that are added to the program
            int numberRandomInterfaces = 100;

            if (args.Length != 14)
            {
                System.Console.WriteLine("Needed parameters: <inputBinary> <outputBinary> <namespace> <class> <method> <depth> <dimension> <numberValidPaths> <duplicateBasicBlockWeight> <duplicateBasicBlockCorrectionValue> <stateChangeWeight> <stateChangeCorrectionValue> <insertOpaquePredicateWeight> <seed>");
                return;
            }
            else
            {
                inputFile                          = args[0];
                targetFile                         = args[1];
                targetNamespace                    = args[2];
                targetClass                        = args[3];
                targetMethod                       = args[4];
                depth                              = Convert.ToInt32(args[5]);
                dimension                          = Convert.ToInt32(args[6]);
                numberValidPaths                   = Convert.ToInt32(args[7]);
                duplicateBasicBlockWeight          = Convert.ToInt32(args[8]);
                duplicateBasicBlockCorrectionValue = Convert.ToInt32(args[9]);
                stateChangeWeight                  = Convert.ToInt32(args[10]);
                stateChangeCorrectionValue         = Convert.ToInt32(args[11]);
                insertOpaquePredicateWeight        = Convert.ToInt32(args[12]);
                seed = Convert.ToInt32(args[13]);
            }

            String logDir = Path.GetDirectoryName(targetFile);

            Log.Log logger = new Log.Log(logDir, "probfuscation_logfile.txt");

            System.Console.WriteLine("Obfuscating: " + inputFile);
            logger.writeLine("Obfuscating: " + inputFile);
            System.Console.WriteLine("Output file: " + targetFile);
            logger.writeLine("Output file: " + targetFile);
            System.Console.WriteLine("Target namespace: " + targetNamespace);
            logger.writeLine("Target namespace: " + targetNamespace);
            System.Console.WriteLine("Target class: " + targetClass);
            logger.writeLine("Target class: " + targetClass);
            System.Console.WriteLine("Target method: " + targetMethod);
            logger.writeLine("Target method: " + targetMethod);
            System.Console.WriteLine("Depth: " + depth);
            logger.writeLine("Depth: " + depth);
            System.Console.WriteLine("Dimension: " + dimension);
            logger.writeLine("Dimension: " + dimension);
            System.Console.WriteLine("Number of vpaths: " + numberValidPaths);
            logger.writeLine("Number of vpaths: " + numberValidPaths);
            System.Console.WriteLine("Basic Block duplication weight: " + duplicateBasicBlockWeight);
            logger.writeLine("Basic Block duplication weight: " + duplicateBasicBlockWeight);
            System.Console.WriteLine("Basic Block duplication correction value: " + duplicateBasicBlockCorrectionValue);
            logger.writeLine("Basic Block duplication correction value: " + duplicateBasicBlockCorrectionValue);
            System.Console.WriteLine("State change weight: " + stateChangeWeight);
            logger.writeLine("State change weight: " + stateChangeWeight);
            System.Console.WriteLine("State change correction value: " + stateChangeCorrectionValue);
            logger.writeLine("State change correction value: " + stateChangeCorrectionValue);
            System.Console.WriteLine("Opaque predicate weight: " + insertOpaquePredicateWeight);
            logger.writeLine("Opaque predicate weight: " + insertOpaquePredicateWeight);
            System.Console.WriteLine("Seed: " + seed);
            logger.writeLine("Seed: " + seed);

            // Seed PRNG for interfaces
            PRNGRandomInterfaces = new Random(seed);

            using (var host = new PeReader.DefaultHost()) {
                IModule /*?*/ module = host.LoadUnitFrom(inputFile) as IModule;

                if (module == null || module == Dummy.Module || module == Dummy.Assembly)
                {
                    Console.WriteLine(inputFile + " is not a PE file containing a CLR module or assembly.");
                    return;
                }

                module = new MetadataDeepCopier(host).Copy(module);

                if (module as Assembly == null)
                {
                    logger.writeLine("File does not have CIL assembly");
                    return;
                }

                // create analyzer object object
                CfgBuilder analyze = new Cfg.CfgBuilder(module, host, logger);

                PdbReader /*?*/ pdbReader = null;
                string          pdbFile   = Path.ChangeExtension(module.Location, "pdb");
                if (File.Exists(pdbFile))
                {
                    using (var pdbStream = File.OpenRead(pdbFile)) {
                        pdbReader = new PdbReader(pdbStream, host);
                    }
                }
                else
                {
                    logger.writeLine("Could not load the PDB file for '" + module.Name.Value + "' . Proceeding anyway.");
                }

                using (pdbReader) {
                    Microsoft.Cci.ILGenerator.LocalScopeProvider localScopeProvider = null;
                    if (pdbReader != null)
                    {
                        localScopeProvider = new ILGenerator.LocalScopeProvider(pdbReader);
                    }

                    // search the namespace the interface should be added to
                    IUnitNamespace foundNamespace = null;
                    foreach (var tempMember in module.UnitNamespaceRoot.Members)
                    {
                        if ((tempMember as IUnitNamespace) == null)
                        {
                            continue;
                        }

                        IUnitNamespace tempNamespace = (tempMember as IUnitNamespace);

                        if (tempNamespace.ToString() == targetNamespace)
                        {
                            foundNamespace = tempNamespace;
                            break;
                        }
                    }
                    if (foundNamespace == null)
                    {
                        throw new ArgumentException("Not able to find target namespace.");
                    }

                    // add created interface (and implemented methods) to all classes
                    bool classFound = false;
                    foreach (var tempClass in module.GetAllTypes())
                    {
                        if ((tempClass as NamespaceTypeDefinition) == null ||
                            tempClass.IsAbstract)
                        {
                            continue;
                        }

                        NamespaceTypeDefinition foundClass = (tempClass as NamespaceTypeDefinition);

                        if (foundClass.ContainingUnitNamespace.ToString() == "")
                        {
                            continue;
                        }
                        if (foundClass.ToString() != targetNamespace + "." + targetClass)
                        {
                            continue;
                        }
                        classFound = true;

                        Random           prng             = new Random();
                        GraphTransformer graphTransformer = new GraphTransformer(module, host, logger, prng, foundNamespace, foundClass, depth, dimension, graphTransformerDebug);

                        graphTransformer.duplicateBasicBlockWeight          = duplicateBasicBlockWeight;
                        graphTransformer.duplicateBasicBlockCorrectionValue = duplicateBasicBlockCorrectionValue;
                        graphTransformer.stateChangeWeight           = stateChangeWeight;
                        graphTransformer.stateChangeCorrectionValue  = stateChangeCorrectionValue;
                        graphTransformer.insertOpaquePredicateWeight = insertOpaquePredicateWeight;
                        graphTransformer.trace = basicBlockTrace;
                        graphTransformer.graphOnlyDumpVPaths   = graphOnlyDumpVPaths;
                        graphTransformer.debuggingDumpLocation = logDir;

                        // Add 100 random interfaces to the namespace
                        Helper testHelper = new Helper(module, host, logger);
                        List <NamespaceTypeDefinition> randomInterfaces = new List <NamespaceTypeDefinition>();
                        for (int i = 0; i < numberRandomInterfaces; i++)
                        {
                            String randName = randomString(20);
                            NamespaceTypeDefinition temp = testHelper.createNewInterface(randName, foundNamespace);
                            randomInterfaces.Add(temp);
                        }

                        InterfaceTransformer interfaceTransformer = new InterfaceTransformer(module, host, logger);
                        foreach (var classToAdd in module.GetAllTypes())
                        {
                            if ((classToAdd as NamespaceTypeDefinition) == null ||
                                classToAdd.IsAbstract ||
                                classToAdd.IsInterface ||
                                classToAdd.IsEnum ||
                                classToAdd.IsDelegate ||
                                classToAdd.IsGeneric ||
                                classToAdd.IsStruct)
                            {
                                continue;
                            }

                            if (((NamespaceTypeDefinition)classToAdd).ContainingUnitNamespace.ToString() == "")
                            {
                                continue;
                            }

                            /*
                             * // Use this code if you want to add standard interfaces to the target class
                             * interfaceTransformer.addStdInterfacesGivenByFile(@"e:\code\dotnet_standard_interfaces.txt");
                             *
                             * // add std interfaces to class
                             * if (foundClass != (classToAdd as NamespaceTypeDefinition)) {
                             *  foreach (ITypeDefinition temp in interfaceTransformer.getInterfacesList()) {
                             *      interfaceTransformer.addInterface((classToAdd as NamespaceTypeDefinition), temp);
                             *  }
                             * }
                             */

                            // Add random interfaces to the classes
                            List <NamespaceTypeDefinition> alreadyAdded = new List <NamespaceTypeDefinition>();
                            int max = PRNGRandomInterfaces.Next(numberRandomInterfaces);
                            NamespaceTypeDefinition interfaceClass = (classToAdd as NamespaceTypeDefinition);
                            logger.writeLine("Adding " + max + " random interfaces to class \"" + interfaceClass.ToString() + "\"");
                            for (int i = 0; i < max; i++)
                            {
                                NamespaceTypeDefinition randInterface = randomInterfaces.ElementAt(PRNGRandomInterfaces.Next(randomInterfaces.Count));
                                if (alreadyAdded.Contains(randInterface))
                                {
                                    continue;
                                }
                                alreadyAdded.Add(randInterface);
                                logger.writeLine("Adding interface: \"" + randInterface.ToString() + "\"");

                                // add nodes interface to class
                                if (interfaceClass.Interfaces != null)
                                {
                                    interfaceClass.Interfaces.Add(randInterface);
                                }
                                else
                                {
                                    interfaceClass.Interfaces = new List <ITypeReference>();
                                    interfaceClass.Interfaces.Add(randInterface);
                                }
                            }
                            logger.writeLine("");

                            // Add special interface for the obfuscation scheme to the class
                            // (makes sure that all needed attributes and methods are implemented)
                            graphTransformer.addNodeInterfaceToTargetClass((classToAdd as NamespaceTypeDefinition));
                        }

                        // Prepare obfuscation graph
                        graphTransformer.generateGraph(numberValidPaths);
                        graphTransformer.createGraphMethods();

                        // Search method to obfuscate
                        MethodDefinition methodToObfu = null;
                        foreach (MethodDefinition tempMethod in foundClass.Methods)
                        {
                            if (tempMethod.Name.ToString() == targetMethod)
                            {
                                methodToObfu = tempMethod;
                                break;
                            }
                        }
                        if (methodToObfu == null)
                        {
                            throw new ArgumentException("Not able to find target method.");
                        }

                        // Obfuscate target method
                        MethodCfg cfg = analyze.buildCfgForMethod(methodToObfu);
                        logger.dumpMethodCfg(cfg, "before");
                        graphTransformer.addObfuscationToMethod(cfg);
                        analyze.createMethodFromCfg(cfg);
                        logger.dumpMethodCfg(cfg, "after");

                        break;
                    }
                    if (!classFound)
                    {
                        throw new ArgumentException("Not able to find target class.");
                    }


                    /*
                     * This code can be used if not only one specific method should be obfuscated,
                     * but the whole class.
                     * List<ClassCfg> classCfgList = new List<ClassCfg>();
                     * foreach (var tempClass in module.GetAllTypes()) {
                     *  if ((tempClass as NamespaceTypeDefinition) == null
                     || tempClass.IsAbstract) {
                     ||     continue;
                     || }
                     ||
                     || // create basic blocks
                     || NamespaceTypeDefinition foundClass = (tempClass as NamespaceTypeDefinition);
                     ||
                     || logger.writeLine("Create CFG for class \"" + foundClass.Name.ToString() + "\"");
                     || ClassCfg temp = analyze.buildCfgForClass(foundClass);
                     || classCfgList.Add(temp);
                     || logger.writeLine("\n---------------------------------\n");
                     ||}
                     ||
                     ||// transform each function
                     ||NopTransformer transformator = new NopTransformer(module, host, logger);
                     ||foreach (ClassCfg tempClassCfg in classCfgList) {
                     || foreach (MethodCfg tempMethodCfg in tempClassCfg.methodCfgs) {
                     ||     logger.writeLine("Transform method CFG of \"" + tempMethodCfg.method.ToString() + "\"");
                     ||     transformator.addNopsToCfg(tempMethodCfg);
                     ||     logger.writeLine("\n---------------------------------\n");
                     || }
                     ||}
                     ||
                     ||foreach (ClassCfg tempClassCfg in classCfgList) {
                     || logger.writeLine("Create class from CFG for \"" + tempClassCfg.classObj.Name.ToString() + "\"");
                     || analyze.createClassFromCfg(tempClassCfg);
                     || logger.writeLine("\n---------------------------------\n");
                     ||}
                     */

                    using (var peStream = File.Create(targetFile)) {
                        using (var pdbWriter = new PdbWriter(Path.ChangeExtension(targetFile, ".pdb"), pdbReader)) {
                            PeWriter.WritePeToStream(module, host, peStream, pdbReader, localScopeProvider, pdbWriter);
                        }
                    }
                }
            }
        }
        // this function adds the created iNode interface to the class and also implements all neded functions
        public void addNodeInterfaceToTargetClass(NamespaceTypeDefinition givenClass) {

            this.logger.writeLine("");
            this.logger.writeLine("Add node interface \"" + this.nodeInterface.ToString() + "\" to class \"" + givenClass.ToString() + "\"");

            // check if generated interface was already added to target class
            if (givenClass.Interfaces != null
                && givenClass.Interfaces.Contains(this.nodeInterface)) {
                this.logger.writeLine("Class \"" + givenClass.ToString() + "\" already contains node interface \"" + this.nodeInterface.ToString() + "\"");
                return;
            }

            // add nodes interface to class
            if (givenClass.Interfaces != null) {
                givenClass.Interfaces.Add(this.nodeInterface);
            }
            else {
                givenClass.Interfaces = new List<ITypeReference>();
                givenClass.Interfaces.Add(this.nodeInterface);
            }

            // add start pointer field
            FieldDefinition startPointerField = new FieldDefinition();
            startPointerField.IsCompileTimeConstant = false;
            startPointerField.IsNotSerialized = false;
            startPointerField.IsReadOnly = false;
            startPointerField.IsRuntimeSpecial = false;
            startPointerField.IsSpecialName = false;
            startPointerField.Type = this.nodeInterface;
            startPointerField.IsStatic = false;
            startPointerField.Visibility = TypeMemberVisibility.Public;
            startPointerField.Name = host.NameTable.GetNameFor("startPointer");
            startPointerField.InternFactory = host.InternFactory;
            startPointerField.ContainingTypeDefinition = givenClass;
            if (givenClass.Fields != null) {
                givenClass.Fields.Add(startPointerField);
            }
            else {
                givenClass.Fields = new List<IFieldDefinition>();
                givenClass.Fields.Add(startPointerField);
            }

            // create getter for the startPointer variable
            MethodDefinition startPointerGetMethod = this.helperClass.createNewMethod("startPointer_get", givenClass, this.nodeInterface, TypeMemberVisibility.Public, null, CallingConvention.HasThis, false, false, true); // TODO: method name

            // create a body for the getter method
            ILGenerator ilGenerator = new ILGenerator(host, startPointerGetMethod);
            ilGenerator.Emit(OperationCode.Ldarg_0);
            ilGenerator.Emit(OperationCode.Ldfld, startPointerField);
            ilGenerator.Emit(OperationCode.Ret);
            IMethodBody body = new ILGeneratorMethodBody(ilGenerator, true, 1, startPointerGetMethod, Enumerable<ILocalDefinition>.Empty, Enumerable<ITypeDefinition>.Empty);
            startPointerGetMethod.Body = body;

            // create setter for the startPointer variable
            List<IParameterDefinition> parameters = new List<IParameterDefinition>();
            ParameterDefinition parameter = new ParameterDefinition();
            parameter.IsIn = false;
            parameter.IsOptional = false;
            parameter.IsOut = false;
            parameter.Name = host.NameTable.GetNameFor("value");
            parameter.Type = this.nodeInterface;
            parameters.Add(parameter);
            MethodDefinition startPointerSetMethod = this.helperClass.createNewMethod("startPointer_set", givenClass, host.PlatformType.SystemVoid, TypeMemberVisibility.Public, parameters, CallingConvention.HasThis, false, false, true); // TODO: method name

            // create a body for the setter method
            ilGenerator = new ILGenerator(host, startPointerSetMethod);
            ilGenerator.Emit(OperationCode.Ldarg_0);
            ilGenerator.Emit(OperationCode.Ldarg_1);
            ilGenerator.Emit(OperationCode.Stfld, startPointerField);
            ilGenerator.Emit(OperationCode.Ret);
            body = new ILGeneratorMethodBody(ilGenerator, true, 1, startPointerSetMethod, Enumerable<ILocalDefinition>.Empty, Enumerable<ITypeDefinition>.Empty);
            startPointerSetMethod.Body = body;

            // add childNodes array field
            FieldDefinition childNodesField = new FieldDefinition();
            childNodesField.IsCompileTimeConstant = false;
            childNodesField.IsNotSerialized = false;
            childNodesField.IsReadOnly = false;
            childNodesField.IsRuntimeSpecial = false;
            childNodesField.IsSpecialName = false;
            // create array of node interface type
            VectorTypeReference nodeInterfaceArrayType = new VectorTypeReference();
            nodeInterfaceArrayType.ElementType = this.nodeInterface;
            nodeInterfaceArrayType.Rank = 1;
            nodeInterfaceArrayType.IsFrozen = true;
            nodeInterfaceArrayType.IsValueType = false;
            nodeInterfaceArrayType.InternFactory = host.InternFactory;
            childNodesField.Type = nodeInterfaceArrayType;

            childNodesField.IsStatic = false;
            childNodesField.Visibility = TypeMemberVisibility.Public;
            childNodesField.Name = host.NameTable.GetNameFor("childNodes");
            childNodesField.InternFactory = host.InternFactory;
            childNodesField.ContainingTypeDefinition = givenClass;
            givenClass.Fields.Add(childNodesField);

            // create getter for the childNodes variable
            parameters = new List<IParameterDefinition>();
            // int parameter
            parameter = new ParameterDefinition();
            parameter.IsIn = false;
            parameter.IsOptional = false;
            parameter.IsOut = false;
            parameter.Type = this.host.PlatformType.SystemInt32;
            parameters.Add(parameter);
            MethodDefinition childNodesGetMethod = this.helperClass.createNewMethod("childNodes_get", givenClass, this.nodeInterface, TypeMemberVisibility.Public, parameters, CallingConvention.HasThis, false, false, true); // TODO: method name

            // create a body for the getter method
            ilGenerator = new ILGenerator(host, childNodesGetMethod);
            ilGenerator.Emit(OperationCode.Ldarg_0);
            ilGenerator.Emit(OperationCode.Ldfld, childNodesField);
            ilGenerator.Emit(OperationCode.Ldarg_1);
            ilGenerator.Emit(OperationCode.Ldelem_Ref);
            ilGenerator.Emit(OperationCode.Ret);
            body = new ILGeneratorMethodBody(ilGenerator, true, 1, childNodesGetMethod, Enumerable<ILocalDefinition>.Empty, Enumerable<ITypeDefinition>.Empty);
            childNodesGetMethod.Body = body;

            // create setter for the childNodes variable
            parameters = new List<IParameterDefinition>();
            // iNode parameter
            parameter = new ParameterDefinition();
            parameter.IsIn = false;
            parameter.IsOptional = false;
            parameter.IsOut = false;
            parameter.Type = this.nodeInterface;
            parameters.Add(parameter);
            // int parameter
            parameter = new ParameterDefinition();
            parameter.IsIn = false;
            parameter.IsOptional = false;
            parameter.IsOut = false;
            parameter.Type = this.host.PlatformType.SystemInt32;
            parameters.Add(parameter);
            MethodDefinition childNodesSetMethod = this.helperClass.createNewMethod("childNodes_set", givenClass, host.PlatformType.SystemVoid, TypeMemberVisibility.Public, parameters, CallingConvention.HasThis, false, false, true); // TODO: method name

            // create a body for the setter method
            ilGenerator = new ILGenerator(host, childNodesSetMethod);
            ilGenerator.Emit(OperationCode.Ldarg_0);
            ilGenerator.Emit(OperationCode.Ldfld, childNodesField);
            ilGenerator.Emit(OperationCode.Ldarg_2);
            ilGenerator.Emit(OperationCode.Ldarg_1);
            ilGenerator.Emit(OperationCode.Stelem_Ref);
            ilGenerator.Emit(OperationCode.Ret);
            body = new ILGeneratorMethodBody(ilGenerator, true, 1, childNodesSetMethod, Enumerable<ILocalDefinition>.Empty, Enumerable<ITypeDefinition>.Empty);
            childNodesSetMethod.Body = body;

            // add current node field
            FieldDefinition currentNodeField = new FieldDefinition();
            currentNodeField.IsCompileTimeConstant = false;
            currentNodeField.IsNotSerialized = false;
            currentNodeField.IsReadOnly = false;
            currentNodeField.IsRuntimeSpecial = false;
            currentNodeField.IsSpecialName = false;
            currentNodeField.Type = this.nodeInterface;
            currentNodeField.IsStatic = false;
            currentNodeField.Visibility = TypeMemberVisibility.Public;
            currentNodeField.Name = host.NameTable.GetNameFor("currentNode");
            currentNodeField.InternFactory = host.InternFactory;
            currentNodeField.ContainingTypeDefinition = givenClass;
            givenClass.Fields.Add(currentNodeField);

            // create getter for the currentNode variable
            MethodDefinition currentNodeGetMethod = this.helperClass.createNewMethod("currentNode_get", givenClass, this.nodeInterface, TypeMemberVisibility.Public, null, CallingConvention.HasThis, false, false, true); // TODO: method name

            // create a body for the getter method
            ilGenerator = new ILGenerator(host, currentNodeGetMethod);
            ilGenerator.Emit(OperationCode.Ldarg_0);
            ilGenerator.Emit(OperationCode.Ldfld, currentNodeField);
            ilGenerator.Emit(OperationCode.Ret);
            body = new ILGeneratorMethodBody(ilGenerator, true, 1, currentNodeGetMethod, Enumerable<ILocalDefinition>.Empty, Enumerable<ITypeDefinition>.Empty);
            currentNodeGetMethod.Body = body;

            // create setter for the currentNode variable
            parameters = new List<IParameterDefinition>();
            parameter = new ParameterDefinition();
            parameter.IsIn = false;
            parameter.IsOptional = false;
            parameter.IsOut = false;
            parameter.Name = host.NameTable.GetNameFor("value");
            parameter.Type = this.nodeInterface;
            parameters.Add(parameter);
            MethodDefinition currentNodeSetMethod = this.helperClass.createNewMethod("currentNode_set", givenClass, host.PlatformType.SystemVoid, TypeMemberVisibility.Public, parameters, CallingConvention.HasThis, false, false, true); // TODO: method name

            // create a body for the setter method
            ilGenerator = new ILGenerator(host, currentNodeSetMethod);
            ilGenerator.Emit(OperationCode.Ldarg_0);
            ilGenerator.Emit(OperationCode.Ldarg_1);
            ilGenerator.Emit(OperationCode.Stfld, currentNodeField);
            ilGenerator.Emit(OperationCode.Ret);
            body = new ILGeneratorMethodBody(ilGenerator, true, 1, currentNodeSetMethod, Enumerable<ILocalDefinition>.Empty, Enumerable<ITypeDefinition>.Empty);
            currentNodeSetMethod.Body = body;

            // check if debugging is activated
            // => add graph debugging attributes and methods
            MethodDefinition objectIdGetMethod = null;
            FieldDefinition objectIdField = null;
            if (this.debugging) {

                this.logger.writeLine("Debugging activated: Adding field for unique object id and getter method");

                // add objectId field
                objectIdField = new FieldDefinition();
                objectIdField.IsCompileTimeConstant = false;
                objectIdField.IsNotSerialized = false;
                objectIdField.IsReadOnly = false;
                objectIdField.IsRuntimeSpecial = false;
                objectIdField.IsSpecialName = false;
                objectIdField.Type = this.host.PlatformType.SystemString;
                objectIdField.IsStatic = false;
                objectIdField.Name = host.NameTable.GetNameFor("DEBUG_objectId");
                objectIdField.Visibility = TypeMemberVisibility.Public;
                objectIdField.InternFactory = host.InternFactory;
                objectIdField.ContainingTypeDefinition = givenClass;
                givenClass.Fields.Add(objectIdField);

                // create getter for the objectId variable
                objectIdGetMethod = this.helperClass.createNewMethod("DEBUG_objectId_get", givenClass, this.host.PlatformType.SystemString, TypeMemberVisibility.Public, null, CallingConvention.HasThis, false, false, true); // TODO: method name

                // create a body for the getter method
                ilGenerator = new ILGenerator(host, objectIdGetMethod);
                ilGenerator.Emit(OperationCode.Ldarg_0);
                ilGenerator.Emit(OperationCode.Ldfld, objectIdField);
                ilGenerator.Emit(OperationCode.Ret);
                body = new ILGeneratorMethodBody(ilGenerator, true, 1, objectIdGetMethod, Enumerable<ILocalDefinition>.Empty, Enumerable<ITypeDefinition>.Empty);
                objectIdGetMethod.Body = body;

            }

            // add .ctor(iNode) to target class
            parameters = new List<IParameterDefinition>();
            parameter = new ParameterDefinition();
            parameter.IsIn = false;
            parameter.IsOptional = false;
            parameter.IsOut = false;
            parameter.Type = this.nodeInterface;
            parameters.Add(parameter);

            MethodDefinition nodeConstructor = this.helperClass.createNewMethod(".ctor", givenClass, host.PlatformType.SystemVoid, TypeMemberVisibility.Public, parameters, CallingConvention.HasThis, false, false, false);
            nodeConstructor.IsSpecialName = true;
            nodeConstructor.IsHiddenBySignature = true;
            nodeConstructor.IsRuntimeSpecial = true;

            // generate node constructor body
            ilGenerator = new ILGenerator(host, currentNodeSetMethod);

            // create local variable list
            List<ILocalDefinition> localVariables = new List<ILocalDefinition>();

            // call system.object constructor
            ilGenerator.Emit(OperationCode.Ldarg_0);
            ilGenerator.Emit(OperationCode.Call, this.helperClass.objectCtor);

            // initialize childNodes array
            ilGenerator.Emit(OperationCode.Ldarg_0);
            ilGenerator.Emit(OperationCode.Ldc_I4, this.graphDimension);
            ilGenerator.Emit(OperationCode.Newarr, nodeInterfaceArrayType);
            ilGenerator.Emit(OperationCode.Stfld, childNodesField);

            // check if debugging is activated
            // => add code to constructor that generates a unique id for this object
            if (this.debugging) {

                this.logger.writeLine("Debugging activated: Adding code to generate unique id to node constructor");

                // create local integer variable needed for debugging code
                LocalDefinition intLocal = new LocalDefinition();
                intLocal.IsReference = false;
                intLocal.IsPinned = false;
                intLocal.IsModified = false;
                intLocal.Type = this.host.PlatformType.SystemInt32;
                intLocal.MethodDefinition = nodeConstructor;
                localVariables.Add(intLocal);

                // use the hash code of this instance as unique object id
                ilGenerator.Emit(OperationCode.Ldarg_0);
                ilGenerator.Emit(OperationCode.Ldarg_0);
                ilGenerator.Emit(OperationCode.Callvirt, this.helperClass.objectGetHashCode);
                ilGenerator.Emit(OperationCode.Stloc, intLocal);

                // cast random integer to string and store in object id
                ilGenerator.Emit(OperationCode.Ldloca, intLocal);
                ilGenerator.Emit(OperationCode.Call, this.helperClass.int32ToString);
                ilGenerator.Emit(OperationCode.Stfld, objectIdField);

            }

            ilGenerator.Emit(OperationCode.Ret);
            body = new ILGeneratorMethodBody(ilGenerator, true, 8, nodeConstructor, localVariables, Enumerable<ITypeDefinition>.Empty);
            nodeConstructor.Body = body;


            // add class to the list of possible nodes for the graph
            PossibleNode tempStruct = new PossibleNode();
            tempStruct.nodeConstructor = nodeConstructor;
            tempStruct.givenClass = givenClass;

            // for each interface the class implements add it to the according list
            foreach (ITypeReference interfaceRef in givenClass.Interfaces) {

                this.logger.writeLine("Add class \"" + givenClass.ToString() + "\" to graph interface list \"" + interfaceRef.ToString() + "\"");

                // check if a list with this interface already exists
                // => if it does just add current class to list
                if (this.graphInterfaces.ContainsKey(interfaceRef)) {
                    List<PossibleNode> tempList = (List<PossibleNode>)this.graphInterfaces[interfaceRef];
                    tempList.Add(tempStruct);
                }
                // if not => add new list for this interface
                else {
                    List<PossibleNode> tempList = new List<PossibleNode>();
                    tempList.Add(tempStruct);
                    this.graphInterfaces.Add(interfaceRef, tempList);
                }
            }

            this.logger.writeLine("");

        }
Beispiel #6
0
        static void Main(string[] args)
        {
            //String inputFile = @"c:\Users\typ\Documents\Visual Studio 2013\Projects\vererbung\vererbung\bin\Debug\vererbung.exe";
            String inputFile = @"e:\dile_v0_2_12_x86\Dile.exe";



            globalLog = new Log(@"e:\merge_logfile.txt");

            System.Console.WriteLine(inputFile);

            /*
             * if (args == null || args.Length == 0)
             * {
             *  Console.WriteLine("Usage: ILMutator <assembly> [<outputPath>]");
             *  return;
             * }
             */



            using (var host = new PeReader.DefaultHost()) {
                //IModule/*?*/ module = host.LoadUnitFrom(args[0]) as IModule;
                IModule /*?*/ module = host.LoadUnitFrom(inputFile) as IModule;



                if (module == null || module == Dummy.Module || module == Dummy.Assembly)
                {
                    //Console.WriteLine(args[0] + " is not a PE file containing a CLR module or assembly.");
                    Console.WriteLine(inputFile + " is not a PE file containing a CLR module or assembly.");
                    return;
                }

                module = new MetadataDeepCopier(host).Copy(module);

                if (module as Assembly == null)
                {
                    globalLog.writeLine("File does not have CIL assembly");
                    return;
                }


                PdbReader /*?*/ pdbReader = null;
                string          pdbFile   = Path.ChangeExtension(module.Location, "pdb");
                if (File.Exists(pdbFile))
                {
                    using (var pdbStream = File.OpenRead(pdbFile)) {
                        pdbReader = new PdbReader(pdbStream, host);
                    }
                }
                else
                {
                    globalLog.writeLine("Could not load the PDB file for '" + module.Name.Value + "' . Proceeding anyway.");
                }

                using (pdbReader) {
                    Microsoft.Cci.ILGenerator.LocalScopeProvider localScopeProvider = null;
                    if (pdbReader != null)
                    {
                        localScopeProvider = new ILGenerator.LocalScopeProvider(pdbReader);
                    }



                    // AB HIER DER INTERESSANTE PART ZUM MERGEN, DAVOR NUR INIT CRAP

                    // search for class in namespace
                    NamespaceTypeDefinition foundClass = null;
                    foreach (var asdf in module.GetAllTypes())
                    {
                        //if (asdf.ToString() == "vererbung.Erber") {
                        if (asdf.ToString() == "Dile.Disassemble.Assembly")
                        {
                            foundClass = (asdf as NamespaceTypeDefinition);
                            break;
                        }
                    }
                    if (foundClass == null)
                    {
                        globalLog.writeLine("Class not found!");
                        return;
                    }

                    // merge class
                    globalLog.writeLine("Merge class \"" + foundClass.ToString() + "\" with all ancestors");
                    mergeClassWithAllAncestors(foundClass, host);



                    string newName;
                    if (args.Length == 2)
                    {
                        newName = args[1];
                        //newName = @"e:\dile_v0_2_12_x86\dile_classes.exe";
                        newName = @"e:\test.exe";
                    }
                    else
                    {
                        var loc      = module.Location;
                        var path     = Path.GetDirectoryName(loc) ?? "";
                        var fileName = Path.GetFileNameWithoutExtension(loc);
                        var ext      = Path.GetExtension(loc);
                        newName = Path.Combine(path, fileName + "1" + ext);
                        //newName = @"e:\dile_v0_2_12_x86\dile_classes.exe";
                        newName = @"e:\test.exe";
                    }

                    using (var peStream = File.Create(newName)) {
                        using (var pdbWriter = new PdbWriter(Path.ChangeExtension(newName, ".pdb"), pdbReader)) {
                            PeWriter.WritePeToStream(module, host, peStream, pdbReader, localScopeProvider, pdbWriter);
                        }
                    }
                }
            }
        }
Beispiel #7
0
        static void mergeClassWithAncestor(NamespaceTypeDefinition mergeTargetClass, PeReader.DefaultHost host)
        {
            // get class from which was inherited
            ITypeDefinition ancestorClass     = null;
            INamedEntity    ancestorClassName = null;

            if (mergeTargetClass.BaseClasses.Count == 1)
            {
                // TODO
                // entferne wenn Methode umgeschrieben

                /*
                 * // ignore inheritance from System.Object
                 * if (mergeTargetClass.BaseClasses[0].ToString() != "System.Object") {
                 *  ancestorClass = (mergeTargetClass.BaseClasses[0] as NamespaceTypeDefinition);
                 * }
                 * // return if ancestor class equals System.Object
                 * else {
                 *  return;
                 * }
                 */



                // check base class is of type NamespaceTypeDefinition
                if (mergeTargetClass.BaseClasses.ElementAt(0) as NamespaceTypeDefinition != null)
                {
                    ancestorClass     = (mergeTargetClass.BaseClasses.ElementAt(0) as ITypeDefinition);
                    ancestorClassName = (mergeTargetClass.BaseClasses.ElementAt(0) as INamedEntity);
                }
                // ignore inheritance from System.Object
                else if (mergeTargetClass.BaseClasses[0].ToString() == "System.Object")
                {
                    return;
                }
                // check for needed values in base class and its resolved value (for example when base class of type NamespaceTypeReference)
                else if ((mergeTargetClass.BaseClasses.ElementAt(0).ResolvedType as ITypeDefinition != null) &&
                         (mergeTargetClass.BaseClasses.ElementAt(0) as INamedEntity != null))
                {
                    // TODO
                    // weiss nicht ob es Sinn macht externe Klassen wie z.B. system.ValueType
                    // in die aktuelle Klasse rein zu mergen => denn Trick mit methoden auf Virtual stellen
                    // damit JIT Compiler unsere Methoden aufruft klappt nicht in dem Fall (da wir die Methoden von System.ValueType nicht umschreiben koennen)
                    //ancestorClass = (mergeTargetClass.BaseClasses[0].ResolvedType as ITypeDefinition);
                    //ancestorClassName = (mergeTargetClass.BaseClasses[0].ResolvedType as INamedEntity);
                    return;
                }
                else
                {
                    throw new ArgumentException("Do not know how to handle base class.");
                }
            }
            else
            {
                throw new ArgumentException("Do not know how to handle multiple inheritance.");
            }


            // copy all attributes from the ancestor class to the current class
            if (ancestorClass.Fields != null)
            {
                globalLog.writeLine("Copying fileds");
                foreach (FieldDefinition field in ancestorClass.Fields)
                {
                    FieldDefinition copy = new FieldDefinition();
                    globalLog.writeLine("Copying field: " + field.Name.ToString());
                    copyField(copy, field);
                    copy.ContainingTypeDefinition = mergeTargetClass;

                    // set intern factory of the copied field to the one of the class
                    // (without it, the generated binary file will have strange results like use only the same field)
                    copy.InternFactory = mergeTargetClass.InternFactory;

                    mergeTargetClass.Fields.Add(copy);
                }
                globalLog.writeLine("");
            }

            // list of all constructors of the ancestor class
            List <MethodDefinition> copiedAncestorConstructors = new List <MethodDefinition>();

            // copy methods from the ancestor class to the current class
            if (ancestorClass.Methods != null)
            {
                globalLog.writeLine("Copying methods");
                foreach (IMethodDefinition method in ancestorClass.Methods)
                {
                    globalLog.writeLine("Copying method: " + method.Name.ToString());

                    // check if the method is a constructor
                    if (method.IsConstructor)
                    {
                        MethodDefinition copiedAncestorConstructor = new MethodDefinition();
                        copyMethod(copiedAncestorConstructor, method, host);

                        // TODO
                        // name muss noch geaendert werden
                        String tempName = "ctor_" + ancestorClassName.Name.ToString();
                        copiedAncestorConstructor.Name = host.NameTable.GetNameFor(tempName);

                        // constructor has the "SpecialName" (the name describes the functionality)
                        // and "RTSpecialName" (runtime should check name encoding) flag set
                        // runtime will raise an exception if these flags are set for a copied constructor
                        // which is added as a normal function
                        copiedAncestorConstructor.IsSpecialName    = false;
                        copiedAncestorConstructor.IsRuntimeSpecial = false;



                        // TODO:
                        // vielleicht einfach von späterer Schleife machen lassen (sollte jetzt schon gehen, aber noch nicht getestet,
                        // deshalb erst ein mal drin gelassen)
                        // copy constructor and rewrite instructions to use attributes and functions
                        // inside the same class
                        var testIlGenerator = new ILGenerator(host, copiedAncestorConstructor);
                        foreach (var operation in copiedAncestorConstructor.Body.Operations)
                        {
                            switch (operation.OperationCode)
                            {
                            case OperationCode.Call:

                                // HIER NOCH CHECKEN OB ANDERE FUNKTIONEN INNERHALB DES ANCESTORS AUFGERUFEN WERDEN
                                // DIESE MUESSEN UMGELEITET WERDEN

                                /*
                                 * Microsoft.Cci.MutableCodeModel.MethodDefinition blah = null;
                                 * if (operation.Value is Microsoft.Cci.MutableCodeModel.MethodDefinition) {
                                 *  blah = (Microsoft.Cci.MutableCodeModel.MethodDefinition)(operation.Value);
                                 *  NamespaceTypeDefinition test = (NamespaceTypeDefinition)blah.ContainingTypeDefinition;
                                 *
                                 *  if (ancestorClass.Name.Equals(test.Name)) {
                                 *      System.Console.WriteLine("Ja");
                                 *  }
                                 *
                                 *
                                 * }
                                 */

                                testIlGenerator.Emit(operation.OperationCode, operation.Value);
                                break;

                            case OperationCode.Stfld:

                                FieldDefinition attribute = (FieldDefinition)operation.Value;

                                // search for the method attribute that is used in the copied constructor
                                // and replace it with the method attribute from the current class
                                FieldDefinition foundField = null;
                                foreach (FieldDefinition field in mergeTargetClass.Fields)
                                {
                                    if (attribute.Name.Equals(field.Name) &&
                                        attribute.Type.Equals(field.Type))
                                    {
                                        foundField = field;
                                        break;
                                    }
                                }
                                if (foundField == null)
                                {
                                    System.Console.WriteLine("Attribute not found");
                                    return;
                                }

                                testIlGenerator.Emit(operation.OperationCode, foundField);

                                break;

                            default:
                                testIlGenerator.Emit(operation.OperationCode, operation.Value);
                                break;
                            }
                        }

                        // create new body
                        List <ILocalDefinition> variableListCopy           = new List <ILocalDefinition>(method.Body.LocalVariables);
                        List <ITypeDefinition>  privateHelperTypesListCopy = new List <ITypeDefinition>(method.Body.PrivateHelperTypes);
                        var newBody = new ILGeneratorMethodBody(testIlGenerator, method.Body.LocalsAreZeroed, method.Body.MaxStack, copiedAncestorConstructor, variableListCopy, privateHelperTypesListCopy);
                        copiedAncestorConstructor.Body = newBody;

                        // set intern factory of the copied constructor to the one of the class
                        // (without it, the generated binary file will have strange results like call always the same method)
                        copiedAncestorConstructor.InternFactory = mergeTargetClass.InternFactory;

                        // add copied constructor to the class
                        copiedAncestorConstructor.ContainingTypeDefinition = mergeTargetClass;
                        copiedAncestorConstructor.Visibility = TypeMemberVisibility.Private;
                        mergeTargetClass.Methods.Add(copiedAncestorConstructor);

                        // add copied ancestor constructor to the list of copied ancestor constructors
                        copiedAncestorConstructors.Add(copiedAncestorConstructor);

                        continue;
                    }

                    else
                    {
                        // copy method
                        MethodDefinition copy = new MethodDefinition();
                        copyMethod(copy, method, host);
                        copy.ContainingTypeDefinition = mergeTargetClass;

                        // set intern factory of the copied method to the one of the class
                        // (without it, the generating of the binary file will have strange results)
                        copy.InternFactory = mergeTargetClass.InternFactory;

                        // add method to the class
                        if (mergeTargetClass.Methods == null)
                        {
                            mergeTargetClass.Methods = new List <IMethodDefinition>();
                        }
                        mergeTargetClass.Methods.Add(copy);
                    }
                }
                globalLog.writeLine("");
            }


            // rewrite constructors of the class to call the copied constructor instead of
            // the constructor of the ancestor class
            // (rewriting methods is handled later)
            foreach (MethodDefinition method in mergeTargetClass.Methods)
            {
                // check if method is a constructor
                if (method.IsConstructor)
                {
                    var testIlGenerator = new ILGenerator(host, method);
                    foreach (var operation in method.Body.Operations)
                    {
                        switch (operation.OperationCode)
                        {
                        // only call instructions that call a constructor have to be redirected
                        case OperationCode.Call:

                            MethodDefinition calledMethod = (MethodDefinition)operation.Value;
                            if (calledMethod.IsConstructor)
                            {
                                // TODO hier treten noch Probleme auf, wenn System.Object ist nicht der oberste Ancestor
                                // sondern z.B. System.ValueType
                                // check if the called constructor is not the constructor of System.Object
                                // and if the constructor that is called is not a constructor of THIS class
                                NamespaceTypeDefinition calledMethodNamespace = (NamespaceTypeDefinition)calledMethod.ContainingTypeDefinition;
                                if (calledMethodNamespace.ToString() != "System.Object" &&
                                    !calledMethodNamespace.Name.Equals(mergeTargetClass.Name))
                                {
                                    // search for the copied constructor that has to be called
                                    // (it is searched by parameter types because they always are named the same ".ctor")
                                    MethodDefinition copiedConstructorToCall = null;
                                    foreach (MethodDefinition copiedAncestorConstructor in copiedAncestorConstructors)
                                    {
                                        // check if the count of the parameters of the called constructor and the copied constructor are the same
                                        if (copiedAncestorConstructor.ParameterCount == calledMethod.ParameterCount)
                                        {
                                            // check if the parameters have the same type in the same order
                                            bool found = true;
                                            for (int i = 0; i < calledMethod.ParameterCount; i++)
                                            {
                                                if (calledMethod.Parameters[i].Type != copiedAncestorConstructor.Parameters[i].Type)
                                                {
                                                    found = false;
                                                    break;
                                                }
                                            }
                                            if (found)
                                            {
                                                copiedConstructorToCall = copiedAncestorConstructor;
                                                break;
                                            }
                                        }
                                    }
                                    if (copiedConstructorToCall == null)
                                    {
                                        throw new ArgumentException("No copied constructor with the same parameter types in the same order.");
                                    }

                                    // call copied constructor instead of constructor of the ancestor
                                    testIlGenerator.Emit(operation.OperationCode, copiedConstructorToCall);
                                }
                                // just emit if the called constructor is the constructor of System.Object
                                else
                                {
                                    testIlGenerator.Emit(operation.OperationCode, operation.Value);
                                }
                            }

                            // just emit operation if no constructor is called
                            // (rewriting methods is handled later)
                            else
                            {
                                testIlGenerator.Emit(operation.OperationCode, operation.Value);
                            }

                            break;

                        // just emit operation if none of the above cases match
                        default:
                            testIlGenerator.Emit(operation.OperationCode, operation.Value);
                            break;
                        }
                    }

                    // create new body
                    List <ILocalDefinition> variableListCopy           = new List <ILocalDefinition>(method.Body.LocalVariables);
                    List <ITypeDefinition>  privateHelperTypesListCopy = new List <ITypeDefinition>(method.Body.PrivateHelperTypes);
                    var newBody = new ILGeneratorMethodBody(testIlGenerator, method.Body.LocalsAreZeroed, method.Body.MaxStack, method, variableListCopy, privateHelperTypesListCopy);
                    method.Body = newBody;
                }
            }


            // rewrite all methods to use local attributes/methods instead of the ones of the ancestor
            foreach (MethodDefinition method in mergeTargetClass.Methods)
            {
                var testIlGenerator = new ILGenerator(host, method);
                foreach (var operation in method.Body.Operations)
                {
                    switch (operation.OperationCode)
                    {
                    case OperationCode.Stfld:
                    case OperationCode.Ldfld:

                        // get namespace of attribute
                        FieldDefinition      attribute          = (FieldDefinition)operation.Value;
                        INamedTypeDefinition attributeNamespace = (INamedTypeDefinition)attribute.ContainingTypeDefinition;

                        // check if namespace of attribute equals the namespace of THIS class
                        // => just emit operation
                        if (mergeTargetClass.Name.Equals(attributeNamespace.Name))
                        {
                            testIlGenerator.Emit(operation.OperationCode, operation.Value);
                            continue;
                        }

                        // try the namespace of all ancestors of this class to see if it was copied
                        else
                        {
                            // flag that indicates if the operation was emitted during the search loop
                            bool operationEmitted = false;

                            // search through all ancestors to find the namespace of the used attribute
                            NamespaceTypeDefinition tempAncestorClass = mergeTargetClass;
                            while (true)
                            {
                                // get class from which was inherited
                                if (tempAncestorClass.BaseClasses.Count == 1)
                                {
                                    // ignore inheritance from System.Object
                                    if (tempAncestorClass.BaseClasses[0].ToString() != "System.Object")
                                    {
                                        tempAncestorClass = (tempAncestorClass.BaseClasses[0] as NamespaceTypeDefinition);
                                    }
                                    // return if ancestor class equals System.Object
                                    else
                                    {
                                        break;
                                    }
                                }
                                else
                                {
                                    throw new ArgumentException("Do not know how to handle multiple inheritance.");
                                }

                                // check namespace of used attribute is equal to namespace of ancestor
                                // => change target of operation to THIS class
                                if (tempAncestorClass.Name.Equals(attributeNamespace.Name))
                                {
                                    // search for the method attribute that is used in the copied method
                                    // and replace it with the method attribute from the current class
                                    FieldDefinition foundField = null;
                                    foreach (FieldDefinition field in mergeTargetClass.Fields)
                                    {
                                        if (attribute.Name.Equals(field.Name) &&
                                            attribute.Type.Equals(field.Type))
                                        {
                                            foundField = field;
                                            break;
                                        }
                                    }
                                    if (foundField == null)
                                    {
                                        throw new ArgumentException("Attribute not found.");
                                    }

                                    // emit operation and set flag that it was emitted
                                    operationEmitted = true;
                                    testIlGenerator.Emit(operation.OperationCode, foundField);
                                    break;
                                }
                            }

                            // if operation was not emitted yet => emit it
                            if (operationEmitted == false)
                            {
                                testIlGenerator.Emit(operation.OperationCode, operation.Value);
                            }
                        }
                        break;

                    case OperationCode.Call:

                        // just emit if value is of type method reference
                        if (operation.Value is Microsoft.Cci.MutableCodeModel.MethodReference)
                        {
                            testIlGenerator.Emit(operation.OperationCode, operation.Value);
                            continue;
                        }

                        // get namespace of called method
                        MethodDefinition        calledMethod          = (MethodDefinition)operation.Value;
                        NamespaceTypeDefinition calledMethodNamespace = (NamespaceTypeDefinition)calledMethod.ContainingTypeDefinition;

                        // check if namespace of called method equals the namespace of THIS class
                        // => just emit operation
                        if (mergeTargetClass.Name.Equals(calledMethodNamespace.Name))
                        {
                            testIlGenerator.Emit(operation.OperationCode, operation.Value);
                            continue;
                        }

                        // try the namespace of all ancestors of this class to see if it was copied
                        else
                        {
                            // flag that indicates if the operation was emitted during the search loop
                            bool operationEmitted = false;

                            // search through all ancestors to find the namespace of the called method
                            NamespaceTypeDefinition tempAncestorClass = mergeTargetClass;
                            while (true)
                            {
                                // get class from which was inherited
                                if (tempAncestorClass.BaseClasses.Count == 1)
                                {
                                    // ignore inheritance from System.Object
                                    if (tempAncestorClass.BaseClasses[0].ToString() != "System.Object")
                                    {
                                        tempAncestorClass = (tempAncestorClass.BaseClasses[0] as NamespaceTypeDefinition);
                                    }
                                    // return if ancestor class equals System.Object
                                    else
                                    {
                                        break;
                                    }
                                }
                                else
                                {
                                    throw new ArgumentException("Do not know how to handle multiple inheritance.");
                                }

                                // check namespace of called method is equal to namespace of ancestor, if the same
                                // => find copied method in THIS class
                                // => change target of operation to method in THIS class
                                if (tempAncestorClass.Name.Equals(calledMethodNamespace.Name))
                                {
                                    // search through all methods in THISS class and search for the copied one
                                    MethodDefinition foundMethod = null;
                                    foreach (MethodDefinition newMethod in mergeTargetClass.Methods)
                                    {
                                        // skip constructors (can not be called from the ancestor)
                                        if (newMethod.IsConstructor)
                                        {
                                            continue;
                                        }

                                        if (newMethod.ParameterCount == calledMethod.ParameterCount)
                                        {
                                            // check if the parameters have the same type in the same order
                                            bool parameterCorrect = true;
                                            for (int i = 0; i < calledMethod.ParameterCount; i++)
                                            {
                                                if (calledMethod.Parameters[i].Type != newMethod.Parameters[i].Type)
                                                {
                                                    parameterCorrect = false;
                                                    break;
                                                }
                                            }

                                            // if the parameters are correct => check the name
                                            if (parameterCorrect)
                                            {
                                                if (calledMethod.Name.Equals(newMethod.Name))
                                                {
                                                    // if name is the same => found method to call
                                                    foundMethod = newMethod;
                                                    break;
                                                }
                                            }
                                        }
                                    }

                                    // check if the method we want to call was found
                                    if (foundMethod == null)
                                    {
                                        throw new ArgumentException("Did not find a method to call.");
                                    }

                                    // emit operation and set flag that it was emitted
                                    operationEmitted = true;
                                    testIlGenerator.Emit(operation.OperationCode, foundMethod);
                                    break;
                                }
                            }

                            // if operation was not emitted yet => emit it
                            if (operationEmitted == false)
                            {
                                testIlGenerator.Emit(operation.OperationCode, operation.Value);
                            }
                        }
                        break;

                    // just emit operation if none of the above cases match
                    default:
                        testIlGenerator.Emit(operation.OperationCode, operation.Value);
                        break;
                    }
                }

                // create new body
                List <ILocalDefinition> variableListCopy           = new List <ILocalDefinition>(method.Body.LocalVariables);
                List <ITypeDefinition>  privateHelperTypesListCopy = new List <ITypeDefinition>(method.Body.PrivateHelperTypes);
                var newBody = new ILGeneratorMethodBody(testIlGenerator, method.Body.LocalsAreZeroed, method.Body.MaxStack, method, variableListCopy, privateHelperTypesListCopy);
                method.Body = newBody;
            }
        }