Microsoft Common Language Infrastructure (also known as .NET) metadata parser
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

80 lines
2.5 KiB

import sys
from dotnet.types import CLISignature
from dotnet.tables import CLITableType, CLIMethodCodeType
from dotnet.file import CLIFile
from dotnet.code import CILFlags
from dotnet.cil import parse as disassemble
def emit_bytes(b):
return '(' + ' '.join(hex(c)[2:] for c in b) + ')'
def emit_ident(e):
return e.name.lower() if e.name else ''
def emit_type(s):
return str(s)
def emit_flags(fs):
return ' '.join(emit_ident(f) for f in fs)
def emit_assembly(a):
flags = ' external' if a.external else ''
print('.assembly{} {}'.format(flags, a.name))
print('{')
print(' .ver {}:{}:{}:{}'.format(a.version_major, a.version_minor, a.build_number, a.rev_number))
if a.public_key:
print(' .publickeytoken = {}'.format(emit_bytes(a.public_key)))
elif not a.external:
print(' .hash algorithm 0x{:08X}'.format(a.hash_algo.value))
print('}')
def emit_field(f):
flags = [f.flags.access]
print(' .field {} {} \'{}\''.format(emit_flags(flags), emit_type(f.signature), f.name))
def emit_cil(c):
print(' .maxstack {}'.format(c.stack_size))
if c.vars:
print(' .locals{} ({})'.format(
' init' if c.attribs.flags & CILFlags.InitLocals else '',
', '.join(emit_type(t) for t in c.vars.signature.signature.vars)
))
for ins in disassemble(c.code):
print(' ' + str(ins))
def emit_method(m):
flags = [m.flags.access, m.flags.flags]
impl_flags = [m.impl_flags.code_type, m.impl_flags.managed]
ret_type = m.signature.signature.ret_type
param_types = m.signature.signature.params
print(' .method {} {} {}({}) {}'.format(
emit_flags(flags), emit_type(ret_type), m.name,
', '.join(emit_type(t) + ' ' + p.name for p, t in zip(m.params, param_types)),
emit_flags(impl_flags)
))
print(' {')
if m.impl_flags.code_type == CLIMethodCodeType.CIL:
emit_cil(m.code)
else:
print(' # Unimplemented: {}'.format(m.impl_flags.code_type.name))
print(' }')
def emit_class(c):
flags = [c.flags.visibility, c.flags.layout, c.flags.formatting]
print('.class {} {}'.format(emit_flags(flags), c.name))
print('{')
for f in c.fields:
emit_field(f)
for m in c.methods:
emit_method(m)
print('}')
file = CLIFile(sys.argv[1])
for a in file.referenced_assemblies:
emit_assembly(a)
emit_assembly(file.assembly)
for i, c in enumerate(file.classes):
emit_class(c)
if i >= 4:
break