rendered paste bodyfrom System.CodeDom import *from System.CodeDom.Compiler import CodeDomProvider, CodeGeneratorOptionsfrom System.IO import StringWriterimport System.String, System.Int16from Decoder import Decoderimport structARITH_ADD = CodeBinaryOperatorType.AddARITH_SUB = CodeBinaryOperatorType.SubtractARITH_MUL = CodeBinaryOperatorType.MultiplyARITH_DIV = CodeBinaryOperatorType.DivideARITH_XOR = '^'ARITH_LSL = '<<'ARITH_LSR = '>>'class DecompilerError(Exception): passclass Decompiler(object): def Opcode(OPCD, XO=0, branch=False): def sub(func): func.opcode = OPCD | (XO << 6) func.branch = branch return func return sub 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 addStatements(self, method, stmts): for stmt in stmts: if hasattr(stmt, 'next'): self.addStatements(method, stmt) else: method.Statements.Add(stmt) def decompile(self, addr, memory): self.addr = addr 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 self.addr += 4 stmts, end = self.handle(inst) self.addStatements(method, stmts) provider = CodeDomProvider.CreateProvider('CSharp') options = CodeGeneratorOptions() options.BracingStyle = 'Block' writer = StringWriter() provider.GenerateCodeFromMember(method, writer, options) print writer.ToString() writer.Close() def handle(self, inst): dec = self.decoder.decode(inst) if dec[0] in self.handlers: handler, branch = self.handlers[dec[0]] return handler(*dec), branch else: raise DecompilerError('No handler for %r', dec) def SIMM(self, SIMM): if SIMM & 0x8000: return -(0x10000 - SIMM) else: return SIMM def arithmetic(self, oper, D, A, B=None, IMM=None): D = CodeVariableReferenceExpression('r%i' % D) if isinstance(oper, CodeBinaryOperatorType): A = CodeVariableReferenceExpression('r%i' % A) if B != None: B = CodeVariableReferenceExpression('r%i' % B) elif IMM != None: B = CodePrimitiveExpression(System.Int16(IMM)) yield CodeAssignStatement( D, CodeBinaryOperatorExpression( A, oper, B ) ) else: if B != None: B = 'r%i' % B elif IMM != None: B = str(IMM) yield CodeAssignStatement( D, CodeSnippetExpression( '(r%i %s %s)' % ( A, oper, B ) ) ) # Arithmetic @Opcode(14) def addi(self, OPCD, D, A, SIMM): if A == 0: yield CodeAssignStatement( CodeVariableReferenceExpression('r%i' % D), CodePrimitiveExpression(System.Int16(self.SIMM(SIMM))) ) else: yield self.arithmetic( ARITH_ADD, D=D, A=A, IMM=self.SIMM(SIMM) ) @Opcode(26) def xori(self, OPCD, S, A, UIMM): yield self.arithmetic( ARITH_XOR, D=A, A=S, IMM=UIMM ) def branch(self, ) # Branches @Opcode(18) def bx(self, OPCD, LI, AA, LK): passif __name__=='__main__': decompiler = Decompiler() decompiler.decompile(0, '\xde\xad\x39\x0e\xba\xbe\x02\x4e\xde\xad\x29\xda')