import clr clr.AddReferenceByPartialName('System') from System.CodeDom import * from System.CodeDom.Compiler import CodeDomProvider, CodeGeneratorOptions from System.IO import StringWriter import System.String from Decoder import Decoder import struct def Opcode(OPCD, XO=0, branch=False): def sub(func): func.opcode = OPCD | (XO << 6) func.branch = branch return func return sub class Decompiler(object): def __init__(self): self.endian = '>' self.decoder = Decoder() self.handlers = {} for name in dir(self): attr = getattr(self, name) if hasattr(attr, 'opcode'): self.handlers[attr.opcode] = attr, attr.branch def decompile(self, addr, memory): method = CodeMemberMethod() method.Name = 'Decompiled' method.ReturnType = CodeTypeReference(System.String) method.Attributes = MemberAttributes.Public end = False while not end: try: inst, = struct.unpack(self.endian + 'L', memory[addr:addr+4]) except (IndexError, struct.error): break stmts, end = self.handle(addr, inst) for stmt in stmts: method.Statements.Add(stmt) addr += 4 provider = CodeDomProvider.CreateProvider('CSharp') options = CodeGeneratorOptions() options.BracingStyle = 'Block' writer = StringWriter() provider.GenerateCodeFromMember(method, writer, options) print writer.ToString() writer.Close() def handle(self, addr, inst): dec = self.decoder.decode(inst) if dec[0] in self.handlers: handler, branch = self.handlers[dec[0]] return handler(addr, *dec), branch else: raise DecompilerError('No handler for %r', dec) @Opcode(14) def addi(self, addr, OPCD, D, A, SIMM): yield CodeCommentStatement('addi r%i, r%i, 0x%04x' % (D, A, SIMM)) if __name__=='__main__': decompiler = Decompiler() decompiler.decompile(0, '\xde\xad\x39\x0e')