MetaDataClass.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  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. using System.Collections;
  20. namespace QUT.PERWAPI
  21. {
  22. /**************************************************************************/
  23. // Class containing MetaData Constants
  24. /**************************************************************************/
  25. /// <summary>
  26. /// MetaData
  27. /// Root (20 bytes + UTF-8 Version String + quad align padding)
  28. /// StreamHeaders (8 bytes + null terminated name string + quad align padding)
  29. /// Streams
  30. /// #~ (always present - holds metadata tables)
  31. /// #Strings (always present - holds identifier strings)
  32. /// #US (Userstring heap)
  33. /// #Blob (signature blobs)
  34. /// #GUID (guids for assemblies or Modules)
  35. /// </summary>
  36. internal class MetaData
  37. {
  38. internal static readonly uint maxSmlIxSize = 0xFFFF;
  39. internal static readonly uint max1BitSmlIx = 0x7FFF;
  40. internal static readonly uint max2BitSmlIx = 0x3FFF;
  41. internal static readonly uint max3BitSmlIx = 0x1FFF;
  42. internal static readonly uint max5BitSmlIx = 0x7FF;
  43. internal static readonly uint[] CIxBitMasks = { 0x0, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F };
  44. internal static readonly int[] CIxShiftMap = { 2, 2, 5, 1, 2, 3, 1, 1, 1, 2, 3, 2, 1 };
  45. internal static readonly uint[] CIxMaxMap = {max2BitSmlIx,max2BitSmlIx,max5BitSmlIx,
  46. max1BitSmlIx,max2BitSmlIx,max3BitSmlIx,
  47. max1BitSmlIx,max1BitSmlIx,max1BitSmlIx,
  48. max2BitSmlIx,max3BitSmlIx,max2BitSmlIx, max1BitSmlIx};
  49. internal static readonly int[] TypeDefOrRefTable = { (int)MDTable.TypeDef, (int)MDTable.TypeRef, (int)MDTable.TypeSpec };
  50. internal static readonly int[] HasConstantTable = { (int)MDTable.Field, (int)MDTable.Param, (int)MDTable.Property };
  51. internal static readonly int[] HasCustomAttributeTable = {(int)MDTable.Method, (int)MDTable.Field, (int)MDTable.TypeRef,
  52. (int)MDTable.TypeDef,(int)MDTable.Param, (int)MDTable.InterfaceImpl,
  53. (int)MDTable.MemberRef, (int)MDTable.Module,(int)MDTable.DeclSecurity,
  54. (int)MDTable.Property,(int)MDTable.Event, (int)MDTable.StandAloneSig,
  55. (int)MDTable.ModuleRef, (int)MDTable.TypeSpec, (int)MDTable.Assembly,
  56. (int)MDTable.AssemblyRef, (int)MDTable.File, (int)MDTable.ExportedType,
  57. (int)MDTable.ManifestResource };
  58. internal static readonly int[] HasFieldMarshalTable = { (int)MDTable.Field, (int)MDTable.Param };
  59. internal static readonly int[] HasDeclSecurityTable = { (int)MDTable.TypeDef, (int)MDTable.Method, (int)MDTable.Assembly };
  60. internal static readonly int[] MemberRefParentTable = {(int)MDTable.TypeDef, (int)MDTable.TypeRef, (int)MDTable.ModuleRef, (int)MDTable.Method,
  61. (int)MDTable.TypeSpec };
  62. internal static readonly int[] HasSemanticsTable = { (int)MDTable.Event, (int)MDTable.Property };
  63. internal static readonly int[] MethodDefOrRefTable = { (int)MDTable.Method, (int)MDTable.MemberRef };
  64. internal static readonly int[] MemberForwardedTable = { (int)MDTable.Field, (int)MDTable.Method };
  65. internal static readonly int[] ImplementationTable = { (int)MDTable.File, (int)MDTable.AssemblyRef, (int)MDTable.ExportedType };
  66. internal static readonly int[] CustomAttributeTypeTable = { 0, 0, (int)MDTable.Method, (int)MDTable.MemberRef };
  67. internal static readonly int[] ResolutionScopeTable = {(int)MDTable.Module, (int)MDTable.ModuleRef, (int)MDTable.AssemblyRef,
  68. (int)MDTable.TypeRef };
  69. internal static readonly int[] TypeOrMethodDefTable = { (int)MDTable.TypeDef, (int)MDTable.Method };
  70. internal static readonly int[][] CIxTables = {TypeDefOrRefTable, HasConstantTable,
  71. HasCustomAttributeTable, HasFieldMarshalTable, HasDeclSecurityTable,
  72. MemberRefParentTable, HasSemanticsTable, MethodDefOrRefTable, MemberForwardedTable,
  73. ImplementationTable, CustomAttributeTypeTable, ResolutionScopeTable,
  74. TypeOrMethodDefTable };
  75. internal static readonly byte StringsHeapMask = 0x1;
  76. internal static readonly byte GUIDHeapMask = 0x2;
  77. internal static readonly byte BlobHeapMask = 0x4;
  78. internal static readonly uint MetaDataSignature = 0x424A5342;
  79. // NOTE: version and stream name strings MUST always be quad padded
  80. internal static readonly string[] versions = { "v1.1.4322\0\0\0",
  81. "v2.0.40607\0\0",
  82. "v2.0.41202\0\0",
  83. "v2.0.50215\0\0",
  84. "v2.0.50727\0\0",
  85. "2.0.0.0\0"
  86. };
  87. internal static readonly byte[] LMajors = { 6, 8, 8, 8, 8 };
  88. //internal static readonly string shortVersion = version.Substring(0,9);
  89. internal static readonly char[] tildeNameArray = { '#', '~', '\0', '\0' };
  90. internal static readonly char[] stringsNameArray = { '#', 'S', 't', 'r', 'i', 'n', 'g', 's', '\0', '\0', '\0', '\0' };
  91. internal static readonly char[] usNameArray = { '#', 'U', 'S', '\0' };
  92. internal static readonly char[] guidNameArray = { '#', 'G', 'U', 'I', 'D', '\0', '\0', '\0' };
  93. internal static readonly char[] blobNameArray = { '#', 'B', 'l', 'o', 'b', '\0', '\0', '\0' };
  94. internal static readonly String stringsName = "#Strings";
  95. internal static readonly String userstringName = "#US";
  96. internal static readonly String blobName = "#Blob";
  97. internal static readonly String guidName = "#GUID";
  98. internal static readonly String tildeName = "#~";
  99. internal static readonly uint MetaDataHeaderSize = 20 + (uint)versions[0].Length;
  100. internal static readonly uint TildeHeaderSize = 24;
  101. internal static readonly uint StreamHeaderSize = 8;
  102. internal static readonly uint NumMetaDataTables = (int)MDTable.MaxMDTable;
  103. internal static readonly uint tildeHeaderSize = 8 + (uint)tildeNameArray.Length;
  104. internal ulong valid = 0, /*sorted = 0x000002003301FA00;*/ sorted = 0;
  105. internal bool[] largeIx = new bool[NumMetaDataTables];
  106. internal bool[] lgeCIx = new bool[(int)CIx.MaxCIx];
  107. internal uint[] elemSize = new uint[NumMetaDataTables];
  108. internal bool largeStrings = false, largeUS = false, largeGUID = false, largeBlob = false;
  109. internal MetaData()
  110. {
  111. InitMetaData();
  112. }
  113. internal void InitMetaData()
  114. {
  115. for (int i = 0; i < NumMetaDataTables; i++)
  116. largeIx[i] = false;
  117. for (int i = 0; i < lgeCIx.Length; i++)
  118. lgeCIx[i] = false;
  119. }
  120. internal bool LargeIx(MDTable tabIx) { return largeIx[(uint)tabIx]; }
  121. internal uint CodedIndexSize(CIx code)
  122. {
  123. if (lgeCIx[(uint)code]) return 4;
  124. return 2;
  125. }
  126. internal uint TableIndexSize(MDTable tabIx)
  127. {
  128. if (largeIx[(uint)tabIx]) return 4;
  129. return 2;
  130. }
  131. internal uint StringsIndexSize()
  132. {
  133. if (largeStrings) return 4;
  134. return 2;
  135. }
  136. internal uint GUIDIndexSize()
  137. {
  138. if (largeGUID) return 4;
  139. return 2;
  140. }
  141. internal uint USIndexSize()
  142. {
  143. if (largeUS) return 4;
  144. return 2;
  145. }
  146. internal uint BlobIndexSize()
  147. {
  148. if (largeBlob) return 4;
  149. return 2;
  150. }
  151. internal void CalcElemSize()
  152. {
  153. elemSize[(int)MDTable.Assembly] = Assembly.Size(this);
  154. elemSize[(int)MDTable.AssemblyOS] = 12;
  155. elemSize[(int)MDTable.AssemblyProcessor] = 4;
  156. elemSize[(int)MDTable.AssemblyRefOS] = 12 + TableIndexSize(MDTable.AssemblyRef);
  157. elemSize[(int)MDTable.AssemblyRefProcessor] = 4 + TableIndexSize(MDTable.AssemblyRef);
  158. elemSize[(int)MDTable.Module] = Module.Size(this);
  159. elemSize[(int)MDTable.TypeRef] = ClassRef.Size(this);
  160. elemSize[(int)MDTable.TypeDef] = ClassDef.Size(this);
  161. elemSize[(int)MDTable.Field] = FieldDef.Size(this);
  162. elemSize[(int)MDTable.Method] = MethodDef.Size(this);
  163. elemSize[(int)MDTable.Param] = Param.Size(this);
  164. elemSize[(int)MDTable.InterfaceImpl] = InterfaceImpl.Size(this);
  165. elemSize[(int)MDTable.MemberRef] = FieldRef.Size(this);
  166. elemSize[(int)MDTable.Constant] = ConstantElem.Size(this);
  167. elemSize[(int)MDTable.CustomAttribute] = CustomAttribute.Size(this);
  168. elemSize[(int)MDTable.FieldMarshal] = FieldMarshal.Size(this);
  169. elemSize[(int)MDTable.DeclSecurity] = DeclSecurity.Size(this);
  170. elemSize[(int)MDTable.ClassLayout] = ClassLayout.Size(this);
  171. elemSize[(int)MDTable.FieldLayout] = FieldLayout.Size(this);
  172. elemSize[(int)MDTable.StandAloneSig] = Signature.Size(this);
  173. elemSize[(int)MDTable.EventMap] = MapElem.Size(this, MDTable.EventMap);
  174. elemSize[(int)MDTable.Event] = Event.Size(this);
  175. elemSize[(int)MDTable.PropertyMap] = MapElem.Size(this, MDTable.PropertyMap);
  176. elemSize[(int)MDTable.Property] = Property.Size(this);
  177. elemSize[(int)MDTable.MethodSemantics] = MethodSemantics.Size(this);
  178. elemSize[(int)MDTable.MethodImpl] = MethodImpl.Size(this);
  179. elemSize[(int)MDTable.ModuleRef] = ModuleRef.Size(this);
  180. elemSize[(int)MDTable.TypeSpec] = TypeSpec.Size(this);
  181. elemSize[(int)MDTable.ImplMap] = ImplMap.Size(this);
  182. elemSize[(int)MDTable.FieldRVA] = FieldRVA.Size(this);
  183. elemSize[(int)MDTable.Assembly] = Assembly.Size(this);
  184. elemSize[(int)MDTable.AssemblyRef] = AssemblyRef.Size(this);
  185. elemSize[(int)MDTable.File] = FileRef.Size(this);
  186. elemSize[(int)MDTable.ExportedType] = ExternClass.Size(this);
  187. elemSize[(int)MDTable.ManifestResource] = ManifestResource.Size(this);
  188. elemSize[(int)MDTable.NestedClass] = MapElem.Size(this, MDTable.NestedClass);
  189. elemSize[(int)MDTable.GenericParam] = GenericParam.Size(this);
  190. elemSize[(int)MDTable.GenericParamConstraint] = GenericParamConstraint.Size(this);
  191. elemSize[(int)MDTable.MethodSpec] = MethodSpec.Size(this);
  192. }
  193. }
  194. }