change __main__ to simple WIP text CIL emitter

This commit is contained in:
Shiz 2020-06-14 17:07:52 +02:00
parent a05727c3a1
commit 6eb2e07dd3
1 changed files with 74 additions and 11 deletions

View File

@ -1,17 +1,80 @@
import sys
from dotnet.types import CLISignature
from dotnet.tables import CLITableType
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])
print(f'Entrypoint: {file.entrypoint.name}')
for cls in file.get_table(CLITableType.TypeDef):
print('---')
print(f'Class: {cls.name}')
print('Fields:')
for f in cls.fields:
print(f'- {f.name}: {f.signature}')
print('Methods:')
for m in cls.methods:
print(f'- {m.name}: {m.signature}')
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