Beispiel #1
0
        private static void Patch(string assembly, string assemblyClean, string lizard, string attributes)
        {
            // keep original assembly before modification
            if (!File.Exists(assemblyClean))
            {
                File.Copy(assembly, assemblyClean);
            }

            File.Copy(LizardDll, lizard);
            File.Copy(AttributesDll, attributes);

            Mono.Cecil.AssemblyDefinition assemblyDefinition = Cecil.ReadAssembly(assembly);

            if (assemblyDefinition == null)
            {
                Externs.MessageBox("Assembly is null", "Failed to load assembly " + assembly);

                Environment.Exit(-1);
            }

            int injectedCorrectly = Util.InjectAllHooks(Attributes, assemblyDefinition);

            if (injectedCorrectly > 0)
            {
                Cecil.WriteChanges(assemblyDefinition);
            }

            ModCompiler.CompileMods();
        }
Beispiel #2
0
        private static IEnumerable <IAssemblyReference> 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(7996, r);
                }
                return(null);
            }

            return(assemblies.Select(a => loader.LoadAssembly(a)).ToList());
        }
        public IEnumerable <Mono.Cecil.TypeDefinition> Filter(Mono.Cecil.AssemblyDefinition assembly)
        {
            var excludeTypes = excludeList;

            bool IsCommandPredicate(Mono.Cecil.TypeDefinition t)
            {
                if (!t.IsValueType || t.IsPrimitive || (!t.IsIRpcCommand() && !t.IsICommandData()))
                {
                    return(false);
                }

                if (excludeTypes != null && excludeTypes.Contains(t.FullName))
                {
                    return(false);
                }
                return(!t.HasAttribute <NetCodeDisableCommandCodeGenAttribute>());
            }

            var result = new List <Mono.Cecil.TypeDefinition>();

            if (assembly?.Modules != null)
            {
                foreach (var m in assembly.Modules)
                {
                    if (m != null)
                    {
                        result.AddRange(m.GetTypes().Where(IsCommandPredicate));
                    }
                }
            }

            return(result);
        }
Beispiel #4
0
        static private void showString(Mono.Cecil.TypeDefinition type,
                                       Mono.Cecil.AssemblyDefinition assembly,
                                       string prefix = "")
        {
            nestSearch(type, assembly, ref prefix, showString);

            type.Methods.ToList().ForEach((method) =>
            {
                var lineCount = 0;
                if (method.HasBody)
                {
                    method.Body.Instructions.ToList().ForEach(inst =>
                    {
                        if (inst.OpCode == Mono.Cecil.Cil.OpCodes.Ldstr)
                        {
                            if (lineCount == 0)
                            {
                                Console.WriteLine(string.Format("{0}.{1}:", prefix, method.Name));
                            }
                            Console.WriteLine(string.Format("{0}:{1}", lineCount, inst.Operand.ToString()));
                            lineCount++;
                        }
                    });
                }

                if (lineCount != 0)
                {
                    Console.WriteLine();
                }
            });
        }
Beispiel #5
0
        static private void debugMethod(Mono.Cecil.TypeDefinition type,
                                        Mono.Cecil.AssemblyDefinition assembly,
                                        string prefix = "")
        {
            nestSearch(type, assembly, ref prefix, debugMethod);

            type.Methods.ToList().ForEach((method) =>
            {
                var il     = method.Body.GetILProcessor();
                var module = type.Module;
                var write  = il.Create(
                    Mono.Cecil.Cil.OpCodes.Call,
                    module.Import(typeof(Console).GetMethod("WriteLine", new[] { typeof(object) })));
                var ret   = il.Create(Mono.Cecil.Cil.OpCodes.Ret);
                var leave = il.Create(Mono.Cecil.Cil.OpCodes.Leave, ret);

                il.InsertAfter(
                    method.Body.Instructions.Last(),
                    write);

                il.InsertAfter(write, leave);
                il.InsertAfter(leave, ret);

                var handler = new Mono.Cecil.Cil.ExceptionHandler(Mono.Cecil.Cil.ExceptionHandlerType.Catch)
                {
                    TryStart     = method.Body.Instructions.First(),
                    TryEnd       = write,
                    HandlerStart = write,
                    HandlerEnd   = ret,
                    CatchType    = module.Import(typeof(Exception)),
                };

                method.Body.ExceptionHandlers.Add(handler);
            });
        }
