578 lines
17 KiB
Python
578 lines
17 KiB
Python
import enum
|
|
from destruct import Struct
|
|
|
|
from .util import MultiEnum
|
|
from .common import (
|
|
CLIElementType, CLIStreamType, CLITableType,
|
|
CLICodedToken, CLIStreamIndex, CLITableIndex, CLITableRange
|
|
)
|
|
from .types import CLIElementType, CLISignature, CLINativeSignature
|
|
|
|
|
|
TABLE_PARSERS = {}
|
|
|
|
def table_parser(name):
|
|
def inner(c):
|
|
TABLE_PARSERS[name] = c
|
|
return c
|
|
return inner
|
|
|
|
|
|
@table_parser(CLITableType.Module)
|
|
class CLIModuleTable(Struct, nocopy=True):
|
|
generation = UInt(16)
|
|
name = CLIStreamIndex(CLIStreamType.String)
|
|
mvid = CLIStreamIndex(CLIStreamType.GUID)
|
|
encid = CLIStreamIndex(CLIStreamType.GUID)
|
|
encbaseid = CLIStreamIndex(CLIStreamType.GUID)
|
|
|
|
|
|
ResolutionScope = CLICodedToken([
|
|
CLITableType.Module, CLITableType.ModuleRef,
|
|
CLITableType.AssemblyRef, CLITableType.TypeRef
|
|
])
|
|
|
|
@table_parser(CLITableType.TypeRef)
|
|
class CLITypeRefTable(Struct, nocopy=True):
|
|
scope = ResolutionScope
|
|
name = CLIStreamIndex(CLIStreamType.String)
|
|
namespace = CLIStreamIndex(CLIStreamType.String)
|
|
|
|
|
|
TypeDefOrRef = CLICodedToken([
|
|
CLITableType.TypeDef, CLITableType.TypeRef, CLITableType.TypeSpec
|
|
])
|
|
|
|
class CLITypeVisiblity(enum.Enum):
|
|
Private = 0x0
|
|
Public = 0x1
|
|
NestedPublic = 0x2
|
|
NestedPrivate = 0x3
|
|
NestedFamily = 0x4
|
|
NestedAssembly = 0x5
|
|
NestedFamANDAssem = 0x6
|
|
NestedFamORAssem = 0x7
|
|
|
|
class CLITypeLayout(enum.Enum):
|
|
Auto = 0x0
|
|
Sequential = 0x8
|
|
Explicit = 0x10
|
|
|
|
class CLITypeClassSemantics(enum.Enum):
|
|
Class = 0x0
|
|
Interface = 0x20
|
|
|
|
class CLITypeStringFormatting(enum.IntFlag):
|
|
ANSI = 0
|
|
Unicode = 0x10000
|
|
Custom = 0x30000
|
|
|
|
class CLITypeFlags(enum.Flag):
|
|
Abstract = 0x80
|
|
Sealed = 0x100
|
|
SpecialName = 0x400
|
|
RTSpecialName = 0x800
|
|
Import = 0x1000
|
|
Serializable = 0x2000
|
|
HasSecurity = 0x4000
|
|
BeforeFieldInit = 0x100000
|
|
IsTypeForwarder = 0x200000
|
|
|
|
class CLITypeAttributes(MultiEnum):
|
|
visibility = (CLITypeVisiblity, 0x7)
|
|
layout = (CLITypeLayout, 0x18)
|
|
semantics = (CLITypeClassSemantics, 0x20)
|
|
formatting = (CLITypeStringFormatting, 0xC30000)
|
|
flags = (CLITypeFlags, None)
|
|
|
|
@table_parser(CLITableType.TypeDef)
|
|
class CLITypeDefTable(Struct, nocopy=True):
|
|
flags = Enum(CLITypeAttributes, UInt(32))
|
|
name = CLIStreamIndex(CLIStreamType.String)
|
|
namespace = CLIStreamIndex(CLIStreamType.String)
|
|
extends = TypeDefOrRef
|
|
fields = CLITableRange(CLITableType.Field)
|
|
methods = CLITableRange(CLITableType.MethodDef)
|
|
|
|
|
|
@table_parser(CLITableType.FieldPointer)
|
|
def CLIFieldPointerTable(Struct, nocopy=True):
|
|
field = CLITableIndex(CLITableType.Field)
|
|
|
|
|
|
class CLIAccess(enum.Enum):
|
|
CompilerControlled = 0
|
|
Private = 1
|
|
FamANDAssem = 2
|
|
Assembly = 3
|
|
Family = 4
|
|
FamORAssem = 5
|
|
Public = 6
|
|
|
|
class CLIFieldFlags(enum.Flag):
|
|
Static = 0x10
|
|
InitOnly = 0x20
|
|
Literal = 0x40
|
|
NotSerialized = 0x80
|
|
HasFieldRVA = 0x100
|
|
SpecialName = 0x200
|
|
RTSpecialName = 0x400
|
|
HasFieldMarshal = 0x1000
|
|
PInvokeImpl = 0x2000
|
|
HasDefault = 0x8000
|
|
|
|
class CLIFieldAttributes(MultiEnum):
|
|
access = (CLIAccess, 0x7)
|
|
flags = (CLIFieldFlags, 0xFFF0)
|
|
|
|
@table_parser(CLITableType.Field)
|
|
class CLIFieldTable(Struct, nocopy=True):
|
|
flags = Enum(CLIFieldAttributes, UInt(16))
|
|
name = CLIStreamIndex(CLIStreamType.String)
|
|
signature = CLIStreamIndex(CLIStreamType.Blob, CLISignature)
|
|
|
|
|
|
@table_parser(CLITableType.MethodPointer)
|
|
def CLIMethodPointerTable(Struct, nocopy=True):
|
|
method = CLITableIndex(CLITableType.Method)
|
|
|
|
|
|
class CLIMemberVtableLayout(enum.Enum):
|
|
ReuseSlot = 0
|
|
NewSlot = 0x100
|
|
|
|
class CLIMethodFlags(enum.Flag):
|
|
Static = 0x10
|
|
Final = 0x20
|
|
Virtual = 0x40
|
|
HideBySig = 0x80
|
|
Strict = 0x200
|
|
Abstract = 0x400
|
|
SpecialName = 0x800
|
|
RTSpecialName = 0x1000
|
|
PInvokeImpl = 0x2000
|
|
HasSecurity = 0x4000
|
|
RequireSecObject = 0x8000
|
|
|
|
class CLIMethodAttributes(MultiEnum):
|
|
access = (CLIAccess, 0x7)
|
|
vtable = (CLIMemberVtableLayout, 0x100)
|
|
flags = (CLIMethodFlags, 0xFEF0)
|
|
|
|
class CLIMethodCodeType(enum.Enum):
|
|
CIL = 0
|
|
Native = 1
|
|
OPTIL = 2
|
|
Runtime = 3
|
|
|
|
class CLIMethodManaged(enum.Enum):
|
|
Managed = 0
|
|
Unmanaged = 4
|
|
|
|
class CLIMethodImplFlags(enum.Flag):
|
|
NoInlining = 0x8
|
|
ForwardRef = 0x10
|
|
Synchronized = 0x20
|
|
NoOptimization = 0x40
|
|
PreserveSig = 0x80
|
|
AggressiveInlining = 0x100
|
|
InternalCall = 0x1000
|
|
|
|
class CLIMethodImplAttributes(MultiEnum):
|
|
code_type = (CLIMethodCodeType, 0x3)
|
|
managed = (CLIMethodManaged, 0x4)
|
|
flags = (CLIMethodImplFlags, 0xFFF8)
|
|
|
|
@table_parser(CLITableType.MethodDef)
|
|
class CLIMethodDefTable(Struct, nocopy=True):
|
|
rva = UInt(32)
|
|
impl_flags = Enum(CLIMethodImplAttributes, UInt(16))
|
|
flags = Enum(CLIMethodAttributes, UInt(16))
|
|
name = CLIStreamIndex(CLIStreamType.String)
|
|
signature = CLIStreamIndex(CLIStreamType.Blob, CLISignature)
|
|
params = CLITableRange(CLITableType.Param)
|
|
|
|
|
|
@table_parser(CLITableType.ParamPointer)
|
|
def CLIParamPointerTable(Struct, nocopy=True):
|
|
param = CLITableIndex(CLITableType.Param)
|
|
|
|
|
|
class CLIParamAttributes(enum.Flag):
|
|
In = 0x1
|
|
Out = 0x2
|
|
Optional = 0x10
|
|
HasDefault = 0x1000
|
|
HasFieldMarshal = 0x2000
|
|
|
|
@table_parser(CLITableType.Param)
|
|
class CLIParamTable(Struct, nocopy=True):
|
|
flags = Enum(CLIParamAttributes, UInt(16))
|
|
sequence = UInt(16)
|
|
name = CLIStreamIndex(CLIStreamType.String)
|
|
|
|
|
|
MemberRefParent = CLICodedToken([
|
|
CLITableType.MethodDef, CLITableType.ModuleRef,
|
|
CLITableType.TypeDef, CLITableType.TypeRef, CLITableType.TypeSpec
|
|
])
|
|
|
|
@table_parser(CLITableType.MemberRef)
|
|
class CLIMemberRefTable(Struct, nocopy=True):
|
|
parent = MemberRefParent
|
|
name = CLIStreamIndex(CLIStreamType.String)
|
|
signature = CLIStreamIndex(CLIStreamType.Blob, CLISignature)
|
|
|
|
|
|
HasCustomAttribute = CLICodedToken([
|
|
CLITableType.MethodDef, CLITableType.Field,
|
|
CLITableType.TypeDef, CLITableType.TypeRef,
|
|
CLITableType.Param, CLITableType.InterfaceImpl,
|
|
CLITableType.MemberRef, CLITableType.Module, 'Permission',
|
|
CLITableType.Property, CLITableType.Event,
|
|
CLITableType.StandAloneSig, CLITableType.ModuleRef, CLITableType.TypeSpec,
|
|
CLITableType.Assembly, CLITableType.AssemblyRef,
|
|
CLITableType.File, CLITableType.ExportedType, CLITableType.ManifestResource,
|
|
CLITableType.GenericParam, CLITableType.GenericParamConstraint,
|
|
CLITableType.MethodSpec
|
|
])
|
|
CustomAttributeType = CLICodedToken([
|
|
None, None, CLITableType.MethodDef, CLITableType.MemberRef, None
|
|
])
|
|
|
|
class CLICustomAttribute(Struct, nocopy=True):
|
|
prolog = Sig(b'\x01\x00')
|
|
fixed = Arr([])
|
|
named_count = UInt(16)
|
|
named = Arr([])
|
|
|
|
def on_named_count(self, spec, context):
|
|
spec.named.count = self.named_count
|
|
|
|
@table_parser(CLITableType.CustomAttribute)
|
|
class CLICustomAttributeTable(Struct, nocopy=True):
|
|
parent = HasCustomAttribute
|
|
type = CustomAttributeType
|
|
value = CLIStreamIndex(CLIStreamType.Blob, CLICustomAttribute)
|
|
|
|
|
|
@table_parser(CLITableType.StandAloneSig)
|
|
class CLIStandAloneSigTable(Struct, nocopy=True):
|
|
signature = CLIStreamIndex(CLIStreamType.Blob, CLISignature)
|
|
|
|
|
|
@table_parser(CLITableType.TypeSpec)
|
|
class CLITypeSpecTable(Struct, nocopy=True):
|
|
signature = CLIStreamIndex(CLIStreamType.Blob, CLISignature)
|
|
|
|
|
|
class AssemblyHashAlgorithm(enum.Enum):
|
|
Null = 0
|
|
MD5 = 0x8003
|
|
SHA1 = 0x8004
|
|
|
|
class AssemblyFlags(enum.Flag):
|
|
PublicKey = 0x1
|
|
Retargetable = 0x100
|
|
DisableJITOptimizing = 0x4000
|
|
EnableJITracking = 0x8000
|
|
|
|
@table_parser(CLITableType.Assembly)
|
|
class CLIAssemblyTable(Struct, nocopy=True):
|
|
hash_algo = Enum(AssemblyHashAlgorithm, UInt(32))
|
|
version_major = UInt(16)
|
|
version_minor = UInt(16)
|
|
build_number = UInt(16)
|
|
rev_number = UInt(16)
|
|
flags = Enum(AssemblyFlags, UInt(32))
|
|
public_key = CLIStreamIndex(CLIStreamType.Blob)
|
|
name = CLIStreamIndex(CLIStreamType.String)
|
|
culture = CLIStreamIndex(CLIStreamType.String)
|
|
|
|
|
|
@table_parser(CLITableType.AssemblyCPU)
|
|
class CLIAssemblyCPUTable(Struct, nocopy=True):
|
|
processor = UInt(32)
|
|
|
|
|
|
@table_parser(CLITableType.AssemblyOS)
|
|
class CLIAssemblyOSTable(Struct, nocopy=True):
|
|
platform_id = UInt(32)
|
|
version_major = UInt(32)
|
|
version_minor = UInt(32)
|
|
|
|
|
|
@table_parser(CLITableType.AssemblyRef)
|
|
class CLIAssemblyRefTable(Struct, nocopy=True):
|
|
version_major = UInt(16)
|
|
version_minor = UInt(16)
|
|
build_number = UInt(16)
|
|
rev_number = UInt(16)
|
|
flags = Enum(AssemblyFlags, UInt(32))
|
|
public_key = CLIStreamIndex(CLIStreamType.Blob)
|
|
name = CLIStreamIndex(CLIStreamType.String)
|
|
culture = CLIStreamIndex(CLIStreamType.String)
|
|
hash_value = CLIStreamIndex(CLIStreamType.Blob)
|
|
|
|
|
|
@table_parser(CLITableType.AssemblyRefCPU)
|
|
class CLIAssemblyRefCPUTable(Struct, nocopy=True):
|
|
processor = UInt(32)
|
|
assembly = CLITableIndex(CLITableType.Assembly)
|
|
|
|
|
|
@table_parser(CLITableType.AssemblyRefOS)
|
|
class CLIAssemblyRefOSTable(Struct, nocopy=True):
|
|
platform_id = UInt(32)
|
|
version_major = UInt(32)
|
|
version_minor = UInt(32)
|
|
assembly = CLITableIndex(CLITableType.Assembly)
|
|
|
|
|
|
Implementation = CLICodedToken([
|
|
CLITableType.File, CLITableType.AssemblyRef, CLITableType.ExportedType
|
|
])
|
|
|
|
class ManifestResourceAttributes(enum.Enum):
|
|
Public = 1
|
|
Private = 2
|
|
|
|
@table_parser(CLITableType.ManifestResource)
|
|
class CLIManifestResourceTable(Struct, nocopy=True):
|
|
offset = UInt(32)
|
|
flags = Enum(ManifestResourceAttributes, UInt(32))
|
|
name = CLIStreamIndex(CLIStreamType.String)
|
|
implementation = Implementation
|
|
|
|
|
|
@table_parser(CLITableType.NestedClass)
|
|
class CLINestedClassTable(Struct, nocopy=True):
|
|
nested = CLITableIndex(CLITableType.TypeDef)
|
|
enclosing = CLITableIndex(CLITableType.TypeDef)
|
|
|
|
|
|
@table_parser(CLITableType.InterfaceImpl)
|
|
class CLIInterfaceImplTable(Struct, nocopy=True):
|
|
type = CLITableIndex(CLITableType.TypeDef)
|
|
interface = TypeDefOrRef
|
|
|
|
|
|
HasConstant = CLICodedToken([
|
|
CLITableType.Param, CLITableType.Field, CLITableType.Property
|
|
])
|
|
|
|
@table_parser(CLITableType.Constant)
|
|
class CLIConstantTable(Struct, nocopy=True):
|
|
type = Enum(CLIElementType, UInt(8))
|
|
_pad1 = UInt(8)
|
|
parent = HasConstant
|
|
value = CLIStreamIndex(CLIStreamType.Blob)
|
|
|
|
|
|
HasDeclSecurity = CLICodedToken([
|
|
CLITableType.TypeDef, CLITableType.MethodDef, CLITableType.Assembly
|
|
])
|
|
|
|
class CLISecurityAction(enum.Enum):
|
|
Demand = 2
|
|
Assert = 3
|
|
Deny = 4
|
|
PermitOnly = 5
|
|
LinkDemand = 6
|
|
InheritanceDemand = 7
|
|
RequestMinimum = 8
|
|
RequestOptional = 9
|
|
RequestRefuse = 10
|
|
|
|
@table_parser(CLITableType.DeclSecurity)
|
|
class CLIDeclSecurityTable(Struct, nocopy=True):
|
|
action = Enum(CLISecurityAction, UInt(16))
|
|
parent = HasDeclSecurity
|
|
permission_set = CLIStreamIndex(CLIStreamType.Blob)
|
|
|
|
|
|
@table_parser(CLITableType.ClassLayout)
|
|
class CLIClassLayoutTable(Struct, nocopy=True):
|
|
packing_size = UInt(16)
|
|
class_size = UInt(32)
|
|
parent = CLITableIndex(CLITableType.TypeDef)
|
|
|
|
|
|
@table_parser(CLITableType.FieldLayout)
|
|
class CLIFieldLayoutTable(Struct, nocopy=True):
|
|
offset = UInt(32)
|
|
field = CLITableIndex(CLITableType.Field)
|
|
|
|
|
|
@table_parser(CLITableType.EventMap)
|
|
class CLIEventMapTable(Struct, nocopy=True):
|
|
parent = CLITableIndex(CLITableType.TypeDef)
|
|
events = CLITableRange(CLITableType.Event)
|
|
|
|
|
|
@table_parser(CLITableType.EventPointer)
|
|
class CLIEventPointerTable(Struct, nocopy=True):
|
|
event = CLITableIndex(CLITableType.Event)
|
|
|
|
|
|
class CLIEventAttributes(enum.Flag):
|
|
SpecialName = 0x200
|
|
RTSpecialName = 0x400
|
|
|
|
@table_parser(CLITableType.Event)
|
|
class CLIEventTable(Struct, nocopy=True):
|
|
flags = Enum(CLIEventAttributes, UInt(16))
|
|
name = CLIStreamIndex(CLIStreamType.String)
|
|
type = TypeDefOrRef
|
|
|
|
|
|
@table_parser(CLITableType.PropertyMap)
|
|
class CLIPropertyMapTable(Struct, nocopy=True):
|
|
parent = CLITableIndex(CLITableType.TypeDef)
|
|
properties = CLITableRange(CLITableType.Property)
|
|
|
|
|
|
@table_parser(CLITableType.PropertyPointer)
|
|
class CLIPropertyPointerTable(Struct, nocopy=True):
|
|
property = CLITableIndex(CLITableType.Property)
|
|
|
|
|
|
class CLIPropertyAttributes(enum.Flag):
|
|
SpecialName = 0x0200
|
|
RTSpecialName = 0x0400
|
|
HasDefault = 0x1000
|
|
|
|
@table_parser(CLITableType.Property)
|
|
class CLIPropertyTable(Struct, nocopy=True):
|
|
flags = Enum(CLIPropertyAttributes, UInt(16))
|
|
name = CLIStreamIndex(CLIStreamType.String)
|
|
signature = CLIStreamIndex(CLIStreamType.Blob, CLISignature)
|
|
|
|
|
|
HasSemantics = CLICodedToken([CLITableType.Event, CLITableType.Property])
|
|
|
|
class CLIMethodSemanticsAttributes(enum.Enum):
|
|
Setter = 0x1
|
|
Getter = 0x2
|
|
Other = 0x4
|
|
AddOn = 0x8
|
|
RemoveOn = 0x10
|
|
Fire = 0x20
|
|
|
|
@table_parser(CLITableType.MethodSemantics)
|
|
class CLIMethodSemanticsTable(Struct, nocopy=True):
|
|
semantics = Enum(CLIMethodSemanticsAttributes, UInt(16))
|
|
method = CLITableIndex(CLITableType.MethodDef)
|
|
association = HasSemantics
|
|
|
|
|
|
MethodDefOrRef = CLICodedToken([
|
|
CLITableType.MethodDef, CLITableType.MemberRef
|
|
])
|
|
|
|
@table_parser(CLITableType.MethodImpl)
|
|
class CLIMethodImplTable(Struct, nocopy=True):
|
|
parent = CLITableIndex(CLITableType.TypeDef)
|
|
body = MethodDefOrRef
|
|
declaration = MethodDefOrRef
|
|
|
|
|
|
@table_parser(CLITableType.ModuleRef)
|
|
class CLIModuleRefTable(Struct, nocopy=True):
|
|
name = CLIStreamIndex(CLIStreamType.String)
|
|
|
|
|
|
MemberForwarded = CLICodedToken([CLITableType.Field, CLITableType.MethodDef])
|
|
|
|
class CLIVariance(enum.Enum):
|
|
No = 0
|
|
Covariant = 1
|
|
Contravariant = 2
|
|
|
|
class CLIConstraint(enum.Flag):
|
|
ReferenceTypeConstraint = 0x4
|
|
NotNullableValueTypeConstraint = 0x8
|
|
DefaultConstructorConstraint = 0x10
|
|
|
|
class CLIPInvokeAttributes(MultiEnum):
|
|
variance = (CLIVariance, 0b11)
|
|
constraint = (CLIConstraint, 0b11100)
|
|
|
|
@table_parser(CLITableType.ImplMap)
|
|
class CLIImplMapTable(Struct, nocopy=True):
|
|
flags = Enum(CLIPInvokeAttributes, UInt(16))
|
|
forwarded = MemberForwarded
|
|
name = CLIStreamIndex(CLIStreamType.String)
|
|
scope = CLITableIndex(CLITableType.ModuleRef)
|
|
|
|
|
|
@table_parser(CLITableType.FieldRVA)
|
|
class CLIFieldRVATable(Struct, nocopy=True):
|
|
rva = UInt(32)
|
|
field = CLITableIndex(CLITableType.Field)
|
|
|
|
|
|
TypeOrMethodDef = CLICodedToken([CLITableType.TypeDef, CLITableType.MethodDef])
|
|
|
|
class CLIGenericParamAttributes(MultiEnum):
|
|
variance = (CLIVariance, 0b11)
|
|
constraint = (CLIConstraint, 0b11100)
|
|
|
|
@table_parser(CLITableType.GenericParam)
|
|
class CLIGenericParamTable(Struct, nocopy=True):
|
|
index = UInt(16)
|
|
flags = Enum(CLIGenericParamAttributes, UInt(16))
|
|
owner = TypeOrMethodDef
|
|
name = CLIStreamIndex(CLIStreamType.String)
|
|
|
|
|
|
@table_parser(CLITableType.MethodSpec)
|
|
class CLIMethodSpecTable(Struct, nocopy=True):
|
|
parent = MethodDefOrRef
|
|
instantiation = CLIStreamIndex(CLIStreamType.Blob)
|
|
|
|
|
|
@table_parser(CLITableType.GenericParamConstraint)
|
|
class CLIGenericParamConstraintTable(Struct, nocopy=True):
|
|
owner = CLITableIndex(CLITableType.GenericParam)
|
|
constraint = TypeDefOrRef
|
|
|
|
|
|
HasFieldMarshal = CLICodedToken([CLITableType.Field, CLITableType.Param])
|
|
|
|
@table_parser(CLITableType.FieldMarshal)
|
|
class CLIFieldMarshalTable(Struct, nocopy=True):
|
|
parent = HasFieldMarshal
|
|
native_type = CLIStreamIndex(CLIStreamType.Blob, CLINativeSignature)
|
|
|
|
|
|
@table_parser(CLITableType.EncLog)
|
|
class CLIEncLogTable(Struct, nocopy=True):
|
|
token = UInt(32)
|
|
func_code = UInt(32)
|
|
|
|
|
|
@table_parser(CLITableType.EncMap)
|
|
class CLIEncMapTable(Struct, nocopy=True):
|
|
token = UInt(32)
|
|
|
|
|
|
class CLIFileAttributes(enum.Enum):
|
|
ContainsMetadata = 0
|
|
ContainsNoMetadata = 1
|
|
|
|
@table_parser(CLITableType.File)
|
|
class CLIFileTable(Struct, nocopy=True):
|
|
flags = Enum(CLIFileAttributes, UInt(32))
|
|
name = CLIStreamIndex(CLIStreamType.String)
|
|
hash = CLIStreamIndex(CLIStreamType.Blob)
|
|
|
|
|
|
@table_parser(CLITableType.ExportedType)
|
|
class CLIExportedTypeTable(Struct, nocopy=True):
|
|
flags = Enum(CLITypeAttributes, UInt(32))
|
|
type_id = UInt(32)
|
|
name = CLIStreamIndex(CLIStreamType.String)
|
|
namespace = CLIStreamIndex(CLIStreamType.String)
|
|
implementation = Implementation
|