ReadAssembly() static private method

static private ReadAssembly ( Mono.Cecil.ModuleDefinition module ) : AssemblyDefinition
module Mono.Cecil.ModuleDefinition
return AssemblyDefinition
        private static IList <Tuple <IUnresolvedAssembly, IList <string>, Assembly> > LoadReferences(IEnumerable <string> references, IErrorReporter er)
        {
            var loader = new CecilLoader {
                IncludeInternalMembers = true
            };
            var assemblies = references.Select(r => AssemblyDefinition.ReadAssembly(r)).ToList();             // Shouldn't result in errors because mcs would have caught it.

            var indirectReferences = (from a in assemblies
                                      from m in a.Modules
                                      from r in m.AssemblyReferences
                                      select r.Name)
                                     .Distinct();

            var directReferences = from a in assemblies select a.Name.Name;

            var missingReferences = indirectReferences.Except(directReferences).ToList();

            if (missingReferences.Count > 0)
            {
                er.Region = DomRegion.Empty;
                foreach (var r in missingReferences)
                {
                    er.Message(Messages._7996, r);
                }
                return(null);
            }

            return(assemblies.Select(asm => Tuple.Create(loader.LoadAssembly(asm), GetReferencedAssemblyNames(asm), LoadPlugin(asm))).ToList());
        }
Esempio n. 2
0
        private AssemblyDefinition ResolveInternal(string refName, Version minVersion, ReaderParameters parameters)
        {
            if (KnownAssemblies.TryGetValue(refName, out var loadedAsms))
            {
                var loadedAsm = loadedAsms.First(asm => asm.GetName().Version >= minVersion);
                var path      = new Uri(loadedAsm.CodeBase).LocalPath;
                if (File.Exists(path))
                {
                    return(parameters == null
                                                ? AssemblyDefinition.ReadAssembly(path, new ReaderParameters { AssemblyResolver = this })
                                                : AssemblyDefinition.ReadAssembly(path, parameters));
                }
            }
            try {
                var newlyLoadedAsm = Assembly.Load(new AssemblyName(refName));
                AddNewKnownAssembly(newlyLoadedAsm);

                var path = new Uri(newlyLoadedAsm.CodeBase).LocalPath;
                if (!File.Exists(path))
                {
                    throw new DllNotFoundException($"Could not locate {refName}");
                }

                return(parameters == null
                                        ? AssemblyDefinition.ReadAssembly(path)
                                        : AssemblyDefinition.ReadAssembly(path, parameters));
            }
            catch {
                throw new DllNotFoundException($"Could not resolve {refName}");
            }
        }
Esempio n. 3
0
        public static byte[] Patch(byte[] code)
        {
            var contractAsmDef = AssemblyDefinition.ReadAssembly(new MemoryStream(code));

            // Get the specific version of the SDK referenced by the contract
            var nameRefSdk = contractAsmDef.MainModule.AssemblyReferences.Single(r => r.Name == Sdk);

            // May cache all versions not to keep reloading for every contract deployment
            var refSdk = AssemblyDefinition.ReadAssembly(Assembly.Load(nameRefSdk.FullName).Location);

            // Get the type definitions mapped for target methods from SDK
            var sdkTypes    = TargetMethods.Select(kv => kv.Value).Distinct();
            var sdkTypeDefs = sdkTypes
                              .Select(t => contractAsmDef.MainModule.ImportReference(refSdk.MainModule.GetType(t)).Resolve())
                              .ToDictionary(def => def.FullName);

            // Patch the types
            foreach (var typ in contractAsmDef.MainModule.Types)
            {
                PatchType(contractAsmDef, typ, sdkTypeDefs);
            }

            var newCode = new MemoryStream();

            contractAsmDef.Write(newCode);
            return(newCode.ToArray());
        }
        private static Assembly LoadPlugin(AssemblyDefinition def)
        {
            foreach (var r in def.Modules.SelectMany(m => m.Resources).OfType <EmbeddedResource>())
            {
                if (r.Name.EndsWith(".dll", StringComparison.InvariantCultureIgnoreCase))
                {
                    var data = r.GetResourceData();
                    var asm  = AssemblyDefinition.ReadAssembly(new MemoryStream(data));

                    var result = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(a => a.GetName().Name == asm.Name.Name);
                    if (result == null)
                    {
                        result = Assembly.Load(data);
                    }
                    return(result);
                }
            }
            return(null);
        }
