CoffUtility.cs 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. using System;
  2. using System.Diagnostics;
  3. using System.Drawing;
  4. using System.IO;
  5. using System.Reflection;
  6. using Aio1Ef.Packer.Common.ExternalCodes;
  7. namespace Aio1Ef.Packer.Common
  8. {
  9. internal static class CoffUtility
  10. {
  11. /// <summary>
  12. /// Parses the PE header and determines whether the given assembly is a console application.
  13. /// </summary>
  14. /// <param name="assemblyPath">The path of the assembly to check.</param>
  15. /// <returns>True if the given assembly is a console application; false otherwise.</returns>
  16. /// <remarks>The magic numbers in this method are extracted from the PE/COFF file
  17. /// format specification available from http://www.microsoft.com/whdc/system/platform/firmware/pecoff.mspx
  18. /// </remarks>
  19. public static bool AssemblyUsesConsoleSubsystem(string assemblyPath)
  20. {
  21. using (var s = new FileStream(assemblyPath, FileMode.Open, FileAccess.Read))
  22. {
  23. var rawPeSignatureOffset = new byte[4];
  24. s.Seek(0x3c, SeekOrigin.Begin);
  25. s.Read(rawPeSignatureOffset, 0, 4);
  26. int peSignatureOffset = rawPeSignatureOffset[0];
  27. peSignatureOffset |= rawPeSignatureOffset[1] << 8;
  28. peSignatureOffset |= rawPeSignatureOffset[2] << 16;
  29. peSignatureOffset |= rawPeSignatureOffset[3] << 24;
  30. var coffHeader = new byte[24];
  31. s.Seek(peSignatureOffset, SeekOrigin.Begin);
  32. s.Read(coffHeader, 0, 24);
  33. byte[] signature = { (byte)'P', (byte)'E', (byte)'\0', (byte)'\0' };
  34. for (var index = 0; index < 4; index++)
  35. {
  36. Debug.Assert(coffHeader[index] == signature[index],
  37. "Attempted to check a non PE file for the console subsystem!");
  38. }
  39. var subsystemBytes = new byte[2];
  40. s.Seek(68, SeekOrigin.Current);
  41. s.Read(subsystemBytes, 0, 2);
  42. var subSystem = subsystemBytes[0] | subsystemBytes[1] << 8;
  43. return subSystem == 3; /*IMAGE_SUBSYSTEM_WINDOWS_CUI*/
  44. }
  45. }
  46. public static string GetTargetPlatform(Assembly assembly)
  47. {
  48. PortableExecutableKinds pek;
  49. ImageFileMachine ifm;
  50. assembly.ManifestModule.GetPEKind(out pek, out ifm);
  51. if (pek == (PortableExecutableKinds.ILOnly | PortableExecutableKinds.Required32Bit) && ifm == ImageFileMachine.I386)
  52. return "x86";
  53. if (pek == (PortableExecutableKinds.ILOnly | PortableExecutableKinds.PE32Plus) && ifm == ImageFileMachine.AMD64)
  54. return "x64";
  55. if (pek == (PortableExecutableKinds.ILOnly) && ifm == ImageFileMachine.I386)
  56. return "anycpu";
  57. if (pek == (PortableExecutableKinds.ILOnly | PortableExecutableKinds.Preferred32Bit) && ifm == ImageFileMachine.I386)
  58. return "anycpu";
  59. throw new ArgumentException($"Not support {pek} & {ifm}");
  60. }
  61. public static Icon GetIconFromFile(string path)
  62. {
  63. try
  64. {
  65. return new IconExtractor(path).GetIcon(0);
  66. }
  67. catch
  68. {
  69. return null;
  70. }
  71. }
  72. }
  73. }