Ejemplo n.º 1
0
        private IMethodDefinition CreateInitMethod(IMethodDefinition incomingMethodDefinition, IFieldReference loadLibraryModule, IFieldReference methodField, IMethodReference isLibraryInitMethod, IPlatformInvokeInformation platformInvokeInformation)
        {
            var methodDefinition = new MethodDefinition
            {
                IsStatic = true,
                Type     = this.platformType.SystemVoid,
                ContainingTypeDefinition = incomingMethodDefinition.ContainingTypeDefinition,
                Name           = this.nameTable.GetNameFor("init_" + incomingMethodDefinition.Name.Value),
                IsNeverInlined = true,
                Visibility     = TypeMemberVisibility.Private
            };

            var ilGenerator = new ILGenerator(this.host, methodDefinition);

            ilGenerator.Emit(OperationCode.Ldsfld, loadLibraryModule);
            ilGenerator.Emit(OperationCode.Dup);
            ilGenerator.Emit(OperationCode.Ldstr, platformInvokeInformation.ImportModule.Name.Value);
            ilGenerator.Emit(OperationCode.Call, isLibraryInitMethod);
            ilGenerator.Emit(OperationCode.Ldstr, platformInvokeInformation.ImportName.Value);
            ilGenerator.Emit(OperationCode.Call, this.getProcAddress);
            ilGenerator.Emit(OperationCode.Stsfld, methodField);
            ilGenerator.Emit(OperationCode.Ret);

            var ilMethodBody = new ILGeneratorMethodBody(ilGenerator, false, 2, methodDefinition, Enumerable.Empty <ILocalDefinition>(), Enumerable.Empty <ITypeDefinition>());

            methodDefinition.Body = ilMethodBody;

            return(methodDefinition);
        }
        private void InjectMethodToDumpCounters()
        {
            var dumper = new MethodDefinition()
            {
                ContainingTypeDefinition = this.counterFieldsForCurrentMethod,
                InternFactory            = this.host.InternFactory,
                IsCil      = true,
                IsStatic   = true,
                Name       = this.host.NameTable.GetNameFor("DumpCounters"),
                Type       = this.host.PlatformType.SystemVoid,
                Visibility = TypeMemberVisibility.Public,
            };

            this.counterFieldsForCurrentMethod.Methods.Add(dumper);
            this.dumperMethods.Add(dumper);

            var ilGenerator = new ILGenerator(this.host, dumper);

            for (int i = 0, n = this.fieldOffsets.Count; i < n; i++)
            {
                ilGenerator.Emit(OperationCode.Ldsfld, this.counterFieldsForCurrentMethod.Fields[i]);
                ilGenerator.Emit(OperationCode.Call, this.logger);
            }
            ilGenerator.Emit(OperationCode.Ret);
            var body = new ILGeneratorMethodBody(ilGenerator, false, 2, dumper, Enumerable <ILocalDefinition> .Empty, Enumerable <ITypeDefinition> .Empty);

            dumper.Body = body;
        }