Beispiel #6
0
        public static string DetectTargetFrameworkId(Mono.Cecil.AssemblyDefinition assembly, string assemblyPath = null)
        {
            if (assembly == null)
            {
                throw new ArgumentNullException(nameof(assembly));
            }

            const string TargetFrameworkAttributeName = "System.Runtime.Versioning.TargetFrameworkAttribute";

            foreach (var attribute in assembly.CustomAttributes)
            {
                if (attribute.AttributeType.FullName != TargetFrameworkAttributeName)
                {
                    continue;
                }
                if (attribute.HasConstructorArguments)
                {
                    if (attribute.ConstructorArguments[0].Value is string value)
                    {
                        return(value);
                    }
                }
            }

            // Optionally try to detect target version through assembly path as a fallback (use case: reference assemblies)
            if (assemblyPath != null)
            {
                /*
                 * Detected path patterns (examples):
                 *
                 * - .NETFramework -> C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\mscorlib.dll
                 * - .NETCore      -> C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.1.0\ref\netcoreapp2.1\System.Console.dll
                 *                 -> C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\3.0.0\ref\netcoreapp3.0\System.Runtime.Extensions.dll
                 * - .NETStandard  -> C:\Program Files\dotnet\sdk\NuGetFallbackFolder\netstandard.library\2.0.3\build\netstandard2.0\ref\netstandard.dll
                 */
                var pathMatch = Regex.Match(assemblyPath, DetectTargetFrameworkIdRefPathPattern,
                                            RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.ExplicitCapture);
                if (pathMatch.Success)
                {
                    var type    = pathMatch.Groups[1].Value;
                    var version = pathMatch.Groups[2].Value;

                    if (type == ".NETFramework")
                    {
                        return($".NETFramework,Version=v{version}");
                    }
                    else if (type.ToLower().Contains("netcore"))
                    {
                        return($".NETCoreApp,Version=v{version}");
                    }
                    else if (type.ToLower().Contains("netstandard"))
                    {
                        return($".NETStandard,Version=v{version}");
                    }
                }
            }

            return(string.Empty);
        }
Beispiel #7
0
        private static GACAssembly QueryAssemblyInfo(string assemblyString)
        {
            string assemblyPath = AssemblyCache.QueryAssemblyInfo(assemblyString);

            Mono.Cecil.AssemblyDefinition assemblyDefinition = Mono.Cecil.AssemblyDefinition.ReadAssembly(assemblyPath);
            return(new GACAssembly(assemblyDefinition.Name.Name,
                                   assemblyDefinition.Name.Version,
                                   assemblyPath,
                                   assemblyDefinition.MainModule.Runtime.ToString(),
                                   KeyTokenToString(assemblyDefinition.Name.PublicKeyToken)));
        }
Beispiel #8
0
        public static bool IsReferenceAssembly(Mono.Cecil.AssemblyDefinition assemblyDef, string assemblyFile)
        {
            if (assemblyDef.CustomAttributes.Any(ca => ca.AttributeType.FullName == "System.Runtime.CompilerServices.ReferenceAssemblyAttribute"))
            {
                return(true);
            }

            // Try to detect reference assembly through specific path pattern
            var refPathMatch = Regex.Match(assemblyFile, RefPathPattern, RegexOptions.IgnoreCase | RegexOptions.Compiled);

            return(refPathMatch.Success);
        }
Beispiel #9
0
 private static void OptimizeAssembly(
     Mono.Cecil.AssemblyDefinition cecilAsm,
     ClrAssembly flameAsm,
     Func <ClrMethodDefinition, MethodBody> optimizeBody)
 {
     foreach (var module in cecilAsm.Modules)
     {
         foreach (var type in module.Types)
         {
             OptimizeType(type, flameAsm, optimizeBody);
         }
     }
 }
