""" t3Function.py """ import cStringIO, struct, t3DataHolder BCDICT = { "\x01": ("PUSH_0", ""), "\x02": ("PUSH_1", ""), "\x03": ("PUSHINT8", "b"), "\x04": ("PUSHINT", "i"), "\x05": ("PUSHSTR", "I"), "\x06": ("PUSHLST", "I"), "\x07": ("PUSHOBJ", "I"), "\x08": ("PUSHNIL", ""), "\x09": ("PUSHTRUE", ""), "\x0a": ("PUSHPROPID", "H"), "\x0b": ("PUSHFNPTR", "I"), "\x0c": ("PUSHSTRI", "H"), "\x0d": ("PUSHPARLST", "B"), "\x0e": ("MAKELSTPAR", ""), "\x0f": ("PUSHENUM", "i"), "\x20": ("NEG", ""), "\x21": ("BNOT", ""), "\x22": ("ADD", ""), "\x23": ("SUB", ""), "\x24": ("MUL", ""), "\x25": ("BAND", ""), "\x26": ("BOR", ""), "\x27": ("SHL", ""), "\x28": ("SHR", ""), "\x29": ("XOR", ""), "\x2a": ("DIV", ""), "\x2b": ("MOD", ""), "\x2c": ("NOT", ""), "\x2d": ("BOOLIZE", ""), "\x2e": ("INC", ""), "\x2f": ("DEC", ""), "\x40": ("EQ", ""), "\x41": ("NE", ""), "\x42": ("LT", ""), "\x43": ("LE", ""), "\x44": ("GT", ""), "\x45": ("GE", ""), "\x50": ("RETVAL", ""), "\x51": ("RETNIL", ""), "\x52": ("RETTRUE", ""), "\x54": ("RET", ""), "\x58": ("CALL", "BI"), "\x59": ("PTRCALL", "B"), "\x60": ("GETPROP", "H"), "\x61": ("CALLPROP", "BH"), "\x62": ("PTRCALLPROP", "B"), "\x63": ("GETPROPSELF", "H"), "\x64": ("CALLPROPSELF", "BH"), "\x65": ("PTRCALLPROPSELF", "B"), "\x66": ("OBJGETPROP", "IH"), "\x67": ("OBJCALLPROP", "BIH"), "\x68": ("GETPROPDATA", "H"), "\x69": ("PTRGETPROPDATA", ""), "\x6a": ("GETPROPLCL1", "BH"), "\x6b": ("CALLPROPLCL1", "BBH"), "\x6c": ("GETPROPR0", "H"), "\x6d": ("CALLPROPR0", "BH"), "\x72": ("INHERIT", "BH"), "\x73": ("PTRINHERIT", "B"), "\x74": ("EXPINHERIT", "BHI"), "\x75": ("PTREXPINHERIT", "BI"), "\x76": ("VARARGC", ""), "\x77": ("DELEGATE", "BH"), "\x78": ("PTRDELEGATE", "B"), "\x80": ("GETLCL1", "B"), "\x81": ("GETLCL2", "H"), "\x82": ("GETARG1", "B"), "\x83": ("GETARG2", "H"), "\x84": ("PUSHSELF", ""), "\x85": ("GETDBLCL", "HH"), "\x86": ("GETDBARG", "HH"), "\x87": ("GETARGC", ""), "\x88": ("DUP", ""), "\x89": ("DISC", ""), "\x8a": ("DISC1", "B"), "\x8b": ("GETR0", ""), "\x8c": ("GETDBARGC", "H"), "\x8d": ("SWAP", ""), "\x8e": ("PUSHCTXELE", "B"), "\x90": ("SWITCH", "h"), "\x91": ("JMP", "h"), "\x92": ("JT", "h"), "\x93": ("JF", "h"), "\x94": ("JE", "h"), "\x95": ("JNE", "h"), "\x96": ("JGT", "h"), "\x97": ("JGE", "h"), "\x98": ("JLT", "h"), "\x99": ("JLE", "h"), "\x9a": ("JST", "h"), "\x9b": ("JSF", "h"), "\x9c": ("LJSR", "h"), "\x9d": ("LRET", "h"), "\x9e": ("JNIL", "h"), "\x9f": ("JNOTNIL", "h"), "\xa0": ("JR0T", "h"), "\xa1": ("JR0F", "h"), "\xb0": ("SAY", "I"), "\xb1": ("BUILTIN_A", "BB"), "\xb2": ("BUILTIN_B", "BB"), "\xb3": ("BUILTIN_C", "BB"), "\xb4": ("BUILTIN_D", "BB"), "\xb5": ("BUILTIN1", "BBB"), "\xb6": ("BUILTIN2", "BHB"), "\xb7": ("CALLEXT", ""), "\xb8": ("THROW", ""), "\xb9": ("SAYVAL", ""), "\xba": ("INDEX", ""), "\xbb": ("IDXLCL1INT8", "BB"), "\xbc": ("IDXINT8", "B"), "\xc0": ("NEW1", "BB"), "\xc1": ("NEW2", "HH"), "\xc2": ("TRNEW1", "BB"), "\xc3": ("TRNEW2", "HH"), "\xd0": ("INCLCL", "H"), "\xd1": ("DECLCL", "H"), "\xd2": ("ADDILC1", "Bb"), "\xd3": ("ADDILC4", "Hi"), "\xd4": ("ADDTOLCL", "H"), "\xd5": ("SUBFROMLCL", "H"), "\xd6": ("ZEROLCL1", "B"), "\xd7": ("ZEROLCL2", "H"), "\xd8": ("NILLCL1", "B"), "\xd9": ("NILLCL2", "H"), "\xda": ("ONELCL1", "B"), "\xdb": ("ONELCL2", "H"), "\xe0": ("SETLCL1", "B"), "\xe1": ("SETLCL2", "H"), "\xe2": ("SETARG1", "B"), "\xe3": ("SETARG2", "H"), "\xe4": ("SETIND", ""), "\xe5": ("SETPROP", "H"), "\xe6": ("PTRSETPROP", ""), "\xe7": ("SETPROPSELF", "H"), "\xe8": ("OBJSETPROP", "IH"), "\xe9": ("SETDBLCL", "HH"), "\xea": ("SETDBARG", "HH"), "\xeb": ("SETSELF", ""), "\xec": ("LOADCTX", ""), "\xed": ("STORECTX", ""), "\xee": ("SETLCL1R0", "B"), "\xef": ("SETINDLCL1I8", "BB"), "\xf1": ("BP", ""), "\xf2": ("NOP", "")} class T3Function: def __init__(self, data, id): self.i_id = id self.datastream = cStringIO.StringIO(data) self.read_method_header() self.bytecode = self.read_bytecodes() self.exception_table = self.read_exception_table() self.debugging_records = self.read_debugging_records() self.datastream.close() def report(self): sl = [] sl.append("Function " + str(self.i_id) + ":\n\n") sl.append("takes variable arguments: " + str(self.b_variableArguments) + "\n") sl.append("parameter count: " + str(self.i_parameterCount) + "\n") sl.append("local variables: " + str(self.i_localVariableCount) + "\n") sl.append("maximum stack slots: " + str(self.i_maximumStackSlots) + "\n") sl.append("\n\n") sl.append(self.bytecode + "\n") return "".join(sl) def __str__(self): return "[function " + str(self.i_id) + "]" def __repr__(self): return self.__str__() def read_method_header(self): pcount = struct.unpack(" 0): self.b_variableArguments = True pcount = pcount &0x7f else: self.b_variableArguments = False self.i_parameterCount = pcount self.datastream.read(1) lvars = struct.unpack(" highestjump: highestjump = jumpto values.append((sval, offset)) # read in two more bytes for the default object defaultoffset = struct.unpack(" highestjump: highestjump = jumpto values.append(("default", defaultoffset)) elif mnemonic in ["JE", "JNE", "JGT", "JGE", "JLE", "JST", "JSF" "LJSR", "JNIL", "JNOTNIL", "JR0T", "JR0F", "JMP"]: relativept = (self.datastream.tell() - 2) - start jumpto = relativept + values[0] if jumpto >= highestjump: highestjump = jumpto elif mnemonic in ["RET", "RETNIL", "RETTRUE", "RETVAL", "THROW"]: if (self.datastream.tell() - start) > highestjump: end = True if values != (): if mnemonic == "SWITCH": outstr.append(" " + str(values[0])) padding = " " * 6 for value in values[1:]: outstr.append("\n" + padding + str(value[0]) + " : " + str(value[1])) else: outstr.append(" " + " ".join([str(value) for value in values])) bclist.append("".join(outstr)) if (self.i_offsetToExceptionTable == 0 and self.i_offsetToDebuggingRecords == 0): i = 0 while True: byte = self.datastream.read(1) if byte not in "\x50\x51\x52\xb8": self.datastream.seek(self.datastream.tell()-1) break elif byte != "": mnemonic, args = BCDICT[byte] out = [] out.append(str((self.datastream.tell() - start) - 1).zfill(3) + " ") out.append(mnemonic) bclist.append("".join(out)) else: break return "\n".join(bclist) def read_exception_table(self): table = [] if self.i_offsetToExceptionTable == 0: return [] self.datastream.seek(self.i_offsetToExceptionTable) count = struct.unpack("