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
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
|
|
|