I am working on porting a 32-bit web application to 64-bit, and I have some problems with our plugin loader code.
In the 32-bit version, we scan the bin webapps directory for all .net DLLs and then load them using Assembly.Load to check for our plugin attributes.
We did this pretty well using the public domain code:
/// <summary> /// Returns true if the file specified is a real CLR type, /// otherwise false is returned. /// False is also returned in the case of an exception being caught /// </summary> /// <param name="file">A string representing the file to check for /// CLR validity</param> /// <returns>True if the file specified is a real CLR type, /// otherwise false is returned. /// False is also returned in the case of an exception being /// caught</returns> public static bool IsDotNetAssembly(String file) { Stream fs = new FileStream(@file, FileMode.Open, FileAccess.Read); try { BinaryReader reader = new BinaryReader(fs); //PE Header starts @ 0x3C (60). Its a 4 byte header. fs.Position = 0x3C; uint peHeader = reader.ReadUInt32(); //Moving to PE Header start location... fs.Position = peHeader; uint peHeaderSignature = reader.ReadUInt32(); ushort machine = reader.ReadUInt16(); ushort sections = reader.ReadUInt16(); uint timestamp = reader.ReadUInt32(); uint pSymbolTable = reader.ReadUInt32(); uint noOfSymbol = reader.ReadUInt32(); ushort optionalHeaderSize = reader.ReadUInt16(); ushort characteristics = reader.ReadUInt16(); // PE Optional Headers // To go directly to the datadictionary, we'll increase the stream current position to with 96 (0x60). // 28 bytes for Standard fields // 68 bytes for NT-specific fields // 128 bytes DataDictionary // DataDictionay has 16 directories // 8 bytes per directory (4 bytes RVA and 4 bytes of Size.) // 15th directory consist of CLR header! (if its 0, it is not a CLR file ) uint[] dataDictionaryRVA = new uint[16]; uint[] dataDictionarySize = new uint[16]; ushort dataDictionaryStart = Convert.ToUInt16(Convert.ToUInt16(fs.Position) + 0x60); fs.Position = dataDictionaryStart; for (int i = 0; i < 15; i++) { dataDictionaryRVA[i] = reader.ReadUInt32(); dataDictionarySize[i] = reader.ReadUInt32(); } if (dataDictionaryRVA[14] == 0) { fs.Close(); return false; } else { fs.Close(); return true; } } catch (Exception) { return false; } finally { fs.Close(); } }
Now the problem is that now we have to process 64-bit or platform independent DLLs, and the offset seems to have changed, and this code does not work. Does anyone know the correct changes to the above code to return true for a valid 64-bit OR platform independent DLL?
source share