All pastes #835334 Raw Edit

Anonymous

public python v1 · immutable
#835334 ·published 2007-12-28 20:39 UTC
rendered paste body
from System.CodeDom import *from System.CodeDom.Compiler import CodeDomProvider, CodeGeneratorOptionsfrom System.IO import StringWriterimport System.String, System.Int16from Struct import Structclass DecoderError(Exception):	passCS = 0x2EDS = 0x3EES = 0x26FS = 0x64GS = 0x65SS = 0x36OPSIZE = 0x66ADSIZE = 0x67LOCK = 0xF0REPNE = 0xF2REP = 0xF3B = 1V = 2Z = 3ARITH_ADD = CodeBinaryOperatorType.AddARITH_SUB = CodeBinaryOperatorType.SubtractARITH_MUL = CodeBinaryOperatorType.MultiplyARITH_DIV = CodeBinaryOperatorType.DivideARITH_AND = CodeBinaryOperatorType.BitwiseAndARITH_OR  = CodeBinaryOperatorType.BitwiseOrARITH_XOR = '^'ARITH_LSL = '<<'ARITH_LSR = '>>'AX = CodeVariableReferenceExpression('ax')CX = CodeVariableReferenceExpression('cx')DX = CodeVariableReferenceExpression('dx')BX = CodeVariableReferenceExpression('bx')SP = CodeVariableReferenceExpression('sp')BP = CodeVariableReferenceExpression('bp')SI = CodeVariableReferenceExpression('si')DI = CodeVariableReferenceExpression('di')regs = AX, CX, DX, BX, SP, BP, SI, DIclass Decompiler(object):	def __init__(self):		self.provider = CodeDomProvider.CreateProvider('CSharp')		self.options = CodeGeneratorOptions()		self.options.BracingStyle = 'Block'				self.forms = {			'E' : (True, self.formE),			'G' : (True, self.formG),			'I' : (False, self.formI),		}		self.sizes = {			'b' : B,			'v' : V,			'z' : Z,		}				self.Mod00 = (			self.memAccess(CodeBinaryOperatorExpression(BX, CodeBinaryOperatorType.Add, SI)),			self.memAccess(CodeBinaryOperatorExpression(BX, CodeBinaryOperatorType.Add, DI)),			self.memAccess(CodeBinaryOperatorExpression(BP, CodeBinaryOperatorType.Add, SI)),			self.memAccess(CodeBinaryOperatorExpression(BP, CodeBinaryOperatorType.Add, DI)),			self.memAccess(SI),			self.memAccess(DI),			None,			self.memAccess(BX)		)		self.Mod01_10 = (			CodeBinaryOperatorExpression(BX, CodeBinaryOperatorType.Add, SI),			CodeBinaryOperatorExpression(BX, CodeBinaryOperatorType.Add, DI),			CodeBinaryOperatorExpression(BP, CodeBinaryOperatorType.Add, SI),			CodeBinaryOperatorExpression(BP, CodeBinaryOperatorType.Add, DI),			SI,			DI,			BP,			BX		)				add = lambda A, B: self.arith(ARITH_ADD, A, B)		sub = lambda A, B: self.arith(ARITH_SUB, A, B)		mul = lambda A, B: self.arith(ARITH_MUL, A, B)		div = lambda A, B: self.arith(ARITH_DIV, A, B)		and_= lambda A, B: self.arith(ARITH_AND, A, B)		or_ = lambda A, B: self.arith(ARITH_OR , A, B)		xor = lambda A, B: self.arith(ARITH_XOR, A, B)		lsl = lambda A, B: self.arith(ARITH_LSL, A, B)		lsr = lambda A, B: self.arith(ARITH_LSR, A, B)		move = CodeAssignStatement				group1 = (			lambda D, S: move(D, add(D, S)),			lambda D, S: move(D, or_(D, S)),			lambda D, S: move(D, adc(D, S)),			lambda D, S: move(D, sbb(D, S)),			lambda D, S: move(D, and_(D, S)),			lambda D, S: move(D, sub(D, S)),			lambda D, S: move(D, xor(D, S)),			lambda D, S: move(D, cmp_(D, S)),		)				self.opcodes = {			0x03 : (self.form('Gv,Ev'), lambda D, S: move(D, add(D, S)), False, False),			0x33 : (self.form('Gv,Ev'), lambda D, S: move(D, xor(D, S)), False, False),			0x80 : (self.form('Eb,Ib'), lambda (mod, reg, rm), D, S: group1[reg](D, S), False, True),			0x81 : (self.form('Eb,Ib'), lambda (mod, reg, rm), D, S: group1[reg](D, S), False, True),			0x82 : (self.form('Ev,Iz'), lambda (mod, reg, rm), D, S: group1[reg](D, S), False, True),			0x83 : (self.form('Ev,Ib'), lambda (mod, reg, rm), D, S: group1[reg](D, S), False, True),			0x89 : (self.form('Ev,Gv'), lambda D, S: move(D, S), False, False),		}		def memAccess(self, expr):		return CodeArrayIndexerExpression(			CodeVariableReferenceExpression('Memory'),			expr		)		def formE(self, size, code, first, off, prefixes, (mod, reg, rm)):		if mod == 0:			ret = self.Mod00[rm]			if ret == None:				return off + 2, self.memAccess(CodePrimitiveExpression(Struct.uint16(code[off:off+2])))			return off, ret		elif mod == 1:			ret = self.Mod01_10			return off + 1, self.memAccess(				CodeBinaryOperatorExpression(					ret, 					CodeBinaryOperatorType.Add, 					CodePrimitiveExpression(ord(code[off]))				)			)		elif mod == 2:			ret = self.Mod01_10			return off + 2, self.memAccess(				CodeBinaryOperatorExpression(					ret, 					CodeBinaryOperatorType.Add, 					CodePrimitiveExpression(Struct.uint16(code[off:off+2]))				)			)		else:			return off, regs[rm]		def formG(self, size, code, first, off, prefixes, (mod, reg, rm)):		return off, regs[reg]		def formI(self, size, code, first, off, prefixes):		if size == B:			return off+1, CodePrimitiveExpression(ord(code[off]))		elif size == Z:			return off+2, CodePrimitiveExpression(Struct.uint16(code[off:off+2]))	def compileExpr(self, expr):		writer = StringWriter()		self.provider.GenerateCodeFromExpression(expr, writer, self.options)		ret = writer.ToString()		writer.Close()		return ret		def arith(self, op, A, B):		if isinstance(op, CodeBinaryOperatorType):			return CodeBinaryOperatorExpression(				A,				op,				B			)		else:			return CodeSnippetExpression(					'(%s %s %s)' % (						self.compileExpr(A),						op,						self.compileExpr(B)					)				)	def branch(L, C=None, cond=None, hintTaken=False):		pass		def comp(op, A, B):		pass		def form(self, formstr):		outform = []		for opc in formstr.split(','):			outform.append((self.forms[opc[0]], self.sizes[opc[1]]))		return tuple(outform)		def decode(self, code, off):		prefixes = []		c = ord(code[off])		off += 1		while c in (CS, DS, ES, FS, GS, SS, OPSIZE, ADSIZE, LOCK, REPNE, REP):			prefixes.append(c)			c = ord(code[off])			off += 1				if c in self.opcodes:			opcd = self.opcodes[c]		else:			c = (c << 8) | ord(code[off])			off += 1						if c in self.opcodes:				opcd = self.opcodes[c]			else:				c = (c << 8) | ord(code[off])				off += 1								if c in self.opcodes:					opcd = self.opcodes[c]				else:					raise DecoderError('Unknown opcode: %06x (may not be three bytes)' % c)				first = off		modrm = None				ops = []		forms, func, branch, instModrm = opcd		for form in forms:			(hasModrm, form), size = form			if hasModrm:				modrm = ord(code[first])				modrm = modrm >> 6, (modrm >> 3) & 7, modrm & 7				off += 1				break		for form in forms:			(hasModrm, form), size = form			if hasModrm:				off, stmt = form(size, code, first, off, prefixes, modrm)			else:				off, stmt = form(size, code, first, off, prefixes)			ops.append(stmt)				if instModrm:			return func(modrm, *ops), off, branch		else:			return func(*ops), off, branch		def decompile(self, code, off):		method = CodeMemberMethod()		method.Name = 'Decompiled'		method.ReturnType = CodeTypeReference(System.String)		method.Attributes = MemberAttributes.Public				branch = False		while not branch and len(code) > off:			stmt, off, branch = self.decode(code, off)			method.Statements.Add(stmt)				writer = StringWriter()		self.provider.GenerateCodeFromMember(method, writer, self.options)		print writer.ToString()		writer.Close()if __name__=='__main__':	decomp = Decompiler()	decomp.decompile('\x33\xC9\x33\xD2\x03\xD0\x89\x1E\xBE\x1E\x83\xC3\x0F', 0)