From 6eb2e07dd34f4def0d2c3cb70e15b4104b4ac51c Mon Sep 17 00:00:00 2001 From: Shiz Date: Sun, 14 Jun 2020 17:07:52 +0200 Subject: [PATCH] change __main__ to simple WIP text CIL emitter --- dotnet/__main__.py | 85 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 74 insertions(+), 11 deletions(-) diff --git a/dotnet/__main__.py b/dotnet/__main__.py index a1414b5..0bdf982 100644 --- a/dotnet/__main__.py +++ b/dotnet/__main__.py @@ -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