FileImage.cs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. /*
  2. * PERWAPI - An API for Reading and Writing PE Files
  3. *
  4. * Copyright (c) Diane Corney, Queensland University of Technology, 2004.
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the PERWAPI Copyright as included with this
  8. * distribution in the file PERWAPIcopyright.rtf.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY as is explained in the copyright notice.
  12. *
  13. * The author may be contacted at d.corney@qut.edu.au
  14. *
  15. * Version Date: 26/01/07
  16. */
  17. using System;
  18. using System.IO;
  19. namespace QUT.PERWAPI
  20. {
  21. /**************************************************************************/
  22. // Class of PEFile constant values
  23. /**************************************************************************/
  24. /// <summary>
  25. /// Image for a PEFile
  26. /// File Structure
  27. /// DOS Header (128 bytes)
  28. /// PE Signature ("PE\0\0")
  29. /// PEFileHeader (20 bytes)
  30. /// PEOptionalHeader (224 bytes)
  31. /// SectionHeaders (40 bytes * NumSections)
  32. ///
  33. /// Sections .text (always present - contains metadata)
  34. /// .sdata (contains any initialised data in the file - may not be present)
  35. /// (for ilams /debug this contains the Debug table)
  36. /// .reloc (always present - in pure CIL only has one fixup)
  37. /// others??? c# produces .rsrc section containing a Resource Table
  38. ///
  39. /// .text layout
  40. /// IAT (single entry 8 bytes for pure CIL)
  41. /// CLIHeader (72 bytes)
  42. /// CIL instructions for all methods (variable size)
  43. /// MetaData
  44. /// Root (20 bytes + UTF-8 Version String + quad align padding)
  45. /// StreamHeaders (8 bytes + null terminated name string + quad align padding)
  46. /// Streams
  47. /// #~ (always present - holds metadata tables)
  48. /// #Strings (always present - holds identifier strings)
  49. /// #US (Userstring heap)
  50. /// #Blob (signature blobs)
  51. /// #GUID (guids for assemblies or Modules)
  52. /// ImportTable (40 bytes)
  53. /// ImportLookupTable(8 bytes) (same as IAT for standard CIL files)
  54. /// Hint/Name Tables with entry "_CorExeMain" for .exe file and "_CorDllMain" for .dll (14 bytes)
  55. /// ASCII string "mscoree.dll" referenced in ImportTable (+ padding = 16 bytes)
  56. /// Entry Point (0xFF25 followed by 4 bytes 0x400000 + RVA of .text)
  57. ///
  58. /// #~ stream structure
  59. /// Header (24 bytes)
  60. /// Rows (4 bytes * numTables)
  61. /// Tables
  62. /// </summary>
  63. internal class FileImage
  64. {
  65. internal readonly static uint DelaySignSize = 128; // Current assemblies are always 128
  66. internal readonly static uint[] iByteMask = { 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 };
  67. internal readonly static ulong[] lByteMask = {0x00000000000000FF, 0x000000000000FF00,
  68. 0x0000000000FF0000, 0x00000000FF000000,
  69. 0x000000FF00000000, 0x0000FF0000000000,
  70. 0x00FF000000000000, 0xFF00000000000000 };
  71. internal readonly static uint nibble0Mask = 0x0000000F;
  72. internal readonly static uint nibble1Mask = 0x000000F0;
  73. internal static readonly byte[] DOSHeader = { 0x4d,0x5a,0x90,0x00,0x03,0x00,0x00,0x00,
  74. 0x04,0x00,0x00,0x00,0xff,0xff,0x00,0x00,
  75. 0xb8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  76. 0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  77. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  78. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  79. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  80. 0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,
  81. 0x0e,0x1f,0xba,0x0e,0x00,0xb4,0x09,0xcd,
  82. 0x21,0xb8,0x01,0x4c,0xcd,0x21,0x54,0x68,
  83. 0x69,0x73,0x20,0x70,0x72,0x6f,0x67,0x72,
  84. 0x61,0x6d,0x20,0x63,0x61,0x6e,0x6e,0x6f,
  85. 0x74,0x20,0x62,0x65,0x20,0x72,0x75,0x6e,
  86. 0x20,0x69,0x6e,0x20,0x44,0x4f,0x53,0x20,
  87. 0x6d,0x6f,0x64,0x65,0x2e,0x0d,0x0d,0x0a,
  88. 0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  89. 0x50,0x45,0x00,0x00};
  90. internal static readonly int PESigOffset = 0x3C;
  91. internal static byte[] PEHeader = { 0x4c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  92. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  93. 0xE0, 0x00, 0x0E, 0x01, // PE Header Standard Fields
  94. 0x0B, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
  95. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  96. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  97. };
  98. internal static IType[] instrMap = {
  99. IType.op, IType.op, IType.op, IType.op, IType.op, IType.op, IType.op, IType.op, IType.op, // 0x00 - 0x08
  100. IType.op, IType.op, IType.op, IType.op, IType.op, IType.uint8Op, IType.uint8Op, // 0x09 - 0x0F
  101. IType.uint8Op, IType.uint8Op, IType.uint8Op, IType.uint8Op, // 0x10 - 0x13
  102. IType.op, IType.op, IType.op, IType.op, IType.op, IType.op, IType.op, IType.op, IType.op, // 0x14 - 0x1C
  103. IType.op, IType.op, IType.int8Op, IType.int32Op, IType.specialOp, // 0x1D - 0x21
  104. IType.specialOp, IType.specialOp,IType.op,IType.op,IType.op,IType.methOp, // 0x22 - 0x27
  105. IType.methOp, IType.specialOp, IType.op, IType.branchOp, IType.branchOp,// 0x28 - 0x2C
  106. IType.branchOp, IType.branchOp, IType.branchOp, IType.branchOp, // 0x2D - 0x30
  107. IType.branchOp, IType.branchOp, IType.branchOp, IType.branchOp, // 0x31 - 0x34
  108. IType.branchOp, IType.branchOp, IType.branchOp, IType.branchOp, // 0x35 - 0x38
  109. IType.branchOp, IType.branchOp, IType.branchOp, IType.branchOp, // 0x39 - 0x3C
  110. IType.branchOp, IType.branchOp, IType.branchOp, IType.branchOp, // 0x3D - 0x40
  111. IType.branchOp, IType.branchOp, IType.branchOp, IType.branchOp, // 0x41 - 0x44
  112. IType.specialOp, IType.op, IType.op, IType.op, IType.op, IType.op, IType.op, // 0x45 - 0x4B
  113. IType.op, IType.op, IType.op, IType.op, IType.op, IType.op, IType.op, IType.op, IType.op, // 0x4C - 0x54
  114. IType.op, IType.op, IType.op, IType.op, IType.op, IType.op, IType.op, IType.op, IType.op, // 0x55 - 0x5D
  115. IType.op, IType.op, IType.op, IType.op, IType.op, IType.op, IType.op, IType.op, IType.op, // 0x5E - 0x66
  116. IType.op, IType.op, IType.op, IType.op, IType.op, IType.op, IType.op, IType.op, // 0x67 - 0x6E
  117. IType.methOp, IType.typeOp, IType.typeOp, IType.specialOp, // 0x6F - 0x72
  118. IType.methOp, IType.typeOp, IType.typeOp, IType.op, IType.op, IType.op, // 0x73 - 0x78
  119. IType.typeOp, IType.op, IType.fieldOp, IType.fieldOp, IType.fieldOp,// 0x79 - 0x7D
  120. IType.fieldOp, IType.fieldOp, IType.fieldOp, IType.typeOp, // 0x7E - 0x81
  121. IType.op, IType.op, IType.op, IType.op, IType.op, IType.op, IType.op, IType.op, IType.op, // 0x82 - 0x8A
  122. IType.op, IType.typeOp, IType.typeOp, IType.op, IType.typeOp, IType.op, // 0x8B - 0x90
  123. IType.op, IType.op, IType.op, IType.op, IType.op, IType.op, IType.op, IType.op, IType.op, // 0x91 - 0x99
  124. IType.op, IType.op, IType.op, IType.op, IType.op, IType.op, IType.op, IType.op, IType.op, // 0x9A - 0xA2
  125. IType.typeOp, IType.typeOp, IType.typeOp, IType.op, IType.op, IType.op, IType.op, IType.op, IType.op, // 0xA3 - 0xAB
  126. IType.op, IType.op, IType.op, IType.op, IType.op, IType.op, IType.op, IType.op, IType.op, // 0xAC - 0xB4
  127. IType.op, IType.op, IType.op, IType.op, IType.op, IType.op, IType.op, IType.op, IType.op, // 0xB5 - 0xBD
  128. IType.op, IType.op, IType.op, IType.op, IType.typeOp, IType.op, IType.op, IType.op, // 0xBE - 0xC5
  129. IType.typeOp, IType.op, IType.op, IType.op, IType.op, IType.op, IType.op, IType.op, // 0xC6 - 0xCD
  130. IType.op, IType.op, IType.specialOp, IType.op, IType.op, IType.op, IType.op, // 0xCE - 0xD4
  131. IType.op, IType.op, IType.op, IType.op, IType.op, IType.op, IType.op, IType.op, // 0xD5 - 0xDC
  132. IType.branchOp, IType.branchOp, IType.op, IType.op }; // 0xDD - 0xE0
  133. internal static IType[] longInstrMap = { IType.op, IType.op, IType.op, IType.op, IType.op, IType.op, IType.methOp, // 0x00 - 0x06
  134. IType.methOp, IType.uint16Op, IType.uint16Op, // 0x07 - 0x09
  135. IType.uint16Op, IType.uint16Op, IType.uint16Op, // 0x0A - 0x0C
  136. IType.uint16Op, IType.uint16Op, IType.op, IType.op, IType.op, // 0x0D - 0x11
  137. IType.uint8Op, IType.op, IType.op, IType.typeOp, IType.typeOp, IType.op, // 0x12 - 0x17
  138. IType.op, IType.op, IType.op, IType.op, IType.typeOp, IType.op, IType.op}; // 0x18 - 0x1D
  139. internal static readonly uint bitmask0 = 0x00000001;
  140. internal static readonly uint bitmask1 = 0x00000002;
  141. internal static readonly uint bitmask2 = 0x00000004;
  142. internal static readonly uint bitmask3 = 0x00000008;
  143. internal static readonly uint bitmask4 = 0x00000010;
  144. internal static readonly uint bitmask5 = 0x00000020;
  145. internal static readonly uint bitmask6 = 0x00000040;
  146. internal static readonly uint bitmask7 = 0x00000080;
  147. internal static readonly uint bitmask8 = 0x00000100;
  148. internal static readonly uint bitmask9 = 0x00000200;
  149. internal static readonly uint bitmask10 = 0x00000400;
  150. internal static readonly uint bitmask11 = 0x00000800;
  151. internal static readonly uint bitmask12 = 0x00001000;
  152. internal static readonly uint bitmask13 = 0x00002000;
  153. internal static readonly uint bitmask14 = 0x00004000;
  154. internal static readonly uint bitmask15 = 0x00008000;
  155. internal static readonly uint bitmask16 = 0x00010000;
  156. internal static readonly uint bitmask17 = 0x00020000;
  157. internal static readonly uint bitmask18 = 0x00040000;
  158. internal static readonly uint bitmask19 = 0x00080000;
  159. internal static readonly uint bitmask20 = 0x00100000;
  160. internal static readonly uint bitmask21 = 0x00200000;
  161. internal static readonly uint bitmask22 = 0x00400000;
  162. internal static readonly uint bitmask23 = 0x00800000;
  163. internal static readonly uint bitmask24 = 0x01000000;
  164. internal static readonly uint bitmask25 = 0x02000000;
  165. internal static readonly uint bitmask26 = 0x04000000;
  166. internal static readonly uint bitmask27 = 0x08000000;
  167. internal static readonly uint bitmask28 = 0x10000000;
  168. internal static readonly uint bitmask29 = 0x20000000;
  169. internal static readonly uint bitmask30 = 0x40000000;
  170. internal static readonly uint bitmask31 = 0x80000000;
  171. internal static readonly ulong bitmask32 = 0x0000000100000000;
  172. internal static readonly ulong bitmask33 = 0x0000000200000000;
  173. internal static readonly ulong bitmask34 = 0x0000000400000000;
  174. internal static readonly ulong bitmask35 = 0x0000000800000000;
  175. internal static readonly ulong bitmask36 = 0x0000001000000000;
  176. internal static readonly ulong bitmask37 = 0x0000002000000000;
  177. internal static readonly ulong bitmask38 = 0x0000004000000000;
  178. internal static readonly ulong bitmask39 = 0x0000008000000000;
  179. internal static readonly ulong bitmask40 = 0x0000010000000000;
  180. internal static readonly ulong bitmask41 = 0x0000020000000000;
  181. internal static readonly ulong bitmask42 = 0x0000040000000000;
  182. internal static readonly ulong bitmask43 = 0x0000080000000000;
  183. internal static readonly ulong bitmask44 = 0x0000100000000000;
  184. internal static readonly ulong bitmask45 = 0x0000200000000000;
  185. internal static readonly ulong bitmask46 = 0x0000400000000000;
  186. internal static readonly ulong bitmask47 = 0x0000800000000000;
  187. internal static readonly ulong bitmask48 = 0x0001000000000000;
  188. internal static readonly ulong bitmask49 = 0x0002000000000000;
  189. internal static readonly ulong bitmask50 = 0x0004000000000000;
  190. internal static readonly ulong bitmask51 = 0x0008000000000000;
  191. internal static readonly ulong bitmask52 = 0x0010000000000000;
  192. internal static readonly ulong bitmask53 = 0x0020000000000000;
  193. internal static readonly ulong bitmask54 = 0x0040000000000000;
  194. internal static readonly ulong bitmask55 = 0x0080000000000000;
  195. internal static readonly ulong bitmask56 = 0x0100000000000000;
  196. internal static readonly ulong bitmask57 = 0x0200000000000000;
  197. internal static readonly ulong bitmask58 = 0x0400000000000000;
  198. internal static readonly ulong bitmask59 = 0x0800000000000000;
  199. internal static readonly ulong bitmask60 = 0x1000000000000000;
  200. internal static readonly ulong bitmask61 = 0x2000000000000000;
  201. internal static readonly ulong bitmask62 = 0x4000000000000000;
  202. internal static readonly ulong bitmask63 = 0x8000000000000000;
  203. internal static readonly ulong[] bitmasks = { bitmask0 , bitmask1 , bitmask2 , bitmask3 ,
  204. bitmask4 , bitmask5 , bitmask6 , bitmask7 ,
  205. bitmask8 , bitmask9 , bitmask10, bitmask11,
  206. bitmask12, bitmask13, bitmask14, bitmask15,
  207. bitmask16, bitmask17, bitmask18, bitmask19,
  208. bitmask20, bitmask21, bitmask22, bitmask23,
  209. bitmask24, bitmask25, bitmask26, bitmask27,
  210. bitmask28, bitmask29, bitmask30, bitmask31,
  211. bitmask32, bitmask33, bitmask34, bitmask35,
  212. bitmask36, bitmask37, bitmask38, bitmask39,
  213. bitmask40, bitmask41, bitmask42, bitmask43,
  214. bitmask44, bitmask45, bitmask46, bitmask47,
  215. bitmask48, bitmask49, bitmask50, bitmask51,
  216. bitmask52, bitmask53, bitmask54, bitmask55,
  217. bitmask56, bitmask57, bitmask58, bitmask59,
  218. bitmask60, bitmask61, bitmask62, bitmask63 };
  219. internal static readonly uint TableMask = 0xFF000000;
  220. internal static readonly uint ElementMask = 0x00FFFFFF;
  221. internal static readonly int NAMELEN = 8, STRLEN = 200;
  222. internal static readonly uint machine = 0x14C;
  223. internal static readonly uint machinex64 = 0x8664;
  224. internal static readonly uint magic = 0x10B;
  225. internal static readonly uint magic64 = 0x20B;
  226. internal static readonly uint minFileAlign = 0x200;
  227. internal static readonly uint midFileAlign = 0x400;
  228. internal static readonly uint maxFileAlign = 0x1000;
  229. internal static readonly uint fileHeaderSize = 0x178;
  230. internal static readonly uint sectionHeaderSize = 40;
  231. internal static readonly uint SectionAlignment = 0x2000;
  232. internal static readonly uint ImageBase = 0x400000;
  233. internal static readonly uint ImportTableSize = 40;
  234. internal static readonly uint IATSize = 8;
  235. internal static readonly uint CLIHeaderSize = 72;
  236. internal static readonly uint relocFlags = 0x42000040;
  237. internal static readonly ushort exeCharacteristics = 0x010E;
  238. internal static readonly ushort dllCharacteristics = 0x210E;
  239. internal static readonly ushort dllFlag = 0x2000;
  240. // section names are all 8 bytes
  241. internal static readonly string textName = ".text\0\0\0";
  242. internal static readonly string sdataName = ".sdata\0\0";
  243. internal static readonly string relocName = ".reloc\0\0";
  244. internal static readonly string rsrcName = ".rsrc\0\0\0";
  245. internal static readonly string exeHintNameTable = "\0\0_CorExeMain\0";
  246. internal static readonly string dllHintNameTable = "\0\0_CorDllMain\0";
  247. internal static readonly string runtimeEngineName = "mscoree.dll\0\0";
  248. internal static readonly DateTime origin = new DateTime(1970, 1, 1);
  249. internal static readonly ushort DLLFlags = (ushort)0x400; // for ver 1.1.4322 prev = (short)0;
  250. internal static readonly uint StackReserveSize = 0x100000;
  251. internal static readonly uint StackCommitSize = 0x1000;
  252. internal static readonly uint HeapReserveSize = 0x100000;
  253. internal static readonly uint HeapCommitSize = 0x1000;
  254. internal static readonly uint LoaderFlags = 0;
  255. internal static readonly uint NumDataDirectories = 0x10;
  256. }
  257. }