PEFileCheck.cs 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Runtime.CompilerServices;
  4. using System.Runtime.InteropServices;
  5. using System.Text;
  6. namespace NativeLibraryLoader.Windows
  7. {
  8. internal class PEFileCheck : IFileCheck
  9. {
  10. unsafe MachineType IFileCheck.CheckFile(string path)
  11. {
  12. MachineType machineType = MachineType.NoSupport;
  13. byte[] bytes = System.IO.File.ReadAllBytes(path);
  14. ImageDosHeader imageDosHeader;
  15. fixed (void* p = &bytes[0])
  16. {
  17. imageDosHeader = Marshal.PtrToStructure<ImageDosHeader>((IntPtr)p);
  18. }
  19. fixed (void* p = &bytes[(imageDosHeader.Lfanew >> 16) | (imageDosHeader.Lfanew << 16)])
  20. {
  21. ImageNTHeaders imageNTHeaders = Marshal.PtrToStructure<ImageNTHeaders>((IntPtr)(p));
  22. }
  23. fixed (void* p = &bytes[((imageDosHeader.Lfanew >> 16) | (imageDosHeader.Lfanew << 16)) + Marshal.SizeOf<ImageNTHeaders>()])
  24. {
  25. switch (Unsafe.Read<MagicType>(p))
  26. {
  27. case MagicType.IMAGE_NT_OPTIONAL_HDR32_MAGIC:
  28. machineType = MachineType.Bit32;
  29. break;
  30. case MagicType.IMAGE_NT_OPTIONAL_HDR64_MAGIC:
  31. machineType = MachineType.Bit64;
  32. break;
  33. }
  34. }
  35. return machineType;
  36. }
  37. enum PeMachineType : ushort
  38. {
  39. /// <summary>
  40. /// The content of this field is assumed to be applicable to any machine type
  41. /// </summary>
  42. Unknown = 0x0000,
  43. /// <summary>
  44. /// Intel 386 or later processors and compatible processors
  45. /// </summary>
  46. I386 = 0x014c,
  47. R3000 = 0x0162,
  48. /// <summary>
  49. /// MIPS little endian
  50. /// </summary>
  51. R4000 = 0x0166,
  52. R10000 = 0x0168,
  53. /// <summary>
  54. /// MIPS little-endian WCE v2
  55. /// </summary>
  56. WCEMIPSV2 = 0x0169,
  57. /// <summary>
  58. /// Alpha AXP
  59. /// </summary>
  60. Alpha = 0x0184,
  61. /// <summary>
  62. /// Hitachi SH3
  63. /// </summary>
  64. SH3 = 0x01a2,
  65. /// <summary>
  66. /// Hitachi SH3 DSP
  67. /// </summary>
  68. SH3DSP = 0x01a3,
  69. /// <summary>
  70. /// Hitachi SH4
  71. /// </summary>
  72. SH4 = 0x01a6,
  73. /// <summary>
  74. /// Hitachi SH5
  75. /// </summary>
  76. SH5 = 0x01a8,
  77. /// <summary>
  78. /// ARM little endian
  79. /// </summary>
  80. ARM = 0x01c0,
  81. /// <summary>
  82. /// Thumb
  83. /// </summary>
  84. Thumb = 0x01c2,
  85. /// <summary>
  86. /// ARM Thumb-2 little endian
  87. /// </summary>
  88. ARMNT = 0x01c4,
  89. /// <summary>
  90. /// Matsushita AM33
  91. /// </summary>
  92. AM33 = 0x01d3,
  93. /// <summary>
  94. /// Power PC little endian
  95. /// </summary>
  96. PowerPC = 0x01f0,
  97. /// <summary>
  98. /// Power PC with floating point support
  99. /// </summary>
  100. PowerPCFP = 0x01f1,
  101. /// <summary>
  102. /// Intel Itanium processor family
  103. /// </summary>
  104. IA64 = 0x0200,
  105. /// <summary>
  106. /// MIPS16
  107. /// </summary>
  108. MIPS16 = 0x0266,
  109. /// <summary>
  110. /// Motorola 68000 series
  111. /// </summary>
  112. M68K = 0x0268,
  113. /// <summary>
  114. /// Alpha AXP 64-bit
  115. /// </summary>
  116. Alpha64 = 0x0284,
  117. /// <summary>
  118. /// MIPS with FPU
  119. /// </summary>
  120. MIPSFPU = 0x0366,
  121. /// <summary>
  122. /// MIPS16 with FPU
  123. /// </summary>
  124. MIPSFPU16 = 0x0466,
  125. /// <summary>
  126. /// EFI byte code
  127. /// </summary>
  128. EBC = 0x0ebc,
  129. /// <summary>
  130. /// RISC-V 32-bit address space
  131. /// </summary>
  132. RISCV32 = 0x5032,
  133. /// <summary>
  134. /// RISC-V 64-bit address space
  135. /// </summary>
  136. RISCV64 = 0x5064,
  137. /// <summary>
  138. /// RISC-V 128-bit address space
  139. /// </summary>
  140. RISCV128 = 0x5128,
  141. /// <summary>
  142. /// x64
  143. /// </summary>
  144. AMD64 = 0x8664,
  145. /// <summary>
  146. /// ARM64 little endian
  147. /// </summary>
  148. ARM64 = 0xaa64,
  149. /// <summary>
  150. /// LoongArch 32-bit processor family
  151. /// </summary>
  152. LoongArch32 = 0x6232,
  153. /// <summary>
  154. /// LoongArch 64-bit processor family
  155. /// </summary>
  156. LoongArch64 = 0x6264,
  157. /// <summary>
  158. /// Mitsubishi M32R little endian
  159. /// </summary>
  160. M32R = 0x9041
  161. }
  162. enum CHARACTERISTICS : UInt16
  163. {
  164. RELOCS_STRIPPED = 0x1,
  165. EXECUTABLE_IMAGE = 0x2,
  166. LINE_NUMS_STRIPPED = 0x4,
  167. LOCAL_SYMS_STRIPPED = 0x8,
  168. AGGRESIVE_WS_TRIM = 0x10,
  169. LARGE_ADDRESS_AWARE = 0x20,
  170. BYTES_REVERSED_LO = 0x80,
  171. BIT32_MACHINE = 0x100,
  172. DEBUG_STRIPPED = 0x200,
  173. REMOVABLE_RUN_FROM_SWAP = 0x400,
  174. NET_RUN_FROM_SWAP = 0x800,
  175. SYSTEM = 0x1000,
  176. DLL = 0x2000,
  177. UP_SYSTEM_ONLY = 0x4000,
  178. BYTES_REVERSED_HI = 0x8000
  179. }
  180. enum MagicType : ushort
  181. {
  182. IMAGE_NT_OPTIONAL_HDR32_MAGIC = 0x10b,
  183. IMAGE_NT_OPTIONAL_HDR64_MAGIC = 0x20b
  184. }
  185. enum SubSystemType : ushort
  186. {
  187. IMAGE_SUBSYSTEM_UNKNOWN = 0,
  188. IMAGE_SUBSYSTEM_NATIVE = 1,
  189. IMAGE_SUBSYSTEM_WINDOWS_GUI = 2,
  190. IMAGE_SUBSYSTEM_WINDOWS_CUI = 3,
  191. IMAGE_SUBSYSTEM_POSIX_CUI = 7,
  192. IMAGE_SUBSYSTEM_WINDOWS_CE_GUI = 9,
  193. IMAGE_SUBSYSTEM_EFI_APPLICATION = 10,
  194. IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER = 11,
  195. IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER = 12,
  196. IMAGE_SUBSYSTEM_EFI_ROM = 13,
  197. IMAGE_SUBSYSTEM_XBOX = 14
  198. }
  199. enum DllCharacteristicsType : ushort
  200. {
  201. RES_0 = 0x0001,
  202. RES_1 = 0x0002,
  203. RES_2 = 0x0004,
  204. RES_3 = 0x0008,
  205. IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE = 0x0040,
  206. IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY = 0x0080,
  207. IMAGE_DLL_CHARACTERISTICS_NX_COMPAT = 0x0100,
  208. IMAGE_DLLCHARACTERISTICS_NO_ISOLATION = 0x0200,
  209. IMAGE_DLLCHARACTERISTICS_NO_SEH = 0x0400,
  210. IMAGE_DLLCHARACTERISTICS_NO_BIND = 0x0800,
  211. RES_4 = 0x1000,
  212. IMAGE_DLLCHARACTERISTICS_WDM_DRIVER = 0x2000,
  213. IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE = 0x8000
  214. }
  215. [StructLayout(LayoutKind.Sequential, Pack = 1, Size = 64)]
  216. struct ImageDosHeader
  217. {
  218. public UInt16 Magic;
  219. public UInt16 Cblp;
  220. public UInt16 Cp;
  221. public UInt16 Crlc;
  222. public UInt16 Minalloc;
  223. public UInt16 Maxalloc;
  224. public UInt16 SS;
  225. public UInt16 SP;
  226. public UInt16 CSum;
  227. public UInt16 IP;
  228. public UInt16 CS;
  229. public UInt16 Lfarlc;
  230. public UInt16 Ovno;
  231. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
  232. public UInt16[] Res;
  233. public UInt16 OemId;
  234. public UInt16 OemInfo;
  235. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
  236. public UInt16[] Res2;
  237. public UInt32 Lfanew;
  238. }
  239. [StructLayout(LayoutKind.Sequential, Pack = 1)]
  240. struct ImageNTHeaders
  241. {
  242. public UInt32 Signature;
  243. public ImageFileHeader ImageFileHeader;
  244. }
  245. [StructLayout(LayoutKind.Sequential, Pack = 1)]
  246. struct ImageFileHeader
  247. {
  248. public PeMachineType Machine;
  249. public UInt16 NumberOfSections;
  250. public UInt32 TimeDateStamp;
  251. public UInt32 PointerToSymbolTable;
  252. public UInt32 NumberOfSymbols;
  253. public UInt16 SizeOfOptionalHeader;
  254. public CHARACTERISTICS Characteristics;
  255. }
  256. }
  257. }