Ejemplo n.º 3
0
        private IMethodDefinition CreateLoadLibraryMethod(ITypeDefinition typeDefinition, IModuleReference moduleRef, IFieldReference fieldRef)
        {
            var methodDefinition = new MethodDefinition
            {
                IsStatic = true,
                Type     = this.platformType.SystemVoid,
                ContainingTypeDefinition = typeDefinition,
                Name           = this.nameTable.GetNameFor("LoadLibrary" + moduleRef.Name.Value),
                IsNeverInlined = true,
                Visibility     = TypeMemberVisibility.Public,
                Parameters     = new List <IParameterDefinition> {
                    new ParameterDefinition {
                        Index = 0, Type = this.platformType.SystemString, Name = this.host.NameTable.GetNameFor("nativeLibraryFilePath")
                    }
                }
            };

            var ilGenerator = new ILGenerator(this.host, methodDefinition);

            ilGenerator.Emit(OperationCode.Ldarg_0);
            ilGenerator.Emit(OperationCode.Call, this.loadLibrary);
            ilGenerator.Emit(OperationCode.Stsfld, fieldRef);
            ilGenerator.Emit(OperationCode.Ret);

            var ilMethodBody = new ILGeneratorMethodBody(ilGenerator, false, 2, methodDefinition, Enumerable.Empty <ILocalDefinition>(), Enumerable.Empty <ITypeDefinition>());

            methodDefinition.Body = ilMethodBody;

            return(methodDefinition);
        }
        private void TransformPInvokeMethodDefinitionToImplementedMethodDefinition(MethodDefinition methodDefinition)
        {
            methodDefinition.IsPlatformInvoke  = false;
            methodDefinition.IsExternal        = false;
            methodDefinition.PreserveSignature = false;

            var ilGenerator            = new ILGenerator(this.host, methodDefinition);
            var label                  = new ILGeneratorLabel();
            var transformationMetadata = this.metadataProvider.Retrieve(methodDefinition);

            var fieldDef        = transformationMetadata.FunctionPointer;
            var locals          = new List <ILocalDefinition>();
            var paramToLocalMap = new Dictionary <IParameterDefinition, ILocalDefinition>();

            ilGenerator.Emit(OperationCode.Ldsfld, fieldDef);
            ilGenerator.Emit(OperationCode.Ldsfld, this.intPtrZero);
            ilGenerator.Emit(OperationCode.Call, this.intPtrOpEquality);
            ilGenerator.Emit(OperationCode.Brfalse_S, label);
            ilGenerator.Emit(OperationCode.Call, transformationMetadata.InitializeMethod);
            ilGenerator.MarkLabel(label);
            this.LoadArguments(locals, paramToLocalMap, ilGenerator, methodDefinition.ParameterCount, i => methodDefinition.Parameters[i], methodDefinition.PlatformInvokeData);
            ilGenerator.Emit(OperationCode.Ldsfld, fieldDef);
            ilGenerator.Emit(OperationCode.Call, transformationMetadata.NativeMethod);
            this.ReturnMarshalling(ilGenerator, methodDefinition);
            this.PostprocessNonBlittableArrayArguments(methodDefinition, locals, paramToLocalMap, ilGenerator);
            ilGenerator.Emit(OperationCode.Ret);

            var ilMethodBody = new ILGeneratorMethodBody(ilGenerator, true, (ushort)((methodDefinition.ParameterCount + 1) * 2), methodDefinition, locals, new List <ITypeDefinition>());

            methodDefinition.PlatformInvokeData = null;
            methodDefinition.Body = ilMethodBody;
        }
Ejemplo n.º 5
0
        private INamedTypeDefinition GenerateTypeA(IUnitNamespace rootNamespace)
        {
            var nt    = Host.NameTable;
            var typeA = new NamespaceTypeDefinition
            {
                ContainingUnitNamespace = rootNamespace,
                Name          = nt.GetNameFor("A"),
                InternFactory = Host.InternFactory,
                IsClass       = true
            };
            var typeParameter = new GenericTypeParameter
            {
                Name          = nt.GetNameFor("T"),
                InternFactory = Host.InternFactory,
                DefiningType  = typeA,
            };

            typeA.GenericParameters.Add(typeParameter);

            var baseGetMethod = new MethodDefinition
            {
                Name       = nt.GetNameFor("Get"),
                IsCil      = true,
                IsVirtual  = true,
                Visibility = TypeMemberVisibility.Assembly,
                Type       = typeParameter,
                ContainingTypeDefinition = typeA,
                InternFactory            = Host.InternFactory,
                IsNewSlot = true
            };

            typeA.Methods.Add(baseGetMethod);

            var il       = new ILGenerator(Host);
            var localVar = new LocalDefinition
            {
                Type = typeParameter,
                Name = nt.GetNameFor("local1"),
            };

            // tricky moment, ILGeneratorMethodBody fills internal collection of local vars only in constructor.
            // lines below should not be swapped

            il.AddVariableToCurrentScope(localVar);
            var body = new ILGeneratorMethodBody(il, true, 1)
            {
                MethodDefinition = baseGetMethod
            };

            baseGetMethod.Body = body;


            il.Emit(OperationCode.Ldloca, localVar);
            il.Emit(OperationCode.Initobj, typeParameter);
            il.Emit(OperationCode.Ldloc_0);
            il.Emit(OperationCode.Ret);

            return(typeA);
        }
