1 changed files with 74 additions and 11 deletions
@ -1,17 +1,80 @@
@@ -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 |
||||
|
Loading…
Reference in new issue