/// <summary>
        ///     Constructor
        /// </summary>
        /// <param name="ctor">Custom attribute constructor</param>
        /// <param name="arguments">Constructor arguments. The list is now owned by this instance.</param>
        /// <param name="namedArguments">Named arguments. The list is now owned by this instance.</param>
        /// <param name="blobReader">A reader that returns the original custom attribute blob data</param>
        internal CustomAttribute(ICustomAttributeType ctor, ThreadSafe.List <CAArgument> arguments, ThreadSafe.List <CANamedArgument> namedArguments, IBinaryReader blobReader)
        {
            Constructor          = ctor;
            ConstructorArguments = arguments == null?ThreadSafeListCreator.Create <CAArgument>() : ThreadSafeListCreator.MakeThreadSafe(arguments);

            NamedArguments = namedArguments == null?ThreadSafeListCreator.Create <CANamedArgument>() : ThreadSafeListCreator.MakeThreadSafe(namedArguments);

            this.blobReader = blobReader;
        }
 /// <summary>
 ///     Constructor
 /// </summary>
 /// <param name="method">The method with all parameters</param>
 /// <param name="declaringType"><paramref name="method" />'s declaring type</param>
 public ParameterList(MethodDef method, TypeDef declaringType)
 {
     Method              = method;
     parameters          = new ThreadSafe.List <Parameter>();
     methodSigIndexBase  = -1;
     hiddenThisParameter = new Parameter(this, 0, Parameter.HIDDEN_THIS_METHOD_SIG_INDEX);
     returnParameter     = new Parameter(this, -1, Parameter.RETURN_TYPE_METHOD_SIG_INDEX);
     UpdateThisParameterType(declaringType);
     UpdateParameterTypes();
 }
        /// <summary>
        ///     Reads the directory header and initializes <see cref="ResourceDirectory.directories" /> and
        ///     <see cref="ResourceDirectory.data" />.
        /// </summary>
        /// <param name="reader"></param>
        private void Initialize(IBinaryReader reader)
        {
            if (depth > MAX_DIR_DEPTH || !reader.CanRead(16))
            {
                InitializeDefault();
                return;
            }

            characteristics = reader.ReadUInt32();
            timeDateStamp   = reader.ReadUInt32();
            majorVersion    = reader.ReadUInt16();
            minorVersion    = reader.ReadUInt16();
            var numNamed = reader.ReadUInt16();
            var numIds   = reader.ReadUInt16();

            var total = numNamed + numIds;

            if (!reader.CanRead(total * 8))
            {
                InitializeDefault();
                return;
            }

            dataInfos = new ThreadSafe.List <EntryInfo>();
            dirInfos  = new ThreadSafe.List <EntryInfo>();
            var offset = reader.Position;

            for (var i = 0; i < total; i++, offset += 8)
            {
                reader.Position = offset;
                var          nameOrId        = reader.ReadUInt32();
                var          dataOrDirectory = reader.ReadUInt32();
                ResourceName name;
                if ((nameOrId & 0x80000000) != 0)
                {
                    name = new ResourceName(ReadString(reader, nameOrId & 0x7FFFFFFF) ?? string.Empty);
                }
                else
                {
                    name = new ResourceName((int)nameOrId);
                }

                if ((dataOrDirectory & 0x80000000) == 0)
                {
                    dataInfos.Add(new EntryInfo(name, dataOrDirectory));
                }
                else
                {
                    dirInfos.Add(new EntryInfo(name, dataOrDirectory & 0x7FFFFFFF));
                }
            }

            directories = new LazyList <ResourceDirectory>(dirInfos.Count, null, (ctx, i) => ReadResourceDirectory((int)i));
            data        = new LazyList <ResourceData>(dataInfos.Count, null, (ctx, i) => ReadResourceData((int)i));
        }
