PEFileCheck.cs 9.3 KB

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