Ejemplo n.º 6
0
        // this function adds a new local variable to the method
        public void addLocalVariable(ILocalDefinition localVariable)
        {
            ILGenerator ilGenerator = new ILGenerator(this.host, this.methodCfg.method);

            // add local variable
            List <ILocalDefinition> variableListCopy = new List <ILocalDefinition>(this.methodCfg.method.Body.LocalVariables);

            variableListCopy.Add(localVariable);

            // create the body
            List <ITypeDefinition> privateHelperTypesListCopy = new List <ITypeDefinition>(this.methodCfg.method.Body.PrivateHelperTypes);
            var newBody = new ILGeneratorMethodBody(ilGenerator, this.methodCfg.method.Body.LocalsAreZeroed, 8, this.methodCfg.method, variableListCopy, privateHelperTypesListCopy); // TODO dynamic max stack size?

            this.methodCfg.method.Body = newBody;
        }
Ejemplo n.º 7
0
        public override IMethodBody Rewrite(IMethodBody methodBody)
        {
            this.currentLocals = new List <ILocalDefinition>(methodBody.LocalVariables);

            try {
                ProcessOperations(methodBody);
                var newBody = new ILGeneratorMethodBody(this.currentGenerator, methodBody.LocalsAreZeroed, (ushort)(methodBody.MaxStack + 1),
                                                        methodBody.MethodDefinition, this.currentLocals ?? new List <ILocalDefinition>(), Enumerable <ITypeDefinition> .Empty);
                return(newBody);
            } catch (ILMutatorException) {
                Console.WriteLine("Internal error during IL mutation for the method '{0}'.",
                                  MemberHelper.GetMemberSignature(methodBody.MethodDefinition, NameFormattingOptions.SmartTypeName));
                return(methodBody);
            } finally {
                this.currentLocals = null;
            }
        }
        private IMethodReference InjectNewEntryPoint(IMethodDefinition oldEntryPoint)
        {
            var containingType = (NamespaceTypeDefinition)oldEntryPoint.ContainingTypeDefinition;
            var entryPoint     = new MethodDefinition()
            {
                ContainingTypeDefinition = containingType,
                InternFactory            = this.host.InternFactory,
                IsCil      = true,
                IsStatic   = true,
                Name       = this.host.NameTable.GetNameFor("InstrumentedMain"),
                Parameters = new List <IParameterDefinition>(oldEntryPoint.Parameters),
                Type       = this.host.PlatformType.SystemVoid,
                Visibility = TypeMemberVisibility.Public,
            };

            containingType.Methods.Add(entryPoint);

            var ilGenerator = new ILGenerator(host, entryPoint);

            foreach (var par in entryPoint.Parameters)
            {
                ilGenerator.Emit(OperationCode.Ldarg, par);
            }
            ilGenerator.Emit(OperationCode.Call, oldEntryPoint);
            foreach (var dumper in this.dumperMethods)
            {
                ilGenerator.Emit(OperationCode.Call, dumper);
            }
            ilGenerator.Emit(OperationCode.Ret);

            var body = new ILGeneratorMethodBody(ilGenerator, true, (ushort)entryPoint.Parameters.Count, entryPoint,
                                                 Enumerable <ILocalDefinition> .Empty, Enumerable <ITypeDefinition> .Empty);

            entryPoint.Body = body;
            return(entryPoint);
        }
Ejemplo n.º 9
0
        private NamespaceTypeDefinition GenerateTypeB(IUnitNamespace rootNamespace, ITypeReference baseType)
        {
            var nt    = Host.NameTable;
            var typeB = new NamespaceTypeDefinition
            {
                ContainingUnitNamespace = rootNamespace,
                Name          = nt.GetNameFor("B"),
                InternFactory = Host.InternFactory,
                IsClass       = true,
                BaseClasses   = { baseType }
            };

            var overrideGetMethod = new MethodDefinition
            {
                Name       = nt.GetNameFor("Get"),
                IsCil      = true,
                IsVirtual  = true,
                Visibility = TypeMemberVisibility.Assembly,
                Type       = Host.PlatformType.SystemString,
                ContainingTypeDefinition = typeB,
                InternFactory            = Host.InternFactory
            };

            typeB.Methods.Add(overrideGetMethod);
            var il   = new ILGenerator(Host);
            var body = new ILGeneratorMethodBody(il, true, 1)
            {
                MethodDefinition = overrideGetMethod
            };

            overrideGetMethod.Body = body;

            il.Emit(OperationCode.Ldstr, "1");
            il.Emit(OperationCode.Ret);
            return(typeB);
        }
