def createMpegAudioMagic(): # ID3v1 magic magics = [("TAG", 0)] # ID3v2 magics for ver_major in ID3v2.VALID_MAJOR_VERSIONS: magic = "ID3%c\x00" % ver_major magics.append( (magic,0) ) # MPEG frame magic # TODO: Use longer magic: 32 bits instead of 16 bits SYNC_BITS = 2047 for version in Frame.VERSION_NAME.iterkeys(): for layer in Frame.LAYER_NAME.iterkeys(): for crc16 in (0, 1): magic = (SYNC_BITS << 5) | (version << 3) | (layer << 1) | crc16 magic = long2raw(magic, BIG_ENDIAN, 2) magics.append( (magic, 0) ) return magics
def createMpegAudioMagic(): # ID3v1 magic magics = [("TAG", 0)] # ID3v2 magics for ver_major in ID3v2.VALID_MAJOR_VERSIONS: magic = "ID3%c\x00" % ver_major magics.append((magic, 0)) # MPEG frame magic # TODO: Use longer magic: 32 bits instead of 16 bits SYNC_BITS = 2047 for version in Frame.VERSION_NAME.iterkeys(): for layer in Frame.LAYER_NAME.iterkeys(): for crc16 in (0, 1): magic = (SYNC_BITS << 5) | (version << 3) | ( layer << 1) | crc16 magic = long2raw(magic, BIG_ENDIAN, 2) magics.append((magic, 0)) return magics
def writeInteger(self, value, signed, size_byte, endian): if signed: value += 1 << (size_byte * 8 - 1) raw = long2raw(value, endian, size_byte) self.writeBytes(raw)
def writeInteger(self, value, signed, size_byte, endian): if signed: value += 1 << (size_byte*8 - 1) raw = long2raw(value, endian, size_byte) self.writeBytes(raw)
class PythonCompiledFile(Parser): PARSER_TAGS = { "id": "python", "category": "program", "file_ext": ("pyc", "pyo"), "min_size": 9 * 8, "description": "Compiled Python script (.pyc/.pyo files)" } endian = LITTLE_ENDIAN # Dictionnary which associate the pyc signature (32-bit integer) # to a Python version string (eg. "m\xf2\r\n" => "Python 2.4b1"). # This list comes from CPython source code, see "MAGIC" # and "pyc_magic" in file Python/import.c MAGIC = { # Python 1.x 20121: ("1.5", 0x1050000), # Python 2.x 50823: ("2.0", 0x2000000), 60202: ("2.1", 0x2010000), 60717: ("2.2", 0x2020000), 62011: ("2.3a0", 0x2030000), 62021: ("2.3a0", 0x2030000), 62041: ("2.4a0", 0x2040000), 62051: ("2.4a3", 0x2040000), 62061: ("2.4b1", 0x2040000), 62071: ("2.5a0", 0x2050000), 62081: ("2.5a0 (ast-branch)", 0x2050000), 62091: ("2.5a0 (with)", 0x2050000), 62092: ("2.5a0 (WITH_CLEANUP opcode)", 0x2050000), 62101: ("2.5b3", 0x2050000), 62111: ("2.5b3", 0x2050000), 62121: ("2.5c1", 0x2050000), 62131: ("2.5c2", 0x2050000), # Python 3.x 3000: ("3.0 (3000)", 0x3000000), 3010: ("3.0 (3010)", 0x3000000), 3020: ("3.0 (3020)", 0x3000000), 3030: ("3.0 (3030)", 0x3000000), 3040: ("3.0 (3040)", 0x3000000), 3050: ("3.0 (3050)", 0x3000000), 3060: ("3.0 (3060)", 0x3000000), 3070: ("3.0 (3070)", 0x3000000), 3080: ("3.0 (3080)", 0x3000000), 3090: ("3.0 (3090)", 0x3000000), 3100: ("3.0 (3100)", 0x3000000), 3102: ("3.0 (3102)", 0x3000000), 3110: ("3.0a4", 0x3000000), 3130: ("3.0a5", 0x3000000), 3131: ("3.0a5 unicode", 0x3000000), } # Dictionnary which associate the pyc signature (4-byte long string) # to a Python version string (eg. "m\xf2\r\n" => "2.4b1") STR_MAGIC = dict( \ (long2raw(magic | (ord('\r')<<16) | (ord('\n')<<24), LITTLE_ENDIAN), value[0]) \ for magic, value in MAGIC.iteritems()) def validate(self): signature = self.stream.readBits(0, 16, self.endian) if signature not in self.MAGIC: return "Unknown version (%s)" % signature if self.stream.readBytes(2 * 8, 2) != "\r\n": return r"Wrong signature (\r\n)" if self.stream.readBytes(8 * 8, 1) != 'c': return "First object bytecode is not code" return True def getVersion(self): if not hasattr(self, "version"): signature = self.stream.readBits(0, 16, self.endian) self.version = self.MAGIC[signature][1] return self.version def createFields(self): yield Enum( Bytes(self, "signature", 4, "Python file signature and version"), self.STR_MAGIC) yield TimestampUnix32(self, "timestamp", "Timestamp") yield Object(self, "content")