Beispiel #10
0
        public IEnumerable <Mono.Cecil.TypeDefinition> Filter(Mono.Cecil.AssemblyDefinition assembly)
        {
            bool IsEnginedSupportedType(Mono.Cecil.TypeDefinition type)
            {
                if (GhostAuthoringComponentEditor.GhostDefaultOverrides.TryGetValue(type.FullName.Replace("/", "+"), out var newComponent))
                {
                    return(true);
                }
                return(false);
            }

            var excludeTypes = excludeList;

            bool IsGhostPredicate(Mono.Cecil.TypeDefinition t)
            {
                if (!t.IsValueType || t.IsPrimitive || !t.IsIComponentData() || t.IsIRpcCommand())
                {
                    return(false);
                }

                if (excludeTypes != null && excludeTypes.Contains(t.FullName))
                {
                    return(false);
                }

                // Backward compatibility for Transform and Rotation and other default types here.
                // Customize the below method in case you need to add more
                if (IsEnginedSupportedType(t))
                {
                    return(true);
                }

                // Otherwise, for backward compatibility I need to scan for presence of any GhostField.
                return(t.HasFields && t.Fields.Any(f => f.HasAttribute <GhostFieldAttribute>()));
            }

            var result = new List <Mono.Cecil.TypeDefinition>();

            if (assembly?.Modules != null)
            {
                foreach (var m in assembly.Modules)
                {
                    if (m != null)
                    {
                        result.AddRange(m.GetTypes().Where(IsGhostPredicate));
                    }
                }
            }

            return(result);
        }
Beispiel #11
0
        public static string FindAssemblyFile(Mono.Cecil.AssemblyDefinition assemblyDefinition, string assemblyFile)
        {
            string tfi = DetectTargetFrameworkId(assemblyDefinition, assemblyFile);
            UniversalAssemblyResolver assemblyResolver;

            if (IsReferenceAssembly(assemblyDefinition, assemblyFile))
            {
                assemblyResolver = new UniversalAssemblyResolver(null, throwOnError: false, tfi);
            }
            else
            {
                assemblyResolver = new UniversalAssemblyResolver(assemblyFile, throwOnError: false, tfi);
            }

            return(assemblyResolver.FindAssemblyFile(AssemblyNameReference.Parse(assemblyDefinition.Name.FullName)));
        }
        private static IEnumerable <TypeDefinition> GetTypesFromDll(string dllPath)
        {
            var dll           = Assembly.LoadFile(dllPath);
            var typesToReturn = new List <Type>();

            try
            {
                return(AssemblyDefinition.ReadAssembly(dllPath).MainModule.Types.Where(_ =>
                                                                                       _.CustomAttributes.Any(x => x.AttributeType.FullName == GenerateCustomAttribute)));
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                return(new List <TypeDefinition>());
            }
        }
        public Mono.Cecil.ModuleDefinition GetModuleZ(String DllFilename)
        {
            if (_AssemblyCache.ContainsKey(DllFilename))
            {
                return(_AssemblyCache[DllFilename].MainModule);
            }

            FileInfo DllFile = null;

            if (!Path.IsPathRooted(DllFilename))
            {
                if (File.Exists(Path.Combine(_ApplicationPath, DllFilename)))
                {
                    DllFile = new FileInfo(Path.Combine(_ApplicationPath, DllFilename));
                }
                else if (File.Exists(PathZ.Combine(_ApplicationPath, "StarshipTheory_Data", DllFilename)))
                {
                    DllFile = new FileInfo(PathZ.Combine(_ApplicationPath, "StarshipTheory_Data", DllFilename));
                }
                else if (File.Exists(PathZ.Combine(_ApplicationPath, "StarshipTheory_Data", "Managed", DllFilename)))
                {
                    DllFile = new FileInfo(PathZ.Combine(_ApplicationPath, "StarshipTheory_Data", "Managed", DllFilename));
                }
                else if (File.Exists(PathZ.Combine(AppDomain.CurrentDomain.BaseDirectory, DllFilename)))
                {
                    DllFile = new FileInfo(PathZ.Combine(AppDomain.CurrentDomain.BaseDirectory, DllFilename));
                }
            }
            else if (File.Exists(DllFilename))
            {
                DllFile = new FileInfo(DllFilename);
            }

            if (DllFile == null)
            {
                return(null);
            }

            Mono.Cecil.AssemblyDefinition Def = Mono.Cecil.AssemblyDefinition.ReadAssembly(DllFile.FullName);
            if (Def != null)
            {
                _AssemblyCache[DllFilename] = Def;
                return(Def.MainModule);
            }

            return(null);
        }
