//Retrieves the details of DLLs and entry points used by P/Invoke public ArrayList GetPInvokeDetails() { ArrayList externalDetails = new ArrayList(); ImplMap implMap = this.peFile.tables.ImplMap; ModuleRef moduleRef = this.peFile.tables.ModuleRef; MethodDef moduleDef = this.peFile.tables.MethodDef; // get the name from the target type and for each type in TypeDef table check the Name for a match. // When the match is found, get the namespace and methodlist start and methodlist finish (by looking at the next row method list start) // Look at all the MethodDefs for the type, for each row look in ImplMap.memberForwarded. // If found, return pinvoke details. for (int i = 0; i < implMap.NumberOfRows; i++) { // ImplMap.MemberForwarded is a coded token with the first bit defining // whether it indexes the MethodDef or Field table. As imported fields are not // supported it always points to the MethodDef table so we can r-shift the bits // to get the correct index into the methoddef table uint methodIndex = implMap.MemberForwarded[i] >> 1; string typeName = GetTypeName(methodIndex); string methodName = (methodIndex > 0) ? GetStringFromStringHeap(moduleDef.Name[methodIndex - 1]) : String.Empty; // Get the dll name and method name string importedMethodName = GetStringFromStringHeap(implMap.ImportName[i]); // import scope points to the moduleref table uint moduleRefEntry = implMap.ImportScope[i]; string dllName = (moduleRefEntry > 0) ? GetStringFromStringHeap(moduleRef.Name[moduleRefEntry - 1]) : String.Empty; externalDetails.Add(new Crossplatform.NET.PInvokeCallDetails(typeName, methodName, dllName, importedMethodName)); } return(externalDetails); }
public Tables(TablesHeader tablesHeader, MetaDataStream stringHeap, BinaryReader reader) { this.tablesHeader = tablesHeader; this.stringHeap = stringHeap; this.reader = reader; this.indexSizeIndicator = tablesHeader.HeapSizes; this.RowsPerTable = tablesHeader.NumberOfRows; // set up a table of coded index information // the first figure in the array is the number of bits needed to encode // which table the index is pointing to. Note, some indexes use more bits // than are necessary, for example CustomAttributeType uses 3 bits even though // it only points to 2 tables, so in theory could be encoded in 1 bit. this.CodedIndexInformation = new object[12]; CodedIndexInformation[(int)Tables.CodedIndexType.TypeDefOrRef] = new int[] { 2, (int)Tables.TableName.TypeDef, (int)Tables.TableName.TypeRef, (int)Tables.TableName.TypeSpec }; CodedIndexInformation[(int)Tables.CodedIndexType.HasConstant] = new int[] { 2, (int)Tables.TableName.Field, (int)Tables.TableName.Param, (int)Tables.TableName.Property }; CodedIndexInformation[(int)Tables.CodedIndexType.HasCustomAttribute] = new int[] { 5, (int)Tables.TableName.MethodDef, (int)Tables.TableName.Field, (int)Tables.TableName.TypeRef, (int)Tables.TableName.TypeDef, (int)Tables.TableName.Param, (int)Tables.TableName.InterfaceImpl, (int)Tables.TableName.MemberRef, (int)Tables.TableName.Module, (int)Tables.TableName.DeclSecurity, (int)Tables.TableName.Property, (int)Tables.TableName.EventX, (int)Tables.TableName.StandAloneSig, (int)Tables.TableName.ModuleRef, (int)Tables.TableName.TypeSpec, (int)Tables.TableName.Assembly, (int)Tables.TableName.AssemblyRef, (int)Tables.TableName.File, (int)Tables.TableName.ExportedType, (int)Tables.TableName.ManifestResource }; CodedIndexInformation[(int)Tables.CodedIndexType.HasFieldMarshal] = new int[] { 1, (int)Tables.TableName.Field, (int)Tables.TableName.Param }; CodedIndexInformation[(int)Tables.CodedIndexType.HasDeclSecurity] = new int[] { 2, (int)Tables.TableName.TypeDef, (int)Tables.TableName.MethodDef, (int)Tables.TableName.Assembly }; CodedIndexInformation[(int)Tables.CodedIndexType.MemberRefParent] = new int[] { 3, (int)Tables.TableName.TypeRef, (int)Tables.TableName.ModuleRef, (int)Tables.TableName.MethodDef, (int)Tables.TableName.TypeSpec }; CodedIndexInformation[(int)Tables.CodedIndexType.HasSemantics] = new int[] { 1, (int)Tables.TableName.EventX, (int)Tables.TableName.Property }; CodedIndexInformation[(int)Tables.CodedIndexType.MethodDefOrRef] = new int[] { 1, (int)Tables.TableName.MethodDef, (int)Tables.TableName.MemberRef }; CodedIndexInformation[(int)Tables.CodedIndexType.MemberForwarded] = new int[] { 1, (int)Tables.TableName.Field, (int)Tables.TableName.MethodDef }; CodedIndexInformation[(int)Tables.CodedIndexType.Implementation] = new int[] { 2, (int)Tables.TableName.File, (int)Tables.TableName.AssemblyRef, (int)Tables.TableName.ExportedType }; CodedIndexInformation[(int)Tables.CodedIndexType.CustomAttributeType] = new int[] { 3, (int)Tables.TableName.MethodDef, (int)Tables.TableName.MemberRef }; CodedIndexInformation[(int)Tables.CodedIndexType.ResolutionScope] = new int[] { 2, (int)Tables.TableName.Module, (int)Tables.TableName.ModuleRef, (int)Tables.TableName.AssemblyRef, (int)Tables.TableName.TypeRef }; this.Module = new Module(Tables.TableName.Module, this); this.TypeRef = new TypeRef(Tables.TableName.TypeRef, this); this.TypeDef = new TypeDef(Tables.TableName.TypeDef, this); this.Field = new Field(Tables.TableName.Field, this); this.MethodDef = new MethodDef(Tables.TableName.MethodDef, this); this.Param = new Param(Tables.TableName.Param, this); this.InterfaceImpl = new InterfaceImpl(Tables.TableName.InterfaceImpl, this); this.MemberRef = new MemberRef(Tables.TableName.MemberRef, this); this.Constant = new Constant(Tables.TableName.Constant, this); this.CustomAttribute = new CustomAttribute(Tables.TableName.CustomAttribute, this); this.FieldMarshal = new FieldMarshal(Tables.TableName.FieldMarshal, this); this.DeclSecurity = new DeclSecurity(Tables.TableName.DeclSecurity, this); this.ClassLayout = new ClassLayout(Tables.TableName.ClassLayout, this); this.FieldLayout = new FieldLayout(Tables.TableName.FieldLayout, this); this.StandAloneSig = new StandAloneSig(Tables.TableName.StandAloneSig, this); this.EventMap = new EventMap(Tables.TableName.EventMap, this); this.EventX = new EventX(Tables.TableName.EventX, this); this.PropertyMap = new PropertyMap(Tables.TableName.PropertyMap, this); this.Property = new Property(Tables.TableName.Property, this); this.MethodSemantics = new MethodSemantics(Tables.TableName.MethodSemantics, this); this.MethodImpl = new MethodImpl(Tables.TableName.MethodImpl, this); this.ModuleRef = new ModuleRef(Tables.TableName.ModuleRef, this); this.TypeSpec = new TypeSpec(Tables.TableName.TypeSpec, this); this.ImplMap = new ImplMap(Tables.TableName.ImplMap, this); }