Ejemplo n.º 10
0
        private IMethodDefinition CreateNativeMethod(IMethodDefinition pinvokeMethodDefinition)
        {
            var pinvokeData = pinvokeMethodDefinition.PlatformInvokeData;

            var nativeMethodDef = CreateRegularMethodDefinitionFromPInvokeMethodDefinition(pinvokeMethodDefinition, this.host.PlatformType.SystemIntPtr, this.host.PlatformType.SystemInt32);

            nativeMethodDef.Parameters.Add(new ParameterDefinition {
                Type = this.platformType.SystemIntPtr, Index = pinvokeMethodDefinition.ParameterCount, Name = this.nameTable.GetNameFor("funcPtr")
            });

            var ilGenerator = new ILGenerator(this.host, nativeMethodDef);

            LoadArguments(ilGenerator, pinvokeMethodDefinition.ParameterCount + 1, i => nativeMethodDef.Parameters[i]);

            var returnType = !IsBlittableType(pinvokeMethodDefinition.Type) ? (pinvokeMethodDefinition.Type.TypeCode == PrimitiveTypeCode.Boolean ? this.platformType.SystemInt32 : this.platformType.SystemIntPtr) : pinvokeMethodDefinition.Type;

            var funcPtr = new FunctionPointerTypeReference
            {
                Type       = returnType,
                Parameters = new List <IParameterTypeInformation>()
            };

            switch (pinvokeData.PInvokeCallingConvention)
            {
            case PInvokeCallingConvention.CDecl:
                funcPtr.CallingConvention = CallingConvention.C;
                break;

            case PInvokeCallingConvention.FastCall:
                funcPtr.CallingConvention = CallingConvention.FastCall;
                break;

            case PInvokeCallingConvention.StdCall:
            case PInvokeCallingConvention.WinApi:
                funcPtr.CallingConvention = CallingConvention.Standard;
                break;

            case PInvokeCallingConvention.ThisCall:
                funcPtr.CallingConvention = CallingConvention.ThisCall;
                break;
            }

            foreach (var parameter in pinvokeMethodDefinition.Parameters)
            {
                var paramDef = new ParameterDefinition {
                    Type = parameter.Type
                };

                if (!IsBlittableType(parameter.Type))
                {
                    paramDef.Type = parameter.Type.TypeCode == PrimitiveTypeCode.Boolean ? this.platformType.SystemInt32 : this.platformType.SystemIntPtr;
                }
                else if (parameter.IsByReference)
                {
                    paramDef.Type = this.platformType.SystemIntPtr;
                }

                funcPtr.Parameters.Add(paramDef);
            }

            ilGenerator.Emit(OperationCode.Calli, (ISignature)funcPtr);
            ilGenerator.Emit(OperationCode.Ret);

            var ilMethodBody = new ILGeneratorMethodBody(ilGenerator, false, nativeMethodDef.ParameterCount, nativeMethodDef, Enumerable.Empty <ILocalDefinition>(), Enumerable.Empty <ITypeDefinition>());

            nativeMethodDef.Body = ilMethodBody;

            return(nativeMethodDef);
        }
