def read(self): self._file_contents = open(self._file_name, 'rb') self._user_data = UserData(self._file_contents) if not self._user_data.read(): return False print self._user_data self._archive_header = ArchiveHeader(self._file_contents, self._user_data) if not self._archive_header.read(): return False print self._archive_header self._block_table = BlockTable(self._file_contents, self._archive_header, self) self._block_table.read() print self._block_table
class ReplayReader(object): """Takes responsibility for reading the entire replay. Also implements some general use algorithms. """ def __init__(self, file_name): self._file_name = file_name self._user_data = None self._archive_header = None self._block_table = None self._file_contents = None self._crypt_table = range(0x500) self.create_crypt_table() def read(self): self._file_contents = open(self._file_name, 'rb') self._user_data = UserData(self._file_contents) if not self._user_data.read(): return False print self._user_data self._archive_header = ArchiveHeader(self._file_contents, self._user_data) if not self._archive_header.read(): return False print self._archive_header self._block_table = BlockTable(self._file_contents, self._archive_header, self) self._block_table.read() print self._block_table def create_crypt_table(self): seed = 0x00100001 for index1 in range(0x100): index2 = index1 for i in range(5): seed = (seed * 125 + 3) % 0x2AAAAB temp1 = (seed & 0xFFFF) << 0x10 seed = (seed * 125 + 3) % 0x2AAAAB temp2 = seed & 0xFFFF self._crypt_table[index2] = (temp1 | temp2) index2 += 0x100 def decrypt(self, data_block, length, key): """in place, length is in bytes, key is an int""" seed = 0xEEEEEEEE # round to int32's # If the data isn't a multiple of int32s, then the remaining bytes will # not get decrypted. length >>= 2 data_block_index = 0 accumulator = StringIO.StringIO() while(length > 0): length -= 1 seed += self._crypt_table[0x400 + (key & 0xFF)] ch = unpack('=I', data_block[data_block_index:data_block_index + 4])[0] ^ ((key + seed) & 0xFFFFFFFF) key = ((((~key << 0x15) & 0xFFFFFFFF) + 0x11111111) & 0xFFFFFFFF) | (key >> 0x0B) seed = (ch + seed + (seed << 5) + 3) & 0xFFFFFFFF accumulator.write(pack("=I", ch)) data_block_index += 4 return accumulator.getvalue() def hash(self, name, hash_type): seed1 = 0x7FED7FED seed2 = 0xEEEEEEEE for ch in name: ch = ord(ch.upper()) seed1 = self._crypt_table[(hash_type << 8) + ch] ^ (seed1 + seed2) & 0xFFFFFFFF seed2 = ch + seed1 + seed2 + (seed2 << 5) + 3 & 0xFFFFFFFF return seed1