Gfy

missing_RAR.py

Gfy
Mar 7th, 2012
99
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3.  
  4. import zlib
  5. import struct
  6.  
  7. # !Referenced file not found:
  8. #   \Modern.Family.S02E02.1080p.BluRay.X264-7SinS\
  9. #   7sins-modern.family.s02e02.1080p.x264.r00
  10.  
  11. path = ""
  12. full = path + "7sins-modern.family.s02e02.1080p.x264.mkv"
  13. part = path + "7sins-modern.family.s02e02.1080p.x264.bin"
  14. todo = path + "7sins-modern.family.s02e02.1080p.x264.r00"
  15. filenb = 1 # r00
  16.  
  17. amount = 99999882 # amount of data stored in one volume
  18. start = amount * filenb
  19. end = start + amount
  20. marker = "526172211a0700"
  21. archive = "b2ef7301000d00000000000000"
  22. fileh = ("34ef74c3904e008ae0f5052ce73d5d021e34f07b7054273f1430290020000000"
  23.          "3773696e732d6d6f6465726e2e66616d696c792e7330326530322e3130383070"
  24.          "2e783236342e6d6b7600f092c340")
  25. arend = "75577b0f40140039e39c7a000000000000000000"
  26.  
  27. def extract_part(stored_file, output_file):
  28.     with open(stored_file, "rb") as af:
  29.         af.seek(start)
  30.         with open(output_file, "wb") as data:
  31.             data.write(af.read(amount))
  32.  
  33. def calc_crc(new_data, previous_crc=None):  
  34.     """calculate the crc needed in the header from the file/RR
  35.     previous_volume: not used: not a running crc!"""
  36.     # we only look at the stored data in the current file
  37.     if previous_crc:
  38.         crc = zlib.crc32(new_data, previous_crc) & 0xFFFFFFFF
  39.     else:
  40.         crc = zlib.crc32(new_data) & 0xFFFFFFFF
  41.     return crc
  42.  
  43. def fix_archive_flags(header, first_volume=False):
  44.     """ necessary because we start from .rar or need .rar
  45.     first_volume is true if we need to create the .rar file """
  46.     (flags, ) = struct.unpack("<H", header[3:5])
  47.     if first_volume and not flags & 0x0100:
  48.         flags += 0x0100 # fist volume flag
  49.     elif not first_volume and flags & 0x0100: # the flag is actually set
  50.         flags -= 0x0100
  51.     fixed = header[:3] + struct.pack("<H", flags) + header[5:]
  52.     header_crc = zlib.crc32(fixed[2:]) & 0xFFFF
  53.     return struct.pack("<H", header_crc) + fixed[2:]
  54.  
  55. def fix_file_flags(header, first_volume=False):
  56.     """ necessary because we start from .rar or need .rar
  57.     first_volume is true if we need to create the .rar file """
  58.     (flags, ) = struct.unpack("<H", header[3:5])
  59.     if first_volume and flags & 0x0001:
  60.         flags -= 0x0001 # file continued from previous volume
  61.     elif not first_volume and not flags & 0x0001:
  62.         flags += 0x0001
  63.     fixed = header[:3] + struct.pack("<H", flags) + header[5:]
  64.     header_crc = zlib.crc32(fixed[2:]) & 0xFFFF
  65.     return struct.pack("<H", header_crc) + fixed[2:]
  66.  
  67. def fix_file_header(file_header, part_crc):
  68.     """ fix the headers before the data """
  69.     before = file_header[:7+9]
  70.     after = file_header[7+9+4:]
  71.     fixed_crc_header = before + struct.pack("<I", part_crc) + after
  72.     header_crc = zlib.crc32(fixed_crc_header[2:]) & 0xFFFF
  73.     fixed_crc_header = struct.pack("<H", header_crc) + fixed_crc_header[2:]
  74.     return fixed_crc_header
  75.        
  76. def fix_end_header(end_header, crc_all, file_number):
  77.     before = end_header[:7]
  78.     after = end_header[7+4+2:]
  79.    
  80.     # change 12 to the next volume
  81.     fixedh = (before + struct.pack("<I", crc_all) +
  82.               struct.pack("<H", file_number) + after)
  83.     header_crc = zlib.crc32(fixedh[2:]) & 0xFFFF
  84.     return struct.pack("<H", header_crc) + fixedh[2:]
  85.  
  86. marker = marker.decode('hex')
  87. archive = archive.decode('hex')
  88. fileh = fileh.decode('hex')
  89. arend = arend.decode('hex')
  90.  
  91. print("Grabbing data from extracted file.")
  92. extract_part(full, part)
  93.  
  94. print("Calculating CRC file data.")
  95. with open(part, "rb") as data:
  96.     part_crc = calc_crc(data.read())
  97.  
  98. print("Fixing flags.")
  99. archive = fix_archive_flags(archive)
  100. fileh = fix_file_flags(fileh)
  101.  
  102. print("Fixing file header.")
  103. fileh = fix_file_header(fileh, part_crc)
  104.  
  105. print("Calculating CRC complete RAR volume.")
  106. # everything except the last 20 bytes
  107. start = marker + archive + fileh
  108. with open(part, "rb") as fh:
  109.     crc_all = calc_crc(fh.read(), calc_crc(start))
  110.  
  111. print("Fixing archive end header.")
  112. arend = fix_end_header(arend, crc_all, filenb)
  113.  
  114. print("Creating %s." % todo)
  115. with open(todo, "wb") as fh:
  116.     fh.write(start)
  117.     with open(part, "rb") as fpart:
  118.         fh.write(fpart.read())
  119.     fh.write(arend)
  120.    
  121. print("Done!")
RAW Paste Data