/// <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)); }
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); }
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" })); } } } }
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); }