internal PEReader(string FileName, TraceLogger TLogger) { this.sectionHeaders = (IList <PEReader.IMAGE_SECTION_HEADER>) new List <PEReader.IMAGE_SECTION_HEADER>(); this.IsAssembly = false; this.OS32BitCompatible = false; this.TL = TLogger; this.TL.LogMessage("PEReader", "Running within CLR version: " + RuntimeEnvironment.GetSystemVersion()); if (Operators.CompareString(Strings.Left(FileName, 5).ToUpper(), "FILE:", false) == 0) { Uri uri = new Uri(FileName); FileName = uri.LocalPath + Uri.UnescapeDataString(uri.Fragment).Replace("/", "\\\\"); } this.TL.LogMessage("PEReader", "Filename to check: " + FileName); if (!File.Exists(FileName)) { throw new FileNotFoundException("PEReader - File not found: " + FileName); } this.TL.LogMessage("PEReader", "Determining whether this is an assembly"); try { this.SuppliedAssembly = Assembly.ReflectionOnlyLoadFrom(FileName); this.IsAssembly = true; this.TL.LogMessage("PEReader.IsAssembly", "Found an assembly because it loaded Ok to the reflection context: " + Conversions.ToString(this.IsAssembly)); } catch (FileNotFoundException ex) { //ProjectData.SetProjectError((Exception) ex); this.TL.LogMessage("PEReader.IsAssembly", "FileNotFoundException: File not found so this is NOT an assembly: " + Conversions.ToString(this.IsAssembly)); //ProjectData.ClearProjectError(); } catch (BadImageFormatException ex) { //ProjectData.SetProjectError((Exception) ex); int hrForException = Marshal.GetHRForException((Exception)ex); switch (hrForException) { case -2147024885: this.TL.LogMessage("PEReader.IsAssembly", "BadImageFormatException. hResult: " + hrForException.ToString("X8") + " - COR_E_BADIMAGEFORMAT. Setting IsAssembly to: " + Conversions.ToString(this.IsAssembly)); break; case -2146234105: this.TL.LogMessage("PEReader.IsAssembly", "BadImageFormatException. hResult: " + hrForException.ToString("X8") + " - CLDB_E_FILE_OLDVER. Setting IsAssembly to: " + Conversions.ToString(this.IsAssembly)); break; case -2146234076: this.TL.LogMessage("PEReader.IsAssembly", "BadImageFormatException. hResult: " + hrForException.ToString("X8") + " - CLDB_E_INDEX_NOTFOUND. Setting IsAssembly to: " + Conversions.ToString(this.IsAssembly)); break; case -2146234098: this.TL.LogMessage("PEReader.IsAssembly", "BadImageFormatException. hResult: " + hrForException.ToString("X8") + " - CLDB_E_FILE_CORRUPT. Setting IsAssembly to: " + Conversions.ToString(this.IsAssembly)); break; case -2146234341: this.IsAssembly = true; this.TL.LogMessage("PEReader.IsAssembly", "BadImageFormatException. hResult: " + hrForException.ToString("X8") + " - COR_E_NEWER_RUNTIME. Setting IsAssembly to: " + Conversions.ToString(this.IsAssembly)); break; case -2146234344: this.TL.LogMessage("PEReader.IsAssembly", "BadImageFormatException. hResult: " + hrForException.ToString("X8") + " - COR_E_ASSEMBLYEXPECTED. Setting IsAssembly to: " + Conversions.ToString(this.IsAssembly)); break; case -2147024703: this.TL.LogMessage("PEReader.IsAssembly", "BadImageFormatException. hResult: " + hrForException.ToString("X8") + " - ERROR_BAD_EXE_FORMAT. Setting IsAssembly to: " + Conversions.ToString(this.IsAssembly)); break; case -2147024704: this.TL.LogMessage("PEReader.IsAssembly", "BadImageFormatException. hResult: " + hrForException.ToString("X8") + " - ERROR_EXE_MARKED_INVALID. Setting IsAssembly to: " + Conversions.ToString(this.IsAssembly)); break; case -2146233315: this.TL.LogMessage("PEReader.IsAssembly", "BadImageFormatException. hResult: " + hrForException.ToString("X8") + " - CORSEC_E_INVALID_IMAGE_FORMAT. Setting IsAssembly to: " + Conversions.ToString(this.IsAssembly)); break; case -2147023898: this.TL.LogMessage("PEReader.IsAssembly", "BadImageFormatException. hResult: " + hrForException.ToString("X8") + " - ERROR_NOACCESS. Setting IsAssembly to: " + Conversions.ToString(this.IsAssembly)); break; case -2147024714: this.TL.LogMessage("PEReader.IsAssembly", "BadImageFormatException. hResult: " + hrForException.ToString("X8") + " - ERROR_INVALID_ORDINAL. Setting IsAssembly to: " + Conversions.ToString(this.IsAssembly)); break; case -2147023742: this.TL.LogMessage("PEReader.IsAssembly", "BadImageFormatException. hResult: " + hrForException.ToString("X8") + " - ERROR_INVALID_DLL. Setting IsAssembly to: " + Conversions.ToString(this.IsAssembly)); break; case -2147023504: this.TL.LogMessage("PEReader.IsAssembly", "BadImageFormatException. hResult: " + hrForException.ToString("X8") + " - ERROR_FILE_CORRUPT. Setting IsAssembly to: " + Conversions.ToString(this.IsAssembly)); break; case -2146234280: this.TL.LogMessage("PEReader.IsAssembly", "BadImageFormatException. hResult: " + hrForException.ToString("X8") + " - COR_E_LOADING_REFERENCE_ASSEMBLY. Setting IsAssembly to: " + Conversions.ToString(this.IsAssembly)); break; case -2146233966: this.TL.LogMessage("PEReader.IsAssembly", "BadImageFormatException. hResult: " + hrForException.ToString("X8") + " - META_E_BAD_SIGNATURE. Setting IsAssembly to: " + Conversions.ToString(this.IsAssembly)); break; default: this.TL.LogMessage("PEReader.IsAssembly", "BadImageFormatException. hResult: " + hrForException.ToString("X8") + " - Meaning of error code is unknown. Setting IsAssembly to: " + Conversions.ToString(this.IsAssembly)); break; } //ProjectData.ClearProjectError(); } catch (FileLoadException ex) { //ProjectData.SetProjectError((Exception) ex); this.IsAssembly = true; this.TL.LogMessage("PEReader.IsAssembly", "FileLoadException: Assembly already loaded so this is an assembly: " + Conversions.ToString(this.IsAssembly)); //ProjectData.ClearProjectError(); } this.TL.LogMessage("PEReader", "Determining PE Machine type"); this.stream = (Stream) new FileStream(FileName, FileMode.Open, FileAccess.Read); this.reader = new BinaryReader(this.stream); this.reader.BaseStream.Seek(0L, SeekOrigin.Begin); this.dosHeader = PEReader.MarshalBytesTo <PEReader.IMAGE_DOS_HEADER>(this.reader); if ((int)this.dosHeader.e_magic != 23117) { throw new ASCOM.InvalidOperationException("File is not a portable executable."); } this.reader.BaseStream.Seek((long)this.dosHeader.e_lfanew, SeekOrigin.Begin); this.ntHeaders.Signature = PEReader.MarshalBytesTo <uint>(this.reader); if ((long)this.ntHeaders.Signature != 17744L) { throw new ASCOM.InvalidOperationException("Invalid portable executable signature in NT header."); } this.ntHeaders.FileHeader = PEReader.MarshalBytesTo <PEReader.IMAGE_FILE_HEADER>(this.reader); switch (this.ntHeaders.FileHeader.Machine) { case 332: this.OS32BitCompatible = true; this.TL.LogMessage("PEReader.MachineType", "Machine - found \"Intel 32bit\" executable. Characteristics: " + this.ntHeaders.FileHeader.Characteristics.ToString("X8") + ", OS32BitCompatible: " + Conversions.ToString(this.OS32BitCompatible)); break; case 512: this.OS32BitCompatible = false; this.TL.LogMessage("PEReader.MachineType", "Machine - found \"Itanium 64bit\" executable. Characteristics: " + this.ntHeaders.FileHeader.Characteristics.ToString("X8") + ", OS32BitCompatible: " + Conversions.ToString(this.OS32BitCompatible)); break; case 34404: this.OS32BitCompatible = false; this.TL.LogMessage("PEReader.MachineType", "Machine - found \"Intel 64bit\" executable. Characteristics: " + this.ntHeaders.FileHeader.Characteristics.ToString("X8") + ", OS32BitCompatible: " + Conversions.ToString(this.OS32BitCompatible)); break; default: this.TL.LogMessage("PEReader.MachineType", "Found Unknown machine type: " + this.ntHeaders.FileHeader.Machine.ToString("X8") + ". Characteristics: " + this.ntHeaders.FileHeader.Characteristics.ToString("X8") + ", OS32BitCompatible: " + Conversions.ToString(this.OS32BitCompatible)); break; } if (this.OS32BitCompatible) { this.TL.LogMessage("PEReader.MachineType", "Reading optional 32bit header"); this.ntHeaders.OptionalHeader32 = PEReader.MarshalBytesTo <PEReader.IMAGE_OPTIONAL_HEADER32>(this.reader); } else { this.TL.LogMessage("PEReader.MachineType", "Reading optional 64bit header"); this.ntHeaders.OptionalHeader64 = PEReader.MarshalBytesTo <PEReader.IMAGE_OPTIONAL_HEADER64>(this.reader); } if (this.IsAssembly) { this.TL.LogMessage("PEReader", "This is an assembly, determining Bitness through the CLR header"); int num1 = 1000; if (this.OS32BitCompatible) { this.TL.LogMessage("PEReader.Bitness", "This is a 32 bit assembly, reading the CLR Header"); if ((long)this.ntHeaders.OptionalHeader32.NumberOfRvaAndSizes < 1000L) { num1 = checked ((int)this.ntHeaders.OptionalHeader32.NumberOfRvaAndSizes); } this.TL.LogMessage("PEReader.Bitness", "Checking " + Conversions.ToString(num1) + " headers"); int num2 = 0; int num3 = checked (num1 - 1); int index = num2; while (index <= num3) { if ((long)this.ntHeaders.OptionalHeader32.DataDirectory[index].Size > 0L) { this.sectionHeaders.Add(PEReader.MarshalBytesTo <PEReader.IMAGE_SECTION_HEADER>(this.reader)); } checked { ++index; } } IEnumerator <PEReader.IMAGE_SECTION_HEADER> enumerator = null; try { enumerator = this.sectionHeaders.GetEnumerator(); while (enumerator.MoveNext()) { PEReader.IMAGE_SECTION_HEADER current = enumerator.Current; if (Operators.CompareString(current.Name, ".text", false) == 0) { this.TextBase = current.PointerToRawData; } } } finally { if (enumerator != null) { enumerator.Dispose(); } } if (num1 >= 15 && (long)this.ntHeaders.OptionalHeader32.DataDirectory[14].VirtualAddress > 0L) { this.reader.BaseStream.Seek((long)checked (this.ntHeaders.OptionalHeader32.DataDirectory[14].VirtualAddress - this.ntHeaders.OptionalHeader32.BaseOfCode + this.TextBase), SeekOrigin.Begin); this.CLR = PEReader.MarshalBytesTo <PEReader.IMAGE_COR20_HEADER>(this.reader); } } else { this.TL.LogMessage("PEReader.Bitness", "This is a 64 bit assembly, reading the CLR Header"); if ((long)this.ntHeaders.OptionalHeader64.NumberOfRvaAndSizes < 1000L) { num1 = checked ((int)this.ntHeaders.OptionalHeader64.NumberOfRvaAndSizes); } this.TL.LogMessage("PEReader.Bitness", "Checking " + Conversions.ToString(num1) + " headers"); int num2 = 0; int num3 = checked (num1 - 1); int index = num2; while (index <= num3) { if ((long)this.ntHeaders.OptionalHeader64.DataDirectory[index].Size > 0L) { this.sectionHeaders.Add(PEReader.MarshalBytesTo <PEReader.IMAGE_SECTION_HEADER>(this.reader)); } checked { ++index; } } IEnumerator <PEReader.IMAGE_SECTION_HEADER> enumerator = null; try { enumerator = this.sectionHeaders.GetEnumerator(); while (enumerator.MoveNext()) { PEReader.IMAGE_SECTION_HEADER current = enumerator.Current; if (Operators.CompareString(current.Name, ".text", false) == 0) { this.TL.LogMessage("PEReader.Bitness", "Found TEXT section"); this.TextBase = current.PointerToRawData; } } } finally { if (enumerator != null) { enumerator.Dispose(); } } if (num1 >= 15 && (long)this.ntHeaders.OptionalHeader64.DataDirectory[14].VirtualAddress > 0L) { this.reader.BaseStream.Seek((long)checked (this.ntHeaders.OptionalHeader64.DataDirectory[14].VirtualAddress - this.ntHeaders.OptionalHeader64.BaseOfCode + this.TextBase), SeekOrigin.Begin); this.CLR = PEReader.MarshalBytesTo <PEReader.IMAGE_COR20_HEADER>(this.reader); this.TL.LogMessage("PEReader.Bitness", "Read CLR header successfully"); } } if (this.OS32BitCompatible) { if (((long)this.CLR.Flags & 2L) > 0L) { this.TL.LogMessage("PEReader.Bitness", "Found \"32bit Required\" assembly"); this.ExecutableBitness = VersionCode.Bitness.Bits32; } else { this.TL.LogMessage("PEReader.Bitness", "Found \"MSIL\" assembly"); this.ExecutableBitness = VersionCode.Bitness.BitsMSIL; } } else { this.TL.LogMessage("PEReader.Bitness", "Found \"64bit Required\" assembly"); this.ExecutableBitness = VersionCode.Bitness.Bits64; } this.TL.LogMessage("PEReader", "Assembly required Runtime version: " + Conversions.ToString((uint)this.CLR.MajorRuntimeVersion) + "." + Conversions.ToString((uint)this.CLR.MinorRuntimeVersion)); } else { this.TL.LogMessage("PEReader", "This is not an assembly, determining Bitness through the executable bitness flag"); if (this.OS32BitCompatible) { this.TL.LogMessage("PEReader.Bitness", "Found 32bit executable"); this.ExecutableBitness = VersionCode.Bitness.Bits32; } else { this.TL.LogMessage("PEReader.Bitness", "Found 64bit executable"); this.ExecutableBitness = VersionCode.Bitness.Bits64; } } }