From 9d75699178b86f57eec172ebd0e925d1590be220 Mon Sep 17 00:00:00 2001 From: Nichlas Severinsen Date: Thu, 21 Jun 2018 21:30:38 +0200 Subject: [PATCH] Struggling to decrypt --- .gitignore | 1 + LibRay-PS3/core.py | 55 ++++++++++++++++++++++++ LibRay-PS3/libray-ps3.py | 93 +++++++++++++++++++++++++++++++++++----- 3 files changed, 139 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index 303ed70..5b55e56 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ *.iso *.ird ird +region_* # Byte-compiled / optimized / DLL files __pycache__/ diff --git a/LibRay-PS3/core.py b/LibRay-PS3/core.py index 8f5bd91..66ba7fd 100644 --- a/LibRay-PS3/core.py +++ b/LibRay-PS3/core.py @@ -16,6 +16,61 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +import os +import gzip ORDER = 'big' SECTOR = 2048 + +def bytes_to_int(byte): + return int.from_bytes(byte, ORDER) + +class IRD: + + def is_compressed(self, fileobj): + fileobj.seek(0) + return fileobj.read(4) != b"3IRD" + + def uncompress(self, filename): + with gzip.open(filename, 'rb') as gzfile: + with open('ird', 'wb') as outfile: + outfile.write(gzfile.read()) + + def __init__(self, filename): + with open(filename, 'rb') as fileobj: + if self.is_compressed(fileobj): + self.uncompress(filename) + + self.size = os.stat('ird').st_size + with open('ird', 'rb') as ird: + self.magic_string = ird.read(4) + self.version = bytes_to_int(ird.read(1)) + self.game_id = ird.read(9) + self.game_name = ird.read(12) + self.update_version = ird.read(4) + self.game_version = ird.read(5) + if self.version == 7: + self.identifier = ird.read(4) + self.header = ird.read(SECTOR*3) + self.footer = ird.read(SECTOR) + self.region_count = ird.read(1) + + print(self.game_name, self.update_version, self.game_version, self.region_count) + + ird.seek(self.size - (2 + 115 + 16 + 16)) + if self.version >= 9: + self.pic = ird.read(115) + self.data_one = ird.read(16) + print(self.data_one.hex()) + self.data_two = ird.read(16) + if self.version < 9: + self.pic = ird.read(115) + self.uid = ird.read(2) + + print(self.uid) + + if filename != 'ird': + os.rm('ird') + + + diff --git a/LibRay-PS3/libray-ps3.py b/LibRay-PS3/libray-ps3.py index 267e7a6..2cfc7ab 100644 --- a/LibRay-PS3/libray-ps3.py +++ b/LibRay-PS3/libray-ps3.py @@ -22,13 +22,90 @@ import os import sys import core import struct +import shutil from Crypto.Cipher import AES +def bytes_to_int(byte): + return int.from_bytes(byte, core.ORDER) + +def int_to_hexstr(integer): + return '{:02x}'.format(integer) + +def int_to_bytes(integer): + return bytes(bytearray.fromhex(int_to_hexstr(integer))) + +def bprint(byte): + byteint = bytes_to_int(byte) + print(byte, '\t->', byteint, '\t->', byteint*8, '\t->', byteint*2048 ) + if __name__ == '__main__': - print(os.path.getsize(sys.argv[1])) - size = os.stat(sys.argv[1]) #.st_size.to_bytes(2, core.ORDER) - print(size) + + #core.IRD('ird.ird') + + #sys.exit() + + bprint(b'\x00\x00\x00\x00') + bprint(b'\x00\x00\x0c\xbf') + bprint(b'\x00\x00\x00q\xc2') + bprint(b'\x00\x00s\xc2\x7f') + bprint(b'\x00\x00s\xc2\x80') + + data = bytes(bytearray.fromhex("c9c1ec71205c2a6e8adc19795f9bfbd8")) + key = bytes(bytearray.fromhex("380bcf0b53455b3c7817ab4fa3ba90ed")) + iv = bytes(bytearray.fromhex("69474772af6fdab342743aefaa186287")) + + cipher = AES.new(key, AES.MODE_CBC, iv) + disc_key = cipher.encrypt(data) + + regions = [ + {'start': 0, 'end': 6682624, 'enc': False}, + {'start': 6682624, 'end': 59641856, 'enc': True}, + {'start': 59641856, 'end': 15537010688, 'enc': False}, + # There's also a last sector between 15537010688 and 15537012736, but seems like it's not used + ] + + files = [] + with open(sys.argv[1], 'rb') as iso: + for i, region in enumerate(regions): + files.append('region_' + str(i)) + with open('region_' + str(i), 'wb') as output: + iso.seek(region['start']) + + if not region['enc']: + while iso.tell() < region['end']: + data = iso.read(core.SECTOR) + output.write(data) + continue + else: + while iso.tell() < region['end']: + data = iso.read(core.SECTOR) + num = iso.tell() + iv = ['' for i in range(0,16)] + for j in range(0,16): + iv[16 - j - 1] = hex(ord(struct.pack("B", num & 0xFF))).replace('0x','') + num >>= 8 + + iv = "".join(iv)[-16:] + #print(iv) + + cipher = AES.new(disc_key, AES.MODE_CBC, iv) + output.write(cipher.decrypt(data)) + print(iso.tell()) + + + with open('output.iso', 'wb') as iso: + for f in files: + with open(f, 'rb') as fd: + shutil.copyfileobj(fd, iso, 1024*1024*10) + + sys.exit() + + size = os.stat(sys.argv[1]).st_size + size_hex = bytes(bytearray.fromhex(hex(int(size / 2048)).replace('0x','').zfill(16))) + + print(size, size_hex) + with open(sys.argv[1], 'rb') as iso: sector1 = iso.read(core.SECTOR) num_unenc_sectors = int.from_bytes(sector1[0:4], core.ORDER) @@ -40,17 +117,12 @@ if __name__ == '__main__': regions.append({'start': sector1[8+4*i:12+4*i], 'end': sector1[12+4*i:16+4*i], 'enc': encrypted}) encrypted = not encrypted - regions.append({'start': regions[-1]['end'], 'end': size, 'enc': True}) - + regions.append({'start': regions[-1]['end'], 'end': size_hex, 'enc': True}) + print(regions) # data1 from ird: 44 4901 0800 0020 0042 444f 0111 0101 00 # TODO: import .ird (which can either be plaintext starting with 3IRD or .gz) - data = bytes(bytearray.fromhex("444901080000200042444f0111010100")) - key = bytes(bytearray.fromhex("380bcf0b53455b3c7817ab4fa3ba90ed")) - iv = bytes(bytearray.fromhex("69474772af6fdab342743aefaa186287")) - cipher = AES.new(key, AES.MODE_CBC, iv) - disc_key = cipher.encrypt(data) print(disc_key) with open('output.iso', 'wb') as output: @@ -64,6 +136,7 @@ if __name__ == '__main__': print('end: ', end) print('size: ', end - start - 1) if region['enc']: + num = end print(num) iv = ['' for i in range(0,16)]