Ejemplo n.º 11
0
        static void Main(string[] args)
        {
            var nameTable = new NameTable();

            using (var host = new PeReader.DefaultHost(nameTable)) {
                var coreAssembly = host.LoadAssembly(host.CoreAssemblySymbolicIdentity);

                var assembly = new Assembly()
                {
                    Name                 = nameTable.GetNameFor("hello"),
                    ModuleName           = nameTable.GetNameFor("hello.exe"),
                    PlatformType         = host.PlatformType,
                    Kind                 = ModuleKind.ConsoleApplication,
                    RequiresStartupStub  = host.PointerSize == 4,
                    TargetRuntimeVersion = coreAssembly.TargetRuntimeVersion,
                };
                assembly.AssemblyReferences.Add(coreAssembly);

                var rootUnitNamespace = new RootUnitNamespace();
                assembly.UnitNamespaceRoot = rootUnitNamespace;
                rootUnitNamespace.Unit     = assembly;

                var moduleClass = new NamespaceTypeDefinition()
                {
                    ContainingUnitNamespace = rootUnitNamespace,
                    InternFactory           = host.InternFactory,
                    IsClass = true,
                    Name    = nameTable.GetNameFor("<Module>"),
                };
                assembly.AllTypes.Add(moduleClass);

                var testClass = new NamespaceTypeDefinition()
                {
                    ContainingUnitNamespace = rootUnitNamespace,
                    InternFactory           = host.InternFactory,
                    IsClass  = true,
                    IsPublic = true,
                    Methods  = new List <IMethodDefinition>(1),
                    Name     = nameTable.GetNameFor("Test"),
                };
                rootUnitNamespace.Members.Add(testClass);
                assembly.AllTypes.Add(testClass);
                testClass.BaseClasses = new List <ITypeReference>()
                {
                    host.PlatformType.SystemObject
                };

                var mainMethod = new MethodDefinition()
                {
                    ContainingTypeDefinition = testClass,
                    InternFactory            = host.InternFactory,
                    IsCil      = true,
                    IsStatic   = true,
                    Name       = nameTable.GetNameFor("Main"),
                    Type       = host.PlatformType.SystemVoid,
                    Visibility = TypeMemberVisibility.Public,
                };
                assembly.EntryPoint = mainMethod;
                testClass.Methods.Add(mainMethod);

                var ilGenerator = new ILGenerator(host, mainMethod);

                var systemConsole = UnitHelper.FindType(nameTable, coreAssembly, "System.Console");
                var writeLine     = TypeHelper.GetMethod(systemConsole, nameTable.GetNameFor("WriteLine"), host.PlatformType.SystemString);

                ilGenerator.Emit(OperationCode.Ldstr, "hello");
                ilGenerator.Emit(OperationCode.Call, writeLine);
                ilGenerator.Emit(OperationCode.Ret);

                var body = new ILGeneratorMethodBody(ilGenerator, true, 1, mainMethod, Enumerable <ILocalDefinition> .Empty, Enumerable <ITypeDefinition> .Empty);
                mainMethod.Body = body;

                using (var peStream = File.Create("hello.exe")) {
                    PeWriter.WritePeToStream(assembly, host, peStream);
                }
            }
        }
Ejemplo n.º 12
0
        // 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);
                }
            }
        }
