Package pype32 :: Module dotnet |
[hide private]
[frames] | no frames]

# Source Code for Module pype32.dotnet

      1  #!/usr/bin/env python
      2  # -*- coding: utf-8 -*-
      3
      4  # Copyright (c) 2015, Sandor Nemes
      5  # All rights reserved.
      6  #
      7  # Redistribution and use in source and binary forms, with or without
      8  # modification, are permitted provided that the following conditions are met:
      9  #
     10  #     * Redistributions of source code must retain the above copyright notice,
     11  #       this list of conditions and the following disclaimer.
     12  #     * Redistributions in binary form must reproduce the above copyright
     13  #       notice,this list of conditions and the following disclaimer in the
     14  #       documentation and/or other materials provided with the distribution.
     15  #     * Neither the name of the copyright holder nor the names of its
     16  #       contributors may be used to endorse or promote products derived from
     17  #       this software without specific prior written permission.
     18  #
     19  # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     20  # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     21  # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     22  # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
     23  # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24  # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25  # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26  # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27  # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28  # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  # POSSIBILITY OF SUCH DAMAGE.
     30
     31  import sys
     32
     33  import datatypes
     34  import caching
     35
     36 -class StringHeapIndex(object):
     37
     38 -    def __init__(self, dt, streams):
     39          self.dt = dt
     40          self.streams = streams
     41          self.offset = 0
     42          self.value = None
     43
     44 -    def getString(self, offset):
     45          funcname = sys._getframe().f_code.co_name
     46          cache = caching.getCache(funcname)
     47          result = cache.get(offset)
     48          if result is not None: return result
     49
     50          for i in self.streams["#Strings"].info:
     51              cache.put(*i.iteritems().next())
     52
     53          return cache.get(offset)
     54
     55 -    def parse(self, readDataInstance):
     56          if self.dt.netMetaDataTableHeader.heapOffsetSizes.value & 0x1:
     57              self.offset = datatypes.DWORD(readDataInstance.readDword()).value
     58          else:
     59              self.offset = datatypes.WORD(readDataInstance.readWord()).value
     60          self.value = self.getString(self.offset)
     61          return self
     62
     63 -class GuidHeapIndex(object):
     64
     65 -    def __init__(self, dt, streams):
     66          self.dt = dt
     67          self.streams = streams
     68          self.offset = 0
     69          self.value = None
     70
     71 -    def getGuid(self, offset):
     72          funcname = sys._getframe().f_code.co_name
     73          cache = caching.getCache(funcname)
     74          result = cache.get(offset)
     75          if result is not None: return result
     76
     77          for i in self.streams["#GUID"].info:
     78              cache.put(*i.iteritems().next())
     79
     80          return cache.get(offset)
     81
     82 -    def parse(self, readDataInstance):
     83          if self.dt.netMetaDataTableHeader.heapOffsetSizes.value & 0x2:
     84              self.offset = datatypes.DWORD(readDataInstance.readDword()).value
     85          else:
     86              self.offset = datatypes.WORD(readDataInstance.readWord()).value
     87          self.value = self.getGuid(16*(self.offset-1))
     88          return self
     89
     90 -class BlobHeapIndex(object):
     91
     92 -    def __init__(self, dt, streams):
     93          self.dt = dt
     94          self.streams = streams
     95          self.offset = 0
     96          self.value = None
     97
     98 -    def getBlob(self, offset):
     99          funcname = sys._getframe().f_code.co_name
    100          cache = caching.getCache(funcname)
    101          result = cache.get(offset)
    102          if result is not None: return result
    103
    104          for i in self.streams["#Blob"].info:
    105              cache.put(*i.iteritems().next())
    106
    107          return cache.get(offset)
    108
    109 -    def parse(self, readDataInstance):
    110          if self.dt.netMetaDataTableHeader.heapOffsetSizes.value & 0x4:
    111              self.offset = datatypes.DWORD(readDataInstance.readDword()).value
    112          else:
    113              self.offset = datatypes.WORD(readDataInstance.readWord()).value
    114          self.value = self.getBlob(self.offset)
    115          return self
    116
    117
    118 -class MultiTableIndex(object):
    119
    120      refs = None
    121
    122 -    def __init__(self, dt=None, streams=None):
    123          if not self.refs: raise NotImplementedError
    124          self.dt = dt
    125          self.streams = streams
    126          self.value = None
    127          self.hash = "{0:x}".format(hash(self.refs))
    128
    129      @staticmethod
    130 -    def getBits(value):
    131          funcname = sys._getframe().f_code.co_name
    132          cache = caching.getCache(funcname)
    133          bits = cache.get(value)
    134          if bits is not None: return bits
    135
    136          bits = 0
    137          tmp = value - 1
    138          while tmp > 0:
    139              bits += 1
    140              tmp >>= 1
    141
    142          cache.put(value, bits)
    143          return bits
    144
    145 -    def dwordIndex(self):
    146          funcname = sys._getframe().f_code.co_name
    147          cache = caching.getCache(funcname)
    148          result = cache.get(self.hash)
    149          if result is not None: return result
    150
    151          largestTable = max(self.dt.tables[_]["rows"] for _ in self.refs if _ != "Not used")
    152          result = self.getBits(largestTable) > 16 - self.getBits(len(self.refs))
    153
    154          cache.put(self.hash, result)
    155          return result
    156
    157 -    def decodeValue(self, value):
    158          funcname = sys._getframe().f_code.co_name
    159          cache = caching.getCache(funcname + "#" + self.hash)
    160          result = cache.get(value)
    161          if result is not None: return result
    162
    163          bits = self.getBits(len(self.refs))
    164          result = (self.refs[value & (1 << bits)-1], value >> bits)
    165
    166          cache.put(value, result)
    167          return result
    168
    169 -    def parse(self, readDataInstance):
    170          if self.dwordIndex():
    171              self.value = self.decodeValue(datatypes.DWORD(readDataInstance.readDword()).value)
    172          else:
    173              self.value = self.decodeValue(datatypes.WORD(readDataInstance.readWord()).value)
    174          return self
    175
    176
    177 -class TypeDefOrRefIndex(MultiTableIndex):
    178      refs = (
    179          "TypeDef",
    180          "TypeRef",
    181          "TypeSpec"
    182      )
    183
    184 -class HasConstantIndex(MultiTableIndex):
    185      refs = (
    186          "Field",
    187          "Param",
    188          "Property"
    189      )
    190
    191 -class HasCustomAttributeIndex(MultiTableIndex):
    192      refs = (
    193          "MethodDef",
    194          "Field",
    195          "TypeRef",
    196          "TypeDef",
    197          "Param",
    198          "InterfaceImpl",
    199          "MemberRef",
    200          "Module",
    201          "Permission",
    202          "Property",
    203          "Event",
    204          "StandAloneSig",
    205          "ModuleRef",
    206          "TypeSpec",
    207          "Assembly",
    208          "AssemblyRef",
    209          "File",
    210          "ExportedType",
    211          "ManifestResource",
    212      )
    213
    214
    215 -class HasFieldMarshallIndex(MultiTableIndex):
    216      refs = (
    217          "Field",
    218          "Param",
    219      )
    220
    221
    222 -class HasDeclSecurityIndex(MultiTableIndex):
    223      refs = (
    224          "TypeDef",
    225          "MethodDef",
    226          "Assembly",
    227      )
    228
    229
    230 -class MemberRefParentIndex(MultiTableIndex):
    231      refs = (
    232          "TypeDef",
    233          "TypeRef",
    234          "ModuleRef",
    235          "MethodDef",
    236          "TypeSpec",
    237      )
    238
    239
    240 -class HasSemanticsIndex(MultiTableIndex):
    241      refs = (
    242          "Event",
    243          "Property",
    244      )
    245
    246
    247 -class MethodDefOrRefIndex(MultiTableIndex):
    248      refs = (
    249          "MethodDef",
    250          "MemberRef",
    251      )
    252
    253
    254 -class MemberForwardedIndex(MultiTableIndex):
    255      refs = (
    256          "Field",
    257          "MethodDef",
    258      )
    259
    260
    261 -class ImplementationIndex(MultiTableIndex):
    262      refs = (
    263          "File",
    264          "AssemblyRef",
    265          "ExportedType",
    266      )
    267
    268
    269 -class CustomAttributeTypeIndex(MultiTableIndex):
    270      refs = (
    271          "Not used",
    272          "Not used",
    273          "MethodDef",
    274          "MemberRef",
    275          "Not used"
    276      )
    277
    278
    279 -class ResolutionScopeIndex(MultiTableIndex):
    280      refs = (
    281          "Module",
    282          "ModuleRef",
    283          "AssemblyRef",
    284          "TypeRef"
    285      )
    286
    287
    288 -class TypeOrMethodDefIndex(MultiTableIndex):
    289      refs = (
    290          "TypeDef",
    291          "MethodDef",
    292      )
    293
    294
    295 -class FieldIndex(MultiTableIndex):
    296      refs = (
    297          "Field",
    298      )
    299
    300
    301 -class MethodDefIndex(MultiTableIndex):
    302      refs = (
    303          "MethodDef",
    304      )
    305
    306
    307 -class ParamIndex(MultiTableIndex):
    308      refs = (
    309          "Param",
    310      )
    311
    312
    313 -class TypeDefIndex(MultiTableIndex):
    314      refs = (
    315          "TypeDef",
    316      )
    317
    318
    319 -class EventIndex(MultiTableIndex):
    320      refs = (
    321          "Event",
    322      )
    323
    324
    325 -class PropertyIndex(MultiTableIndex):
    326      refs = (
    327          "Property",
    328      )
    329
    330
    331 -class ModuleRefIndex(MultiTableIndex):
    332      refs = (
    333          "ModuleRef",
    334      )
    335
    336
    337 -class AssemblyRefIndex(MultiTableIndex):
    338      refs = (
    339          "AssemblyRef",
    340      )
    341
    342
    343 -class GenericParamIndex(MultiTableIndex):
    344      refs = (
    345          "GenericParam",
    346      )
    347
    348
    349  MetadataTableNames = {
    350      0x00: "Module",
    351      0x01: "TypeRef",
    352      0x02: "TypeDef",
    353      0x03: "FieldPtr",
    354      0x04: "Field",
    355      0x05: "MethodPtr",
    356      0x06: "MethodDef",
    357      0x07: "ParamPtr",
    358      0x08: "Param",
    359      0x09: "InterfaceImpl",
    360      0x0a: "MemberRef",
    361      0x0b: "Constant",
    362      0x0c: "CustomAttribute",
    363      0x0d: "FieldMarshal",
    364      0x0e: "Permission", # DeclSecurity
    365      0x0f: "ClassLayout",
    366      0x10: "FieldLayout",
    367      0x11: "StandAloneSig",
    368      0x12: "EventMap",
    369      0x13: "EventPtr",
    370      0x14: "Event",
    371      0x15: "PropertyMap",
    372      0x16: "PropertyPtr",
    373      0x17: "Property",
    374      0x18: "MethodSemantics",
    375      0x19: "MethodImpl",
    376      0x1a: "ModuleRef",
    377      0x1b: "TypeSpec",
    378      0x1c: "ImplMap",
    379      0x1d: "FieldRVA",
    380      0x1e: None,
    381      0x1f: None,
    382      0x20: "Assembly",
    383      0x21: "AssemblyProcessor",
    384      0x22: "AssemblyOS",
    385      0x23: "AssemblyRef",
    386      0x24: "AssemblyRefProcessor",
    387      0x25: "AssemblyRefOS",
    388      0x26: "File",
    389      0x27: "ExportedType",
    390      0x28: "ManifestResource",
    391      0x29: "NestedClass",
    392      0x2a: "GenericParam",
    393      0x2b: "MethodSpec",
    394      0x2c: "GenericParamConstraint",
    395      0x2d: None,
    396      0x2e: None,
    397      0x2f: None,
    398      0x30: None,
    399      0x31: None,
    400      0x32: None,
    401      0x33: None,
    402      0x34: None,
    403      0x35: None,
    404      0x36: None,
    405      0x37: None,
    406      0x38: None,
    407      0x39: None,
    408      0x3a: None,
    409      0x3b: None,
    410      0x3c: None,
    411      0x3d: None,
    412      0x3e: None,
    413      0x3f: None,
    414  }
    415
    416
    417 -def MetadataTableDefinitions(dt, netMetaDataStreams):
    418      return {
    419          0x00: [
    420              { "generation": datatypes.WORD() },
    421              { "name": StringHeapIndex(dt, netMetaDataStreams) },
    422              { "mvId": GuidHeapIndex(dt, netMetaDataStreams) },
    423              { "encId": GuidHeapIndex(dt, netMetaDataStreams) },
    424              { "encBaseId": GuidHeapIndex(dt, netMetaDataStreams) },
    425          ],
    426          0x01: [
    427              { "resolutionScope": ResolutionScopeIndex(dt, netMetaDataStreams) },
    428              { "typeName": StringHeapIndex(dt, netMetaDataStreams) },
    429              { "typeNamespace": StringHeapIndex(dt, netMetaDataStreams) },
    430          ],
    431          0x02: [
    432              { "flags": datatypes.DWORD() },
    433              { "typeName": StringHeapIndex(dt, netMetaDataStreams) },
    434              { "typeNamespace": StringHeapIndex(dt, netMetaDataStreams) },
    435              { "extends": TypeDefOrRefIndex(dt, netMetaDataStreams) },
    436              { "fieldList": FieldIndex(dt, netMetaDataStreams) },
    437              { "methodList": MethodDefIndex(dt, netMetaDataStreams) },
    438          ],
    439          0x03: [
    440              { "ref": datatypes.WORD() },
    441          ],
    442          0x04: [
    443              { "flags": datatypes.WORD() },
    444              { "name": StringHeapIndex(dt, netMetaDataStreams) },
    445              { "signature": BlobHeapIndex(dt, netMetaDataStreams) },
    446          ],
    447          0x05: [
    448              { "ref": datatypes.WORD() },
    449          ],
    450          0x06: [
    451              { "rva": datatypes.DWORD() },
    452              { "implFlags": datatypes.WORD() },
    453              { "flags": datatypes.WORD() },
    454              { "name": StringHeapIndex(dt, netMetaDataStreams) },
    455              { "signature": BlobHeapIndex(dt, netMetaDataStreams) },
    456              { "paramList": ParamIndex(dt, netMetaDataStreams) },
    457          ],
    458          0x07: [
    459              { "ref": datatypes.WORD() },
    460          ],
    461          0x08: [
    462              { "flags": datatypes.WORD() },
    463              { "sequence": datatypes.WORD() },
    464              { "name": StringHeapIndex(dt, netMetaDataStreams) },
    465          ],
    466          0x09: [
    467              { "class": TypeDefIndex(dt, netMetaDataStreams) },
    468              { "interface": TypeDefOrRefIndex(dt, netMetaDataStreams) },
    469          ],
    470          0x0a: [
    471              { "class": MemberRefParentIndex(dt, netMetaDataStreams) },
    472              { "name": StringHeapIndex(dt, netMetaDataStreams) },
    473              { "signature": BlobHeapIndex(dt, netMetaDataStreams) },
    474          ],
    475          0x0b: [
    476              { "type": datatypes.WORD() },
    477              { "parent": HasConstantIndex(dt, netMetaDataStreams) },
    478              { "value": BlobHeapIndex(dt, netMetaDataStreams) },
    479          ],
    480          0x0c: [
    481              { "parent": HasCustomAttributeIndex(dt, netMetaDataStreams) },
    482              { "type": CustomAttributeTypeIndex(dt, netMetaDataStreams) },
    483              { "value": BlobHeapIndex(dt, netMetaDataStreams) },
    484          ],
    485          0x0d: [
    486              { "parent": HasFieldMarshallIndex(dt, netMetaDataStreams) },
    487              { "nativeType": BlobHeapIndex(dt, netMetaDataStreams) },
    488          ],
    489          0x0e: [
    490              { "action": datatypes.WORD() },
    491              { "parent": HasDeclSecurityIndex(dt, netMetaDataStreams) },
    492              { "permissionSet": BlobHeapIndex(dt, netMetaDataStreams) },
    493          ],
    494          0x0f: [
    495              { "packingSize": datatypes.WORD() },
    496              { "classSize": datatypes.DWORD() },
    497              { "parent": TypeDefIndex(dt, netMetaDataStreams) },
    498          ],
    499          0x10: [
    500              { "offset": datatypes.DWORD() },
    501              { "field": FieldIndex(dt, netMetaDataStreams) },
    502          ],
    503          0x11: [
    504              { "signature": BlobHeapIndex(dt, netMetaDataStreams) },
    505          ],
    506          0x12: [
    507              { "parent": TypeDefIndex(dt, netMetaDataStreams) },
    508              { "eventList": EventIndex(dt, netMetaDataStreams) },
    509          ],
    510          0x13: [
    511              { "ref": datatypes.WORD() },
    512          ],
    513          0x14: [
    514              { "eventFlags": datatypes.WORD() },
    515              { "name": StringHeapIndex(dt, netMetaDataStreams) },
    516              { "eventType": TypeDefOrRefIndex(dt, netMetaDataStreams) },
    517          ],
    518          0x15: [
    519              { "parent": TypeDefIndex(dt, netMetaDataStreams) },
    520              { "propertyList": PropertyIndex(dt, netMetaDataStreams) },
    521          ],
    522          0x16: [
    523              { "ref": datatypes.WORD() },
    524          ],
    525          0x17: [
    526              { "flags": datatypes.WORD() },
    527              { "name": StringHeapIndex(dt, netMetaDataStreams) },
    528              { "type": BlobHeapIndex(dt, netMetaDataStreams) },
    529          ],
    530          0x18: [
    531              { "semantics": datatypes.WORD() },
    532              { "method": MethodDefIndex(dt, netMetaDataStreams) },
    533              { "association": HasSemanticsIndex(dt, netMetaDataStreams) },
    534          ],
    535          0x19: [
    536              { "class": TypeDefIndex(dt, netMetaDataStreams) },
    537              { "methodBody": MethodDefOrRefIndex(dt, netMetaDataStreams) },
    538              { "methodDeclaration": MethodDefOrRefIndex(dt, netMetaDataStreams) },
    539          ],
    540          0x1a: [
    541              { "name": StringHeapIndex(dt, netMetaDataStreams) },
    542          ],
    543          0x1b: [
    544              { "signature": BlobHeapIndex(dt, netMetaDataStreams) },
    545          ],
    546          0x1c: [
    547              { "mappingFlags": datatypes.WORD() },
    548              { "memberForwarded": MemberForwardedIndex(dt, netMetaDataStreams) },
    549              { "importName": StringHeapIndex(dt, netMetaDataStreams) },
    550              { "importScope": ModuleRefIndex(dt, netMetaDataStreams) },
    551          ],
    552          0x1d: [
    553              { "rva": datatypes.DWORD() },
    554              { "field": FieldIndex(dt, netMetaDataStreams) },
    555          ],
    556          0x1e: None,
    557          0x1f: None,
    558          0x20: [
    559              { "hashAlgId": datatypes.DWORD() },
    560              { "majorVersion": datatypes.WORD() },
    561              { "minorVersion": datatypes.WORD() },
    562              { "buildNumber": datatypes.WORD() },
    563              { "revisionNumber": datatypes.WORD() },
    564              { "flags": datatypes.DWORD() },
    565              { "publicKey": BlobHeapIndex(dt, netMetaDataStreams) },
    566              { "name": StringHeapIndex(dt, netMetaDataStreams) },
    567              { "culture": StringHeapIndex(dt, netMetaDataStreams) },
    568          ],
    569          0x21: [
    570              { "processor": datatypes.DWORD() },
    571          ],
    572          0x22: [
    573              { "osPlatformId": datatypes.DWORD() },
    574              { "osMajorVersion": datatypes.DWORD() },
    575              { "osMinorVersion": datatypes.DWORD() },
    576          ],
    577          0x23: [
    578              { "majorVersion": datatypes.WORD() },
    579              { "minorVersion": datatypes.WORD() },
    580              { "buildNumber": datatypes.WORD() },
    581              { "revisionNumber": datatypes.WORD() },
    582              { "flags": datatypes.DWORD() },
    583              { "publicKeyOrToken": BlobHeapIndex(dt, netMetaDataStreams) },
    584              { "name": StringHeapIndex(dt, netMetaDataStreams) },
    585              { "culture": StringHeapIndex(dt, netMetaDataStreams) },
    586              { "hashValue": BlobHeapIndex(dt, netMetaDataStreams) },
    587          ],
    588          0x24: [
    589              { "processor": datatypes.DWORD() },
    590              { "assemblyRef": AssemblyRefIndex(dt, netMetaDataStreams) },
    591          ],
    592          0x25: [
    593              { "osPlatformId": datatypes.DWORD() },
    594              { "osMajorVersion": datatypes.DWORD() },
    595              { "osMinorVersion": datatypes.DWORD() },
    596              { "assemblyRef": AssemblyRefIndex(dt, netMetaDataStreams) },
    597          ],
    598          0x26: [
    599              { "flags": datatypes.DWORD() },
    600              { "name": StringHeapIndex(dt, netMetaDataStreams) },
    601              { "hashValue": BlobHeapIndex(dt, netMetaDataStreams) },
    602          ],
    603          0x27: [
    604              { "flags": datatypes.DWORD() },
    605              { "typeDefId": datatypes.DWORD() },
    606              { "typeName": StringHeapIndex(dt, netMetaDataStreams) },
    607              { "typeNamespace": StringHeapIndex(dt, netMetaDataStreams) },
    608              { "implementation": ImplementationIndex(dt, netMetaDataStreams) },
    609          ],
    610          0x28: [
    611              { "offset": datatypes.DWORD() },
    612              { "flags": datatypes.DWORD() },
    613              { "name": StringHeapIndex(dt, netMetaDataStreams) },
    614              { "implementation": ImplementationIndex(dt, netMetaDataStreams) },
    615          ],
    616          0x29: [
    617              { "nestedClass": TypeDefIndex(dt, netMetaDataStreams) },
    618              { "enclosingClass": TypeDefIndex(dt, netMetaDataStreams) },
    619          ],
    620          0x2a: [
    621              { "number": datatypes.WORD() },
    622              { "flags": datatypes.WORD() },
    623              { "owner": TypeOrMethodDefIndex(dt, netMetaDataStreams) },
    624              { "name": StringHeapIndex(dt, netMetaDataStreams) },
    625          ],
    626          0x2b: [
    627              { "method": MethodDefOrRefIndex(dt, netMetaDataStreams) },
    628              { "instantiation": BlobHeapIndex(dt, netMetaDataStreams) },
    629          ],
    630          0x2c: [
    631              { "owner": GenericParamIndex(dt, netMetaDataStreams) },
    632              { "constraint": TypeDefOrRefIndex(dt, netMetaDataStreams) },
    633          ],
    634          0x2d: None,
    635          0x2e: None,
    636          0x2f: None,
    637          0x30: None,
    638          0x31: None,
    639          0x32: None,
    640          0x33: None,
    641          0x34: None,
    642          0x35: None,
    643          0x36: None,
    644          0x37: None,
    645          0x38: None,
    646          0x39: None,
    647          0x3a: None,
    648          0x3b: None,
    649          0x3c: None,
    650          0x3d: None,
    651          0x3e: None,
    652          0x3f: None,
    653      }
    654