Beispiel #14
0
        static private void nestSearch(Mono.Cecil.TypeDefinition type,
                                       Mono.Cecil.AssemblyDefinition assembly,
                                       ref string prefix,
                                       _delegate del)
        {
            if (prefix != "")
            {
                prefix += ".";
            }
            if (type.Namespace != "")
            {
                prefix += type.Namespace + ".";
            }
            prefix += type.Name;

            var _prefix = prefix;

            type.NestedTypes.ToList().ForEach(x =>
            {
                del(x, assembly, _prefix);
            });
        }
Beispiel #15
0
        public static BuildArtifact Get(byte[] data)
        {
            BuildArtifact art = new BuildArtifact();

            using (MemoryStream ms = new MemoryStream(data))
            {
                try
                {
                    Mono.Cecil.AssemblyDefinition    def  = Mono.Cecil.AssemblyDefinition.ReadAssembly(ms);
                    Mono.Cecil.AssemblyNameReference defn = Mono.Cecil.AssemblyNameDefinition.Parse(def.FullName);

                    art.Version    = defn.Version.ToString();
                    art.Name       = defn.Name;
                    art.IsAssembly = true;
                }
                catch
                {
                }
            }

            art.Data = data;

            return(art);
        }
Beispiel #16
0
        static int Main(string[] args)
        {
            if (args.Length < 2)
            {
                Console.WriteLine("[?] Usage: cfg.exe MyAssembly.dll Namespace.Class.Method[:n]");
                return(-1);
            }

            var location = args[1].Split(new[] { '.' });

            if (location.Length < 3)
            {
                Console.WriteLine("[-] Please provide full path to the method - Namespace.Class.Method[:n]");
                return(-2);
            }

            var len = location.Length;

            var className  = location[len - 2];
            var methodName = location[len - 1];
            int skip       = 0;

            if (methodName.Contains(':'))
            {
                var noOfMethod = methodName.Split(':');
                methodName = noOfMethod[0];
                int.TryParse(noOfMethod[1], out skip);
            }
            var namespaceName             = String.Join(".", location.TakeWhile(x => x != className));
            AssemblyDefinition definition = AssemblyDefinition.ReadAssembly(args[0]);
            var targetMethod = definition.MainModule.Types.First(x => x.Namespace == namespaceName && x.Name == className).Methods
                               .Where(x => x.Name == methodName).Skip(skip).First();

            Console.WriteLine("digraph CFG {");
            Console.WriteLine("node [shape=box]");
            //first instruction is always a leader
            var leadersToVisit = new List <Instruction> {
                targetMethod.Body.Instructions.First()
            };
            var edges = new List <Edge>();

            foreach (var instruction in targetMethod.Body.Instructions.Skip(1))
            {
                switch (instruction.OpCode.FlowControl)
                {
                case FlowControl.Cond_Branch:
                    var leaders = instruction.Operand is Instruction[] switchTargets
                            ? switchTargets
                            : new[] { instruction.Operand as Instruction };
                    leaders = leaders.Append(instruction.Next).ToArray();
                    leadersToVisit.AddRange(leaders);
                    edges.AddRange(leaders.Select(x => new Edge {
                        From = instruction, To = x
                    }));
                    break;

                case FlowControl.Branch:
                    var branchTarget = instruction.Operand as Instruction;
                    leadersToVisit.Add(branchTarget);
                    edges.Add(new Edge {
                        From = instruction, To = instruction.Operand as Instruction
                    });

                    var previousInstruction = (instruction.Operand as Instruction).Previous;
                    edges.Add(new Edge {
                        From = previousInstruction, To = branchTarget
                    });
                    break;

                case FlowControl.Return:
                    if (instruction.Next != null)
                    {
                        leadersToVisit.Add(instruction.Next);
                    }
                    break;
                }
            }

            var distinctLeaders = leadersToVisit.Distinct(new OpCodeEqualityComparer()).ToArray();

            Array.Sort(distinctLeaders, new OpCodeComparer());
            var reverseLeadersBBs = new Dictionary <Instruction[], Instruction>();

            for (var i = 0; i < distinctLeaders.Length - 1; i++)
            {
                var leader     = distinctLeaders[i];
                var nextLeader = distinctLeaders[i + 1];
                var bb         = targetMethod.Body.Instructions
                                 .SkipWhile(x => x.Offset < leader.Offset)
                                 .TakeWhile(x => x.Offset < nextLeader.Offset)
                                 .ToArray();
                reverseLeadersBBs.Add(bb, leader);
                PrintBB(leader, bb);
            }

            var lastLeader   = distinctLeaders.Last();
            var lastLeaderBB = targetMethod.Body.Instructions.SkipWhile(x => x.Offset < lastLeader.Offset).ToArray();

            PrintBB(lastLeader, lastLeaderBB);
            reverseLeadersBBs.Add(lastLeaderBB, lastLeader);
            foreach (var edge in edges)
            {
                var leader = reverseLeadersBBs.First(x => x.Key.Select(y => y.Offset)
                                                     .Contains(edge.From.Offset)).Value;
                PrintEdge(leader, edge.To);
            }
            Console.WriteLine("}");
            return(0);
        }
 public void SetUp()
 {
     strategy = new TrackNUnitTestMethods();
     assemblyDefinition = Mono.Cecil.AssemblyDefinition.ReadAssembly(typeof(TrackNUnitTestMethodsTests).Assembly.Location);
 }