Ejemplo n.º 13
0
        // makes a copy of the method
        public void copyMethod(MethodDefinition dest, IMethodDefinition source)
        {
            // only copy body if it is not a dummy (= empty)
            if (!(source.Body is Microsoft.Cci.Dummy))
            {
                // copy instructions
                ILGenerator ilGenerator = new ILGenerator(this.host, dest);
                foreach (var operation in source.Body.Operations)
                {
                    ilGenerator.Emit(operation.OperationCode, operation.Value);
                }

                // copy the exception handler
                foreach (IOperationExceptionInformation exceptionToCopy in source.Body.OperationExceptionInformation)
                {
                    ILGeneratorLabel tryStart = new ILGeneratorLabel();
                    tryStart.Offset = exceptionToCopy.TryStartOffset;
                    ILGeneratorLabel tryEnd = new ILGeneratorLabel();
                    tryEnd.Offset = exceptionToCopy.TryEndOffset;
                    ILGeneratorLabel handlerStart = new ILGeneratorLabel();
                    handlerStart.Offset = exceptionToCopy.HandlerStartOffset;
                    ILGeneratorLabel handlerEnd = new ILGeneratorLabel();
                    handlerEnd.Offset = exceptionToCopy.HandlerEndOffset;
                    ILGeneratorLabel filterStart = new ILGeneratorLabel();
                    filterStart.Offset = exceptionToCopy.FilterDecisionStartOffset;

                    ilGenerator.AddExceptionHandlerInformation(exceptionToCopy.HandlerKind, exceptionToCopy.ExceptionType,
                                                               tryStart, tryEnd, handlerStart, handlerEnd, filterStart);
                }

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

            dest.CallingConvention = source.CallingConvention;
            if (source.IsGeneric)
            {
                dest.GenericParameters = new List <IGenericMethodParameter>(source.GenericParameters);
            }
            else
            {
                dest.GenericParameters = null;
            }
            if (source.ParameterCount > 0)
            {
                dest.Parameters = new List <IParameterDefinition>(source.Parameters);
            }
            else
            {
                dest.Parameters = null;
            }
            if (source.IsPlatformInvoke)
            {
                dest.PlatformInvokeData = source.PlatformInvokeData;
            }
            else
            {
                dest.PlatformInvokeData = Dummy.PlatformInvokeInformation;
            }
            dest.ReturnValueAttributes = new List <ICustomAttribute>(source.ReturnValueAttributes);
            if (source.ReturnValueIsModified)
            {
                dest.ReturnValueCustomModifiers = new List <ICustomModifier>(source.ReturnValueCustomModifiers);
            }
            else
            {
                dest.ReturnValueCustomModifiers = new List <ICustomModifier>(0);
            }
            if (source.ReturnValueIsMarshalledExplicitly)
            {
                dest.ReturnValueMarshallingInformation = source.ReturnValueMarshallingInformation;
            }
            else
            {
                dest.ReturnValueMarshallingInformation = Dummy.MarshallingInformation;
            }
            if (source.HasDeclarativeSecurity && IteratorHelper.EnumerableIsNotEmpty(source.SecurityAttributes))
            {
                dest.SecurityAttributes = new List <ISecurityAttribute>(source.SecurityAttributes);
            }
            else
            {
                dest.SecurityAttributes = null;
            }
            dest.Type = source.Type;
            dest.AcceptsExtraArguments     = source.AcceptsExtraArguments;
            dest.HasDeclarativeSecurity    = source.HasDeclarativeSecurity;
            dest.IsAbstract                = source.IsAbstract;
            dest.IsAccessCheckedOnOverride = source.IsAccessCheckedOnOverride;
            dest.IsCil                 = source.IsCil;
            dest.IsExternal            = source.IsExternal;
            dest.IsForwardReference    = source.IsForwardReference;
            dest.IsHiddenBySignature   = source.IsHiddenBySignature;
            dest.IsNativeCode          = source.IsNativeCode;
            dest.IsNewSlot             = source.IsNewSlot;
            dest.IsNeverInlined        = source.IsNeverInlined;
            dest.IsAggressivelyInlined = source.IsAggressivelyInlined;
            dest.IsNeverOptimized      = source.IsNeverOptimized;
            dest.IsPlatformInvoke      = source.IsPlatformInvoke;
            dest.IsRuntimeImplemented  = source.IsRuntimeImplemented;
            dest.IsRuntimeInternal     = source.IsRuntimeInternal;
            dest.IsRuntimeSpecial      = source.IsRuntimeSpecial;
            dest.IsSealed              = source.IsSealed;
            dest.IsSpecialName         = source.IsSpecialName;
            dest.IsStatic              = source.IsStatic;
            dest.IsSynchronized        = source.IsSynchronized;
            dest.IsUnmanaged           = source.IsUnmanaged;
            if (dest.IsStatic)
            {
                dest.IsVirtual = false;
            }
            else
            {
                dest.IsVirtual = source.IsVirtual;
            }
            dest.PreserveSignature                 = source.PreserveSignature;
            dest.RequiresSecurityObject            = source.RequiresSecurityObject;
            dest.ReturnValueIsByRef                = source.ReturnValueIsByRef;
            dest.ReturnValueIsMarshalledExplicitly = source.ReturnValueIsMarshalledExplicitly;
            dest.ReturnValueName = source.ReturnValueName;
            dest.Name            = source.Name;
            dest.Visibility      = source.Visibility;
        }
Ejemplo n.º 14
0
        static void copyMethod(MethodDefinition dest, IMethodDefinition source, PeReader.DefaultHost host)
        {
            // only copy body if it is not a dummy (= empty)
            if (!(source.Body is Microsoft.Cci.Dummy))
            {
                // TODO
                // langsames kopieren des Bodies, schnellerer weg möglich?
                var testIlGenerator = new ILGenerator(host, dest);
                foreach (var operation in source.Body.Operations)
                {
                    testIlGenerator.Emit(operation.OperationCode, operation.Value);
                }
                List <ILocalDefinition> variableListCopy           = new List <ILocalDefinition>(source.Body.LocalVariables);
                List <ITypeDefinition>  privateHelperTypesListCopy = new List <ITypeDefinition>(source.Body.PrivateHelperTypes);
                var newBody = new ILGeneratorMethodBody(testIlGenerator, source.Body.LocalsAreZeroed, source.Body.MaxStack, dest, variableListCopy, privateHelperTypesListCopy);
                dest.Body = newBody;
            }

            dest.CallingConvention = source.CallingConvention;
            if (source.IsGeneric)
            {
                dest.GenericParameters = new List <IGenericMethodParameter>(source.GenericParameters);
            }
            else
            {
                dest.GenericParameters = null;
            }
            if (source.ParameterCount > 0)
            {
                dest.Parameters = new List <IParameterDefinition>(source.Parameters);
            }
            else
            {
                dest.Parameters = null;
            }
            if (source.IsPlatformInvoke)
            {
                dest.PlatformInvokeData = source.PlatformInvokeData;
            }
            else
            {
                dest.PlatformInvokeData = Dummy.PlatformInvokeInformation;
            }
            dest.ReturnValueAttributes = new List <ICustomAttribute>(source.ReturnValueAttributes);
            if (source.ReturnValueIsModified)
            {
                dest.ReturnValueCustomModifiers = new List <ICustomModifier>(source.ReturnValueCustomModifiers);
            }
            else
            {
                dest.ReturnValueCustomModifiers = new List <ICustomModifier>(0);
            }
            if (source.ReturnValueIsMarshalledExplicitly)
            {
                dest.ReturnValueMarshallingInformation = source.ReturnValueMarshallingInformation;
            }
            else
            {
                dest.ReturnValueMarshallingInformation = Dummy.MarshallingInformation;
            }
            if (source.HasDeclarativeSecurity && IteratorHelper.EnumerableIsNotEmpty(source.SecurityAttributes))
            {
                dest.SecurityAttributes = new List <ISecurityAttribute>(source.SecurityAttributes);
            }
            else
            {
                dest.SecurityAttributes = null;
            }
            dest.Type = source.Type;
            dest.AcceptsExtraArguments     = source.AcceptsExtraArguments;
            dest.HasDeclarativeSecurity    = source.HasDeclarativeSecurity;
            dest.IsAbstract                = source.IsAbstract;
            dest.IsAccessCheckedOnOverride = source.IsAccessCheckedOnOverride;
            dest.IsCil                 = source.IsCil;
            dest.IsExternal            = source.IsExternal;
            dest.IsForwardReference    = source.IsForwardReference;
            dest.IsHiddenBySignature   = source.IsHiddenBySignature;
            dest.IsNativeCode          = source.IsNativeCode;
            dest.IsNewSlot             = source.IsNewSlot;
            dest.IsNeverInlined        = source.IsNeverInlined;
            dest.IsAggressivelyInlined = source.IsAggressivelyInlined;
            dest.IsNeverOptimized      = source.IsNeverOptimized;
            dest.IsPlatformInvoke      = source.IsPlatformInvoke;
            dest.IsRuntimeImplemented  = source.IsRuntimeImplemented;
            dest.IsRuntimeInternal     = source.IsRuntimeInternal;
            dest.IsRuntimeSpecial      = source.IsRuntimeSpecial;
            dest.IsSealed              = source.IsSealed;
            dest.IsSpecialName         = source.IsSpecialName;
            dest.IsStatic              = source.IsStatic;
            dest.IsSynchronized        = source.IsSynchronized;
            dest.IsUnmanaged           = source.IsUnmanaged;
            if (dest.IsStatic)
            {
                dest.IsVirtual = false;
            }
            else
            {
                dest.IsVirtual = source.IsVirtual;
            }
            dest.PreserveSignature                 = source.PreserveSignature;
            dest.RequiresSecurityObject            = source.RequiresSecurityObject;
            dest.ReturnValueIsByRef                = source.ReturnValueIsByRef;
            dest.ReturnValueIsMarshalledExplicitly = source.ReturnValueIsMarshalledExplicitly;
            dest.ReturnValueName = source.ReturnValueName;
            dest.Name            = source.Name;
            dest.Visibility      = source.Visibility;
        }
Ejemplo n.º 15
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;
            }
        }