Esempio n. 5
0
        private void CopyAndPrepareCoreAssembly(IFile originalAssemblyFile, IDirectory tempDirectory)
        {
            var newLocation = tempDirectory.GetFile(originalAssemblyFile.Name);

            originalAssemblyFile.CopyTo(newLocation.FullName);

            AssemblyDefinition newAssembly;

            using (var stream = newLocation.OpenRead()) {
                newAssembly = AssemblyDefinition.ReadAssembly(stream);
            }
            foreach (var reference in newAssembly.MainModule.AssemblyReferences)
            {
                var fileInTemp = GetAssemblyFile(tempDirectory, reference);
                if (!fileInTemp.Exists)
                {
                    continue;
                }

                var assemblyName = AssemblyName.GetAssemblyName(fileInTemp.FullName);
                if (assemblyName.GetPublicKey() != null)
                {
                    // ReSharper disable once RedundantCheckBeforeAssignment (in case of change tracking)
                    if (reference.Version != assemblyName.Version)
                    {
                        reference.Version = assemblyName.Version;
                    }

                    continue;
                }

                reference.PublicKey      = null;
                reference.PublicKeyToken = null;
                reference.HasPublicKey   = false;
            }
            using (var stream = newLocation.Open(FileMode.Create)) {
                newAssembly.Write(stream);
            }
        }
Esempio n. 6
0
        private bool GetFieldOrProperty(ILWeaver weaver, MethodDefinition originalMethod, ref TypeDefinition currentArg, string target, Patcher patcher)
        {
            if (currentArg == null || string.IsNullOrEmpty(target))
            {
                return(false);
            }

            while (currentArg != null)
            {
                if (currentArg.IsClass)
                {
                    if (currentArg.HasFields)
                    {
                        foreach (var field in currentArg.Fields)
                        {
                            if (!string.Equals(field.Name, target, StringComparison.CurrentCultureIgnoreCase))
                            {
                                continue;
                            }

                            weaver.Add(field.Module == originalMethod.Module
                                ? Instruction.Create(OpCodes.Ldfld, field)
                                : Instruction.Create(OpCodes.Ldfld, originalMethod.Module.Import(field)));
                            currentArg = field.FieldType.Resolve();

                            return(true);
                        }
                    }
                }

                if (currentArg.HasProperties)
                {
                    foreach (var property in currentArg.Properties)
                    {
                        if (!string.Equals(property.Name, target, StringComparison.CurrentCultureIgnoreCase))
                        {
                            continue;
                        }

                        weaver.Add(property.GetMethod.Module == originalMethod.Module
                            ? Instruction.Create(OpCodes.Callvirt, property.GetMethod)
                            : Instruction.Create(OpCodes.Callvirt, originalMethod.Module.Import(property.GetMethod)));
                        currentArg = property.PropertyType.Resolve();

                        return(true);
                    }
                }

                if (currentArg.HasInterfaces)
                {
                    foreach (var intf in currentArg.Interfaces)
                    {
                        var previousArg = currentArg;
                        currentArg = intf.Resolve();
                        if (GetFieldOrProperty(weaver, originalMethod, ref currentArg, target, patcher))
                        {
                            return(true);
                        }
                        currentArg = previousArg;
                    }
                }

                if (currentArg.BaseType != null && originalMethod.Module.Assembly != currentArg.BaseType.Module.Assembly)
                {
                    var baseType         = currentArg.BaseType;
                    var baseTypeAssembly = AssemblyDefinition.ReadAssembly($"{(patcher != null ? patcher.PatchProject.TargetDirectory : PatcherForm.MainForm.CurrentProject.TargetDirectory)}\\{baseType.Scope.Name}{(baseType.Scope.Name.EndsWith(".dll") ? "" : ".dll")}");
                    currentArg = baseTypeAssembly.MainModule.Types.Single(x => x.FullName == baseType.FullName);
                }
                else
                {
                    currentArg = currentArg.BaseType?.Resolve();
                }
            }

            return(false);
        }