Beispiel #18
0
		protected abstract IEnumerable<TMethod> CollectConstructors (TType type); // Must return all instance ctors. May return static ctors too (they're automatically filtered out).

		protected abstract bool ContainsPlatformReference (TAssembly assembly); // returns true if the assembly is monotouch.dll too.
Beispiel #19
0
		protected abstract string GetAssemblyName (TAssembly assembly);
Beispiel #20
0
 public void GetTestAssembly()
 {
     TestAssembly = MonoCecilTypeSystemHelper.GetTestAssemlyDefinition();
 }
 public void SetUp()
 {
     strategy           = new TrackNUnitTestMethods();
     assemblyDefinition = Mono.Cecil.AssemblyDefinition.ReadAssembly(typeof(TrackNUnitTestMethodsTests).Assembly.Location);
 }
 public void GetTestAssembly()
 {
     TestAssembly = MonoCecilAssemblyHelper.GetTestAssemlyDefinition();
 }
Beispiel #23
0
        public List <AssemblyObject> Read(List <string> assemblies)
        {
            List <AssemblyObject> result = new List <AssemblyObject>();

            foreach (string assembly in assemblies)
            {
                string directory = Directory.GetCurrentDirectory();
                if (assembly.StartsWith("System"))
                {
                    // TODO: This needs more love before we include .Net modules
                    //directory = RuntimeEnvironment.GetRuntimeDirectory();
                    continue;
                }

                Mono.Cecil.AssemblyDefinition definition = Mono.Cecil.AssemblyDefinition.ReadAssembly(System.IO.Path.Combine(directory, assembly));
                foreach (Mono.Cecil.ModuleDefinition module in definition.Modules)
                {
                    foreach (Mono.Cecil.TypeDefinition type in module.Types)
                    {
                        string name = type.Name;

                        string ns = type.Namespace;

                        bool found = false;
                        foreach (string allowed in _Namespaces)
                        {
                            if (ns.StartsWith(allowed))
                            {
                                found = true;
                                break;
                            }
                        }
                        if (!found)
                        {
                            continue;
                        }

                        AssemblyObject working = result.FirstOrDefault(a => a.Namespace == ns);
                        if (working == null)
                        {
                            working = new AssemblyObject()
                            {
                                Name = ns, Namespace = ns
                            };
                            result.Add(working);
                        }

                        AssemblyObject o = new AssemblyObject()
                        {
                            Name = name, Namespace = ns
                        };
                        if (type.HasFields)
                        {
                            foreach (Mono.Cecil.FieldDefinition f in type.Fields)
                            {
                                if (f.IsPublic)
                                {
                                    string fname = f.Name;
                                    o.Fields.Add(new AssemblyObject()
                                    {
                                        Name = fname
                                    });
                                }
                            }
                        }
                        if (type.HasProperties)
                        {
                            foreach (Mono.Cecil.PropertyDefinition p in type.Properties)
                            {
                                string pname = p.Name;
                                o.Properties.Add(new AssemblyObject()
                                {
                                    Name = pname
                                });
                            }
                        }
                        if (type.HasMethods)
                        {
                            foreach (Mono.Cecil.MethodDefinition m in type.Methods)
                            {
                                if (m.IsPublic)
                                {
                                    string mname = m.Name;
                                    if (!mname.StartsWith("get_") || !mname.StartsWith("set_"))
                                    {
                                        continue;
                                    }

                                    AssemblyObject mo = new AssemblyObject()
                                    {
                                        Name = mname
                                    };
                                    if (m.HasParameters)
                                    {
                                        foreach (Mono.Cecil.ParameterDefinition r in m.Parameters)
                                        {
                                            string rname = r.Name;
                                            mo.Methods.Add(new AssemblyObject()
                                            {
                                                Name = rname
                                            });
                                        }
                                    }
                                    o.Methods.Add(mo);
                                }
                            }
                        }

                        working.Children.Add(o);
                    }
                }
            }

            return(result);
        }
        public static MonoSymbolFile ReadSymbolFile(Mono.Cecil.AssemblyDefinition assembly, string filename)
        {
            string name = filename + ".mdb";

            return(new MonoSymbolFile(name, assembly));
        }
