/// <summary> /// Populates the list of assembly references. /// </summary> void LoadAssemblyReferences() //^ ensures this.AssemblyReferenceArray != null; { uint numberOfAssemblyReferences = this.PEFileReader.AssemblyRefTable.NumberOfRows; AssemblyReference[] assemblyRefList = new AssemblyReference[numberOfAssemblyReferences + 1]; for (uint i = 1; i <= numberOfAssemblyReferences; ++i) { AssemblyRefRow assemblyRefRow = this.PEFileReader.AssemblyRefTable[i]; IName assemblyRefName = this.GetNameFromOffset(assemblyRefRow.Name); IName cultureName = this.GetNameFromOffset(assemblyRefRow.Culture); Version version = new Version(assemblyRefRow.MajorVersion, assemblyRefRow.MinorVersion, assemblyRefRow.BuildNumber, assemblyRefRow.RevisionNumber); byte[] publicKeyTokenArray = TypeCache.EmptyByteArray; if (assemblyRefRow.PublicKeyOrToken != 0) { var publicKeyOrTokenArray = this.PEFileReader.BlobStream[assemblyRefRow.PublicKeyOrToken]; if ((assemblyRefRow.Flags & AssemblyFlags.PublicKey) == AssemblyFlags.PublicKey && publicKeyOrTokenArray.Length > 0) { publicKeyTokenArray = UnitHelper.ComputePublicKeyToken(publicKeyOrTokenArray); } else { publicKeyTokenArray = publicKeyOrTokenArray; } if (publicKeyTokenArray.Length != 8) { // Error } } AssemblyIdentity assemblyIdentity = new AssemblyIdentity(assemblyRefName, cultureName.Value, version, publicKeyTokenArray, string.Empty); AssemblyReference assemblyReference = new AssemblyReference(this, i, assemblyIdentity, assemblyRefRow.Flags); assemblyRefList[i] = assemblyReference; } this.AssemblyReferenceArray = assemblyRefList; }
// Caller should lock this. internal Assembly/*?*/ ResolveAssemblyRefReference( AssemblyReference assemblyReference ) { Assembly/*?*/ assem = this.ModuleReader.LookupAssembly(this.Module, assemblyReference.UnifiedAssemblyIdentity); return assem; }
private AssemblyIdentity GetCoreAssemblySymbolicIdentity() { lock (GlobalLock.LockingObject) { INameTable nameTable = this.NameTable; PeReader peReader = this.ModuleReader; int systemKey = nameTable.System.UniqueKey; int objectKey = nameTable.Object.UniqueKey; int valueTypeKey = nameTable.ValueType.UniqueKey; int enumKey = nameTable.Enum.UniqueKey; int multicastDelegateKey = nameTable.MulticastDelegate.UniqueKey; int arrayKey = nameTable.Array.UniqueKey; int attributeKey = nameTable.Attribute.UniqueKey; int delegateKey = nameTable.Delegate.UniqueKey; int iAsyncResultKey = peReader.IAsyncResult.UniqueKey; int iCloneableKey = peReader.ICloneable.UniqueKey; int asyncCallbackKey = peReader.AsyncCallback.UniqueKey; int attributeUsageAttributeKey = nameTable.AttributeUsageAttribute.UniqueKey; int paramArrayAttributeKey = peReader.ParamArrayAttribute.UniqueKey; int booleanKey = nameTable.Boolean.UniqueKey; int byteKey = nameTable.Byte.UniqueKey; int charKey = nameTable.Char.UniqueKey; int sByteKey = nameTable.SByte.UniqueKey; int int16Key = nameTable.Int16.UniqueKey; int uint16Key = nameTable.UInt16.UniqueKey; int int32Key = nameTable.Int32.UniqueKey; int uint32Key = nameTable.UInt32.UniqueKey; int int64Key = nameTable.Int64.UniqueKey; int uint64Key = nameTable.UInt64.UniqueKey; int stringKey = nameTable.String.UniqueKey; int intPtrKey = nameTable.IntPtr.UniqueKey; int uintPtrKey = nameTable.UIntPtr.UniqueKey; int singleKey = nameTable.Single.UniqueKey; int doubleKey = nameTable.Double.UniqueKey; int typedReferenceKey = nameTable.TypedReference.UniqueKey; int typeKey = nameTable.Type.UniqueKey; int dateTimeKey = nameTable.DateTime.UniqueKey; int decimalKey = nameTable.Decimal.UniqueKey; int dbNullKey = nameTable.DBNull.UniqueKey; int runtimeArgumentHandleKey = peReader.RuntimeArgumentHandle.UniqueKey; int runtimeFieldHandleKey = peReader.RuntimeFieldHandle.UniqueKey; int runtimeMethodHandleKey = peReader.RuntimeMethodHandle.UniqueKey; int runtimeTypeHandleKey = peReader.RuntimeTypeHandle.UniqueKey; int argIteratorKey = peReader.ArgIterator.UniqueKey; int voidKey = nameTable.Void.UniqueKey; int mscorlibKey = peReader.Mscorlib.UniqueKey; int systemRuntimeKey = peReader.System_Runtime.UniqueKey; TypeRefTableReader trTable = this.PEFileReader.TypeRefTable; var hitCounts = new uint[trTable.NumberOfRows]; for (uint i = 1; i <= trTable.NumberOfRows; i++) { TypeRefRow tr = trTable[i]; IName nsName = this.GetNameFromOffset(tr.Namespace); if (nsName.UniqueKey != systemKey) continue; int tKey = this.GetNameFromOffset(tr.Name).UniqueKey; //Look for a lot of different mscorlib types, since an assembly need not reference System.Object or any particular type. if (tKey != objectKey && tKey != valueTypeKey && tKey != enumKey && tKey != multicastDelegateKey && tKey != arrayKey && tKey != attributeKey && tKey != delegateKey && tKey != iAsyncResultKey && tKey != iCloneableKey && tKey != asyncCallbackKey && tKey != attributeUsageAttributeKey && tKey != paramArrayAttributeKey && tKey != booleanKey && tKey != byteKey && tKey != charKey && tKey != sByteKey && tKey != int16Key && tKey != uint16Key && tKey != int32Key && tKey != uint32Key && tKey != int64Key && tKey != uint64Key && tKey != stringKey && tKey != intPtrKey && tKey != uintPtrKey && tKey != singleKey && tKey != doubleKey && tKey != typedReferenceKey && tKey != typeKey && tKey != dateTimeKey && tKey != decimalKey && tKey != dbNullKey && tKey != runtimeArgumentHandleKey && tKey != runtimeFieldHandleKey && tKey != runtimeMethodHandleKey && tKey != runtimeTypeHandleKey && tKey != argIteratorKey && tKey != voidKey) continue; uint resolutionScopeKind = (tr.ResolutionScope & TokenTypeIds.TokenTypeMask); if (resolutionScopeKind != TokenTypeIds.AssemblyRef) continue; uint resolutionScopeRowId = (tr.ResolutionScope & TokenTypeIds.RIDMask); //Just because this reference looks like a mscorlib type, does not mean that it actually is one. Badly behaved assemblies might reuse mscorlib names. //We therefore count the number of references and hope that mscorlib has a majority. hitCounts[resolutionScopeRowId-1]++; if (tKey == enumKey) this.SystemEnumAssembly = this.AssemblyReferenceArray[resolutionScopeRowId]; else if (tKey == valueTypeKey) this.SystemValueTypeAssembly = this.AssemblyReferenceArray[resolutionScopeRowId]; else if (tKey == multicastDelegateKey) this.SystemMulticastDelegateAssembly = this.AssemblyReferenceArray[resolutionScopeRowId]; else if (tKey == typeKey) this.SystemTypeAssembly = this.AssemblyReferenceArray[resolutionScopeRowId]; else if (tKey == paramArrayAttributeKey) this.SystemParamArrayAttributeAssembly = this.AssemblyReferenceArray[resolutionScopeRowId]; } uint maxHits = 0; uint rowWithMaxHits = 0; for (uint i = 0; i < hitCounts.Length; i++) { if (hitCounts[i] > maxHits) { maxHits = hitCounts[i]; rowWithMaxHits = i; } } if (maxHits > 0) { return this.AssemblyReferenceArray[rowWithMaxHits+1].AssemblyIdentity; } TypeDefTableReader tdTable = this.PEFileReader.TypeDefTable; for (uint i = 1; i <= tdTable.NumberOfRows; i++) { TypeDefRow td = tdTable[i]; IName nsName = this.GetNameFromOffset(td.Namespace); if (nsName.UniqueKey != systemKey) continue; int tKey = this.GetNameFromOffset(td.Name).UniqueKey; //if you're mscorlib, you have to define System.Object if (tKey != objectKey) continue; AssemblyIdentity/*?*/ result = this.Module.ModuleIdentity as AssemblyIdentity; if (result != null) return result; //TODO: error break; } AssemblyRefTableReader arTable = this.PEFileReader.AssemblyRefTable; for (uint i = 1; i <= arTable.NumberOfRows; i++) { AssemblyRefRow ar = arTable[i]; int key = this.GetNameFromOffset(ar.Name).UniqueKey; if (key != systemRuntimeKey) continue; var identity = this.AssemblyReferenceArray[i].AssemblyIdentity; if (identity.Version.Major >= 4) return identity; } for (uint i = 1; i <= arTable.NumberOfRows; i++) { AssemblyRefRow ar = arTable[i]; int key = this.GetNameFromOffset(ar.Name).UniqueKey; if (key != mscorlibKey) continue; return this.AssemblyReferenceArray[i].AssemblyIdentity; } } return Dummy.AssemblyIdentity; }