Esempio n. 7
0
        public void Inject(Mono.Cecil.AssemblyDefinition assemblyDefinition, 
            Dictionary<Mono.Cecil.MethodDefinition, List<Aspect>> eligibleMethods)
        {
            /* The around aspect is to intercept all calls to the target method, and
             * replace those calls with a completely different method. While preserving
             * the option to call back to the target method when necessary.
             */
            this.AssemblyDefinition = assemblyDefinition;
            this.EligibleMethods = eligibleMethods;
            var NewMethodNames = new StringCollection();
            var eligibleAroundMethods = this.EligibleMethods.Where(x => x.Value.Any(y =>
                    y.BuffaloAspect == Common.Enums.BuffaloAspect.MethodAroundAspect));
            foreach (var d in eligibleAroundMethods)
            {
                var method = d.Key;
                var aspects = d.Value;
                var il = method.Body.GetILProcessor();
                var methodType = method.DeclaringType;
                var maInstructions = new List<Instruction>();
                var aspectVarInstructions = new List<Instruction>();
                var aroundInstructions = new List<Instruction>();

                foreach (var aspec in aspects.Where(x =>
                    x.BuffaloAspect == Common.Enums.BuffaloAspect.MethodAroundAspect))
                {
                    //if aspect is from a different assembly, need to work from that context
                    var aspect = aspec;
                    var writedll = false;
                    AssemblyDefinition ass = null;
                    if (!aspect.TypeDefinition.Module.FullyQualifiedName.Equals(
                        this.AssemblyDefinition.MainModule.FullyQualifiedName))
                    {
                        ass = AssemblyDefinition.ReadAssembly(aspect.TypeDefinition.Module.FullyQualifiedName);
                        var asp = ass.MainModule.Types.FirstOrDefault(x => x.FullName == aspect.Name);
                        if (asp != null)
                        {
                            var newaspect = new Aspect { Name = asp.FullName, TypeDefinition = asp, BuffaloAspect = Common.Enums.BuffaloAspect.MethodAroundAspect };
                            aspect = newaspect;
                            writedll = true;
                        }
                    }

                    var varTicks = System.DateTime.Now.Ticks;

                    //create a replacement for the annotated function
                    var methodName = string.Format("{0}{1}", method.Name, varTicks);
                    MethodDefinition newmethod =
                        new MethodDefinition(methodName, method.Attributes, method.ReturnType);
                    methodType.Methods.Add(newmethod);
                    NewMethodNames.Add(methodName);
                    //newmethod.Body.SimplifyMacros();
                    newmethod.Body.InitLocals = true;

                    //create aspect variable
                    var varAspectName = "asp" + varTicks;
                    var varAspectRef = this.AssemblyDefinition.MainModule.Import(aspect.TypeDefinition);
                    var varAspect = new VariableDefinition(varAspectName, varAspectRef);
                    newmethod.Body.Variables.Add(varAspect);
                    var varAspectIdx = newmethod.Body.Variables.Count - 1;
                    var ctor = aspect.TypeDefinition.Methods.First(x => x.IsConstructor);
                    var ctoref = this.AssemblyDefinition.MainModule.Import(ctor);
                    //store the newly created aspect variable
                    newmethod.Body.Instructions.Add(Instruction.Create(OpCodes.Newobj, ctoref));
                    newmethod.Body.Instructions.Add(Instruction.Create(OpCodes.Stloc, varAspect));
                    //copy all the paramters
                    method.Parameters.ToList().ForEach(x =>
                        newmethod.Parameters.Add(new ParameterDefinition(x.Name, x.Attributes, x.ParameterType)));
                    //create a MethodArgs
                    var var = newmethod.AddMethodArgsVariable(this.AssemblyDefinition);

                    #region Calling MethodArgs.Invoke
                    newmethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ldloc, varAspect));
                    newmethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ldloc, var.Var));
                    var aspectInvoke = aspect.TypeDefinition.Methods.First(x => x.Name.Equals("Invoke"));
                    var aspectInvokeRef =
                        this.AssemblyDefinition.MainModule.Import(aspectInvoke, newmethod);
                    newmethod.Body.Instructions.Add(Instruction.Create(OpCodes.Callvirt, aspectInvokeRef));
                    #endregion

                    #region Handling return value
                    if (!newmethod.ReturnType.FullName.Equals("System.Void"))
                    {
                        //create an object variable to hold the return value
                        var varObj = new VariableDefinition("obj" + varTicks,
                            this.AssemblyDefinition.MainModule.Import(typeof(object)));
                        newmethod.Body.Variables.Add(varObj);
                        newmethod.Body.Instructions.Add(
                            Instruction.Create(OpCodes.Stloc, varObj));
                        newmethod.Body.Instructions.Add(
                            Instruction.Create(OpCodes.Ldloc, varObj));
                        newmethod.Body.Instructions.Add(
                            Instruction.Create(OpCodes.Unbox_Any, newmethod.ReturnType));
                    }
                    else
                    {
                        //pop the return value since it's not used?
                        newmethod.Body.Instructions.Add(
                            Instruction.Create(OpCodes.Pop));
                    }
                    #endregion

                    HandleProceed2(method, il, aspect.TypeDefinition);

                    #region Modify all calls from origin to the generated method
                    foreach (var type in this.AssemblyDefinition.MainModule.Types
                        .Where(x => x.BaseType == null || !x.BaseType.FullName.Equals("Buffalo.MethodAroundAspect")))
                    {
                        var methods = type.Methods.Where(x => !NewMethodNames.Contains(x.Name));
                        foreach (var m in methods)
                        {
                            for (int j = 0; j < m.Body.Instructions.Count; ++j)
                            {
                                if (m.Body.Instructions[j].ToString().Contains(method.FullName))
                                {
                                    m.Body.Instructions[j].Operand = newmethod;
                                    //MethodArgs.Invoke returns an object, need to unbox it here to the original type
                                    //However, unboxing is needed only if the original method has a return type
                                    //other than void
                                    if (!newmethod.ReturnType.FullName.Equals("System.Void"))
                                    {
                                        //var unbox = Instruction.Create(OpCodes.Unbox_Any, newmethod.ReturnType);
                                        //var il2 = m.Body.GetILProcessor();
                                        //il2.InsertAfter(m.Body.Instructions[j], unbox);
                                    }
                                }
                            }
                        }
                    }
                    #endregion

                    newmethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ret));
                    if (writedll)
                    {
                        ass.Write2(ass.MainModule.FullyQualifiedName);
                    }
                }
            }
        }