Beispiel #25
0
		protected abstract IEnumerable<TType> CollectTypes (TAssembly assembly);
Beispiel #26
0
        public static void Inject(string input_assembly_path, string output_assembly_path, string logger_assembly_path, string logger_type_name, string before_call_log_method_name, string log_attribute_name)
        {
            System.Diagnostics.Debug.Assert(System.IO.File.Exists(input_assembly_path));

            if (input_assembly_path != output_assembly_path)
            {
                if (System.IO.File.Exists(output_assembly_path))
                {
                    System.IO.File.Delete(output_assembly_path);
                }
                System.IO.File.Copy(input_assembly_path, output_assembly_path);
                System.Diagnostics.Debug.Assert(System.IO.File.Exists(output_assembly_path));
            }

            var    assembly_resolver        = new Mono.Cecil.DefaultAssemblyResolver();
            string input_assembly_directory = System.IO.Path.GetDirectoryName(input_assembly_path);

            assembly_resolver.AddSearchDirectory(input_assembly_directory);
            #if SILVERLIGHT
            Microsoft.Silverlight.Build.Tasks.GetSilverlightFrameworkPath path_task = new Microsoft.Silverlight.Build.Tasks.GetSilverlightFrameworkPath();
            path_task.RegistryBase = "Software\\Microsoft\\Microsoft SDKs\\Silverlight";
            path_task.Execute();
            assembly_resolver.AddSearchDirectory(path_task.SilverlightPath);
            foreach (string path in path_task.SilverlightSDKPaths)
            {
                assembly_resolver.AddSearchDirectory(path);
            }
            #endif
            Mono.Cecil.AssemblyDefinition injectible_assembly = Mono.Cecil.AssemblyDefinition.ReadAssembly(output_assembly_path, new Mono.Cecil.ReaderParameters {
                AssemblyResolver = assembly_resolver
            });

            System.Diagnostics.Debug.Assert(System.IO.File.Exists(logger_assembly_path));
            Mono.Cecil.AssemblyDefinition logger_assembly = Mono.Cecil.AssemblyDefinition.ReadAssembly(logger_assembly_path);
            Mono.Cecil.TypeDefinition     logger_type     = logger_assembly.MainModule.GetType(logger_type_name);
            System.Diagnostics.Debug.Assert(logger_type != null);
            Mono.Cecil.MethodDefinition before_callback_method_info = logger_type.Methods.First(m => m.Name == before_call_log_method_name);
            Mono.Cecil.MethodReference  before_callback_reference   = injectible_assembly.MainModule.Import(before_callback_method_info);

            //make sure to get System.Object.ToString method from assembly compatible with the injected assembly
            #if SILVERLIGHT
            string core_assembly_path = path_task.SilverlightPath + "mscorlib.dll";
            Mono.Cecil.AssemblyDefinition core_assembly         = Mono.Cecil.AssemblyDefinition.ReadAssembly(core_assembly_path);
            Mono.Cecil.TypeDefinition     object_type           = core_assembly.MainModule.GetType("System.Object");
            Mono.Cecil.MethodDefinition   to_string_method_info = object_type.Methods.First(m => m.Name == "ToString");
            #else
            System.Reflection.MethodInfo to_string_method_info = typeof(System.Object).GetMethod("ToString");
            #endif
            Mono.Cecil.MethodReference to_string_reference = injectible_assembly.MainModule.Import(to_string_method_info);

            foreach (Mono.Cecil.TypeDefinition type_definition in injectible_assembly.MainModule.Types)
            {
                bool is_type_logable = type_definition.CustomAttributes.Any(a => a.AttributeType.FullName == log_attribute_name);
                foreach (Mono.Cecil.MethodDefinition method_definition in type_definition.Methods)
                {
                    bool is_method_logable = is_type_logable || method_definition.CustomAttributes.Any(a => a.AttributeType.FullName == log_attribute_name);

                    if (is_method_logable)
                    {
                        Mono.Cecil.Cil.ILProcessor processor = method_definition.Body.GetILProcessor();

                        System.Collections.Generic.List <Mono.Cecil.Cil.Instruction> original_instructions = new System.Collections.Generic.List <Mono.Cecil.Cil.Instruction>();
                        original_instructions.AddRange(method_definition.Body.Instructions);
                        method_definition.Body.Instructions.Clear();

                        #region parameters

                        int method_parameters_count = method_definition.Parameters.Count;
                        int local_variables_count   = method_definition.Body.Variables.Count;
                        int arguments_array_index   = local_variables_count;

                        // Create an array of type System.String with the same number of elements as count of method parameters
                        // Add metadata for a new variable of type System.String[] to method body
                        // .locals init (System.String[] V_0)
                        Mono.Cecil.ArrayType arguments = new Mono.Cecil.ArrayType(injectible_assembly.MainModule.TypeSystem.String);
                        method_definition.Body.Variables.Add(new Mono.Cecil.Cil.VariableDefinition((Mono.Cecil.TypeReference)arguments));
                        method_definition.Body.InitLocals = true;
                        method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Ldc_I4, method_parameters_count));
                        method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Newarr, injectible_assembly.MainModule.TypeSystem.String));
                        // This instruction will store the address of the newly created array in the newly added local variable, which is at index = local_variables_count
                        method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Stloc, arguments_array_index));

                        #region parameters_to_string

                        // Instance methods have an an implicit argument called "this"
                        // so in that case we need to refer to actual arguments with +1 position
                        int parameter_offset = method_definition.IsStatic ? 0 : 1;
                        for (int i = 0; i < method_parameters_count; ++i)
                        {
                            // load argument array and current index
                            method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Ldloc, arguments_array_index));
                            method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Ldc_I4, i));

                            // load argument
                            method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Ldarga, i + parameter_offset));

                            // convert argument to string
                            Mono.Cecil.TypeReference argument_type = method_definition.Parameters[i].ParameterType;

                            method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Constrained, argument_type));
                            method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Callvirt, to_string_reference));

                            // store string in array
                            method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Stelem_Ref));
                        }

                        #endregion parameters_to_string

                        string method_signature = method_definition.ToString();
                        // load method signature
                        method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Ldstr, method_signature));

                        // load parameters array
                        method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Ldloc, arguments_array_index));

                        #endregion parameters

                        // load before call instruction
                        method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Call, before_callback_reference));

                        foreach (var IL in original_instructions)
                        {
                            method_definition.Body.Instructions.Add(IL);
                        }
                    }
                }
            }

            injectible_assembly.Write(output_assembly_path);
        }
