示例#1
0
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
示例#2
0
 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)
示例#3
0
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_NUMBER
    # in file Lib/importlib/_bootstrap_external.py
    MAGIC = {
        # Python 1.x
        20121: ("1.5", 0x1050000),
        50428: ("1.6", 0x1060000),

        # 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),
        62151: ("2.6a0", 0x2070000),
        62161: ("2.6a1", 0x2070000),
        62171: ("2.7a0", 0x2070000),
        62181: ("2.7a0", 0x2070000),
        62191: ("2.7a0", 0x2070000),
        62201: ("2.7a0", 0x2070000),
        62211: ("2.7a0", 0x2070000),

        # 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),
        3061: ("3.0 (3061)", 0x3000000),
        3071: ("3.0 (3071)", 0x3000000),
        3081: ("3.0 (3081)", 0x3000000),
        3091: ("3.0 (3091)", 0x3000000),
        3101: ("3.0 (3101)", 0x3000000),
        3103: ("3.0 (3103)", 0x3000000),
        3111: ("3.0a4", 0x3000000),
        3131: ("3.0a5", 0x3000000),
        3141: ("3.1a0", 0x3010000),
        3151: ("3.1a0", 0x3010000),
        3160: ("3.2a0", 0x3020000),
        3170: ("3.2a1", 0x3020000),
        3180: ("3.2a2", 0x3020000),
        3190: ("Python 3.3a0", 0x3030000),
        3200: ("Python 3.3a0 ", 0x3030000),
        3210: ("Python 3.3a0 ", 0x3030000),
        3220: ("Python 3.3a1 ", 0x3030000),
        3230: ("Python 3.3a4 ", 0x3030000),
        3250: ("Python 3.4a1 ", 0x3040000),
        3260: ("Python 3.4a1 ", 0x3040000),
        3270: ("Python 3.4a1 ", 0x3040000),
        3280: ("Python 3.4a1 ", 0x3040000),
        3290: ("Python 3.4a4 ", 0x3040000),
        3300: ("Python 3.4a4 ", 0x3040000),
        3310: ("Python 3.4rc2", 0x3040000),
        3320: ("Python 3.5a0 ", 0x3050000),
        3330: ("Python 3.5b1 ", 0x3050000),
        3340: ("Python 3.5b2 ", 0x3050000),
        3350: ("Python 3.5b2 ", 0x3050000),
        3351: ("Python 3.5.2 ", 0x3050000),
        3360: ("Python 3.6a0 ", 0x3060000),
        3361: ("Python 3.6a0 ", 0x3060000),
        3370: ("Python 3.6a1 ", 0x3060000),
        3371: ("Python 3.6a1 ", 0x3060000),
        3372: ("Python 3.6a1 ", 0x3060000),
        3373: ("Python 3.6b1 ", 0x3060000),
        3375: ("Python 3.6b1 ", 0x3060000),
        3376: ("Python 3.6b1 ", 0x3060000),
        3377: ("Python 3.6b1 ", 0x3060000),
        3378: ("Python 3.6b2 ", 0x3060000),
        3379: ("Python 3.6rc1", 0x3060000),
        3390: ("Python 3.7a0 ", 0x3070000),
    }

    # 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.items())

    def validate(self):
        magic_number = self["magic_number"].value
        if magic_number not in self.MAGIC:
            return "Unknown magic number (%s)" % magic_number
        if self["magic_string"].value != "\r\n":
            return r"Wrong magic string (\r\n)"

        version = self.getVersion()
        if version >= 0x3030000 and self['magic_number'].value >= 3200:
            offset = 12
        else:
            offset = 8
        value = self.stream.readBits(offset * 8, 7, self.endian)
        if value != ord(b'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 UInt16(self, "magic_number", "Magic number")
        yield String(self,
                     "magic_string",
                     2,
                     r"Magic string \r\n",
                     charset="ASCII")
        yield TimestampUnix32(self, "timestamp", "Timestamp")
        version = self.getVersion()
        if version >= 0x3030000 and self['magic_number'].value >= 3200:
            yield UInt32(self, "filesize",
                         "Size of the Python source file (.py) modulo 2**32")
        yield Object(self, "content")
示例#4
0
 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)