예제 #4
0
        private void InitializeInverseGenericParamOwnerRidList()
        {
            if (gpRidToOwnerRid != null)
            {
                return;
            }
            var gpTable            = tablesStream.GenericParamTable;
            var newGpRidToOwnerRid = new uint[gpTable.Rows];

            // Find all owners by reading the GenericParam.Owner column
            var ownerCol   = gpTable.TableInfo.Columns[2];
            var ownersDict = new ThreadSafe.Dictionary <uint, bool>();

#if THREAD_SAFE
            tablesStream.theLock.EnterWriteLock(); try {
#endif
            for (uint rid = 1; rid <= gpTable.Rows; rid++)
            {
                uint owner;
                if (!tablesStream.ReadColumn_NoLock(gpTable, rid, ownerCol, out owner))
                {
                    continue;
                }
                ownersDict[owner] = true;
            }
#if THREAD_SAFE
        }

        finally { tablesStream.theLock.ExitWriteLock(); }
#endif

            // Now that we have the owners, find all the generic params they own. An obfuscated
            // module could have 2+ owners pointing to the same generic param row.
            var owners = new ThreadSafe.List <uint>(ownersDict.Keys);
            owners.Sort();
            for (var i = 0; i < owners.Count; i++)
            {
                uint ownerToken;
                if (!CodedToken.TypeOrMethodDef.Decode(owners[i], out ownerToken))
                {
                    continue;
                }
                var ridList = GetGenericParamRidList(MDToken.ToTable(ownerToken), MDToken.ToRID(ownerToken));
                for (uint j = 0; j < ridList.Length; j++)
                {
                    var ridIndex = ridList[j] - 1;
                    if (newGpRidToOwnerRid[ridIndex] != 0)
                    {
                        continue;
                    }
                    newGpRidToOwnerRid[ridIndex] = owners[i];
                }
            }
            Interlocked.CompareExchange(ref gpRidToOwnerRid, newGpRidToOwnerRid, null);
        }
        private ThreadSafe.IEnumerable <string> GetPrivatePaths(string baseDir, string configFileName)
        {
            var searchPaths = new ThreadSafe.List <string>();

            try
            {
                var dirName = Path.GetDirectoryName(Path.GetFullPath(configFileName));

                searchPaths.Add(dirName);

                using (var xmlStream = new FileStream(configFileName, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    var doc = new XmlDocument();
                    doc.Load(XmlReader.Create(xmlStream));
                    foreach (var tmp in doc.GetElementsByTagName("probing"))
                    {
                        var probingElem = tmp as XmlElement;
                        if (probingElem == null)
                        {
                            continue;
                        }
                        var privatePath = probingElem.GetAttribute("privatePath");
                        if (string.IsNullOrEmpty(privatePath))
                        {
                            continue;
                        }
                        foreach (var tmp2 in privatePath.Split(';'))
                        {
                            var path = tmp2.Trim();
                            if (path == "")
                            {
                                continue;
                            }
                            var newPath = Path.GetFullPath(Path.Combine(dirName, path.Replace('\\', Path.DirectorySeparatorChar)));
                            if (Directory.Exists(newPath) && newPath.StartsWith(baseDir + Path.DirectorySeparatorChar))
                            {
                                searchPaths.Add(newPath);
                            }
                        }
                    }
                }
            }
            catch (ArgumentException)
            {
            }
            catch (IOException)
            {
            }
            catch (XmlException)
            {
            }

            return(searchPaths);
        }
예제 #6
0
        private void InitializeInverseGenericParamConstraintOwnerRidList()
        {
            if (gpcRidToOwnerRid != null)
            {
                return;
            }
            var gpcTable            = tablesStream.GenericParamConstraintTable;
            var newGpcRidToOwnerRid = new uint[gpcTable.Rows];

            var ownerCol   = gpcTable.TableInfo.Columns[0];
            var ownersDict = new ThreadSafe.Dictionary <uint, bool>();

#if THREAD_SAFE
            tablesStream.theLock.EnterWriteLock(); try {
#endif
            for (uint rid = 1; rid <= gpcTable.Rows; rid++)
            {
                uint owner;
                if (!tablesStream.ReadColumn_NoLock(gpcTable, rid, ownerCol, out owner))
                {
                    continue;
                }
                ownersDict[owner] = true;
            }
#if THREAD_SAFE
        }

        finally { tablesStream.theLock.ExitWriteLock(); }
#endif

            var owners = new ThreadSafe.List <uint>(ownersDict.Keys);
            owners.Sort();
            for (var i = 0; i < owners.Count; i++)
            {
                var ownerToken = owners[i];
                var ridList    = GetGenericParamConstraintRidList(ownerToken);
                for (uint j = 0; j < ridList.Length; j++)
                {
                    var ridIndex = ridList[j] - 1;
                    if (newGpcRidToOwnerRid[ridIndex] != 0)
                    {
                        continue;
                    }
                    newGpcRidToOwnerRid[ridIndex] = ownerToken;
                }
            }
            Interlocked.CompareExchange(ref gpcRidToOwnerRid, newGpcRidToOwnerRid, null);
        }
        /// <summary>
        ///     Gets all search paths to use for this module
        /// </summary>
        /// <param name="module">The module or <c>null</c> if unknown</param>
        /// <returns>A list of all search paths to use for this module</returns>
        private ThreadSafe.IEnumerable <string> GetSearchPaths(ModuleDef module)
        {
            var keyModule = module;

            if (keyModule == null)
            {
                keyModule = nullModule;
            }
            ThreadSafe.IList <string> searchPaths;
            if (moduleSearchPaths.TryGetValue(keyModule, out searchPaths))
            {
                return(searchPaths);
            }
            moduleSearchPaths[keyModule] = searchPaths = new ThreadSafe.List <string>(GetModuleSearchPaths(module));
            return(searchPaths);
        }
        private ThreadSafe.IEnumerable <string> GetDirs(string baseDir)
        {
            var dirs = new ThreadSafe.List <string>();

            try
            {
                foreach (var di in new DirectoryInfo(baseDir).GetDirectories())
                {
                    dirs.Add(di.FullName);
                }
            }
            catch
            {
            }
            return(dirs);
        }
        /// <inheritdoc />
        public void Clear()
        {
            ThreadSafe.List <AssemblyDef> asms;
#if THREAD_SAFE
            theLock.EnterWriteLock(); try {
#endif
            asms = new ThreadSafe.List <AssemblyDef>(cachedAssemblies.Values);
            cachedAssemblies.Clear();
#if THREAD_SAFE
        }
        finally { theLock.ExitWriteLock(); }
#endif
            foreach (var asm in asms)
            {
                if (asm == null)
                {
                    continue;
                }
                foreach (var mod in asm.Modules.GetSafeEnumerable())
                {
                    mod.Dispose();
                }
            }
        }
        static AssemblyResolver()
        {
            gacInfos = new ThreadSafe.List <GacInfo>();

            if (Type.GetType("Mono.Runtime") != null)
            {
                var dirs = new ThreadSafe.Dictionary <string, bool>(StringComparer.OrdinalIgnoreCase);
                extraMonoPaths = new ThreadSafe.List <string>();
                foreach (var prefix in FindMonoPrefixes())
                {
                    var dir = Path.Combine(Path.Combine(Path.Combine(prefix, "lib"), "mono"), "gac");
                    if (dirs.ContainsKey(dir))
                    {
                        continue;
                    }
                    dirs[dir] = true;

                    if (Directory.Exists(dir))
                    {
                        gacInfos.Add(new GacInfo(-1, "", Path.GetDirectoryName(dir), new[]
                        {
                            Path.GetFileName(dir)
                        }));
                    }

                    dir = Path.GetDirectoryName(dir);
                    foreach (var verDir in monoVerDirs)
                    {
                        var dir2 = Path.Combine(dir, verDir);
                        if (Directory.Exists(dir2))
                        {
                            extraMonoPaths.Add(dir2);
                        }
                    }
                }

                var paths = Environment.GetEnvironmentVariable("MONO_PATH");
                if (paths != null)
                {
                    foreach (var path in paths.Split(Path.PathSeparator))
                    {
                        if (path != string.Empty && Directory.Exists(path))
                        {
                            extraMonoPaths.Add(path);
                        }
                    }
                }
            }
            else
            {
                var windir = Environment.GetEnvironmentVariable("WINDIR");
                if (!string.IsNullOrEmpty(windir))
                {
                    string path;

                    // .NET 1.x and 2.x
                    path = Path.Combine(windir, "assembly");
                    if (Directory.Exists(path))
                    {
                        gacInfos.Add(new GacInfo(2, "", path, new[]
                        {
                            "GAC_32", "GAC_64", "GAC_MSIL", "GAC"
                        }));
                    }

                    // .NET 4.x
                    path = Path.Combine(Path.Combine(windir, "Microsoft.NET"), "assembly");
                    if (Directory.Exists(path))
                    {
                        gacInfos.Add(new GacInfo(4, "v4.0_", path, new[]
                        {
                            "GAC_32", "GAC_64", "GAC_MSIL"
                        }));
                    }
                }
            }
        }
예제 #11
0
        private void InitializeNestedClassesDictionary()
        {
            var table     = tablesStream.NestedClassTable;
            var destTable = tablesStream.TypeDefTable;

            ThreadSafe.Dictionary <uint, bool> validTypeDefRids = null;
            var typeDefRidList = GetTypeDefRidList();

            if (typeDefRidList.Length != destTable.Rows)
            {
                validTypeDefRids = new ThreadSafe.Dictionary <uint, bool>((int)typeDefRidList.Length);
                for (uint i = 0; i < typeDefRidList.Length; i++)
                {
                    validTypeDefRids[typeDefRidList[i]] = true;
                }
            }

            var nestedRidsDict = new ThreadSafe.Dictionary <uint, bool>((int)table.Rows);
            var nestedRids     = new ThreadSafe.List <uint>((int)table.Rows); // Need it so we add the rids in correct order

            for (uint rid = 1; rid <= table.Rows; rid++)
            {
                if (validTypeDefRids != null && !validTypeDefRids.ContainsKey(rid))
                {
                    continue;
                }
                var row = tablesStream.ReadNestedClassRow(rid);
                if (row == null)
                {
                    continue; // Should never happen since rid is valid
                }
                if (!destTable.IsValidRID(row.NestedClass) || !destTable.IsValidRID(row.EnclosingClass))
                {
                    continue;
                }
                if (nestedRidsDict.ContainsKey(row.NestedClass))
                {
                    continue;
                }
                nestedRidsDict[row.NestedClass] = true;
                nestedRids.Add(row.NestedClass);
            }

            var newTypeDefRidToNestedClasses = new ThreadSafe.Dictionary <uint, RandomRidList>();

            foreach (var nestedRid in nestedRids)
            {
                var row = tablesStream.ReadNestedClassRow(GetNestedClassRid(nestedRid));
                if (row == null)
                {
                    continue;
                }
                RandomRidList ridList;
                if (!newTypeDefRidToNestedClasses.TryGetValue(row.EnclosingClass, out ridList))
                {
                    newTypeDefRidToNestedClasses[row.EnclosingClass] = ridList = new RandomRidList();
                }
                ridList.Add(nestedRid);
            }

            var newNonNestedTypes = new RandomRidList((int)(destTable.Rows - nestedRidsDict.Count));

            for (uint rid = 1; rid <= destTable.Rows; rid++)
            {
                if (validTypeDefRids != null && !validTypeDefRids.ContainsKey(rid))
                {
                    continue;
                }
                if (nestedRidsDict.ContainsKey(rid))
                {
                    continue;
                }
                newNonNestedTypes.Add(rid);
            }

            Interlocked.CompareExchange(ref nonNestedTypes, newNonNestedTypes, null);

            // Initialize this one last since it's tested by the callers of this method
            Interlocked.CompareExchange(ref typeDefRidToNestedClasses, newTypeDefRidToNestedClasses, null);
        }