Beispiel #27
0
		public void RegisterAssembly (TAssembly assembly)
		{
			if (assembly == null)
				throw new ArgumentNullException ("assembly");

			if (assemblies.ContainsKey (assembly))
				return;

			if (!ContainsPlatformReference (assembly)) {
				assemblies.Add (assembly, null);
				return;
			}

			if (SkipRegisterAssembly (assembly)) {
				Trace ("[ASSEMBLY] Skipped registration for {0}", GetAssemblyName (assembly));
				return;
			}
			
			var exceptions = new List<Exception> ();

			try {
				var types = CollectTypes (assembly);

				Trace ("[ASSEMBLY] Registering {0}", assembly.ToString ());

				// Normally this method is only called at startup, when we're still
				// single-threaded. In this case it makes sense to lock as seldom as
				// possible, so instead of locking 'types' once for every type, we
				// lock it once for all of them.
				lock (this.types) {
					foreach (TType type in types) {
						//Trace (" Checking {0}", GetTypeFullName (type));
						if (HasModelAttribute (type)) {
							Trace ("{0} is a model: not registering it", GetTypeFullName (type));
							continue;
						}

						RegisterTypeUnsafe (type, ref exceptions);
					}
				}

				assemblies.Add (assembly, null);
			} catch (Exception e) {
				ReportError (4116, "Could not register the assembly '{0}': {1}", GetAssemblyName (assembly), e);
			}

			FlushTrace ();

			if (exceptions.Count > 0) {
				Exception ae = exceptions.Count == 1 ? exceptions [0] : new AggregateException (exceptions);
#if !MTOUCH
				Console.WriteLine (ae);
#endif
				throw ae;
			}
		}
        protected MonoSymbolFile(string filename, Mono.Cecil.AssemblyDefinition assembly) : this(filename)
        {
            Guid mvid = assembly.MainModule.Mvid;

            CheckGuidMatch(mvid, filename, assembly.MainModule.Image.FileInformation.FullName);
        }
        public IEnumerable <Mono.Cecil.TypeDefinition> Filter(Mono.Cecil.AssemblyDefinition assembly)
        {
            bool IsEnginedSupportedType(Mono.Cecil.TypeDefinition type)
            {
                if (GhostAuthoringModifiers.GhostDefaultOverrides.TryGetValue(type.FullName.Replace("/", "+"), out var newComponent))
                {
                    return(true);
                }
                return(false);
            }

            var excludeTypes = excludeList;

            bool IsGhostPredicate(Mono.Cecil.TypeDefinition t)
            {
                if (!t.IsValueType || t.IsPrimitive || t.IsIRpcCommand())
                {
                    return(false);
                }

                if (t.HasCustomAttributes)
                {
                    var variant = t.GetAttribute <GhostComponentVariationAttribute>();
                    if (variant != null)
                    {
                        return(true);
                    }
                }
                if (!(t.IsIComponentData() || t.IsBufferElementData() || t.IsICommandData()))
                {
                    return(false);
                }

                if (excludeTypes != null && excludeTypes.Contains(t.FullName))
                {
                    return(false);
                }

                // Backward compatibility for Transform and Rotation and other default types here.
                // Customize the below method in case you need to add more
                if (IsEnginedSupportedType(t))
                {
                    return(true);
                }

                return((t.HasFields && t.Fields.Any(f => f.IsPublic && f.HasAttribute <GhostFieldAttribute>())) ||
                       (t.HasProperties && t.Properties.Any(f =>
                                                            f.GetMethod != null && f.GetMethod.IsPublic && f.SetMethod != null && f.SetMethod.IsPublic &&
                                                            f.HasAttribute <GhostFieldAttribute>())));
            }

            var result = new List <Mono.Cecil.TypeDefinition>();

            if (assembly?.Modules != null)
            {
                foreach (var m in assembly.Modules)
                {
                    if (m != null)
                    {
                        result.AddRange(m.GetTypes().Where(IsGhostPredicate));
                    }
                }
            }

            return(result);
        }
Beispiel #30
0
		protected virtual bool SkipRegisterAssembly (TAssembly assembly) { return false; }