2018-06-20 22:28:52 +02:00
|
|
|
# -*- coding: utf8 -*-
|
|
|
|
|
|
|
|
|
|
# LibRay-PS3 - Libre Blu-Ray PS3 ISO Tool
|
|
|
|
|
# Copyright (C) 2018 Nichlas Severinsen
|
|
|
|
|
#
|
|
|
|
|
# This program is free software: you can redistribute it and/or modify
|
|
|
|
|
# it under the terms of the GNU General Public License as published by
|
|
|
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
# (at your option) any later version.
|
|
|
|
|
#
|
|
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
# GNU General Public License for more details.
|
|
|
|
|
#
|
|
|
|
|
# You should have received a copy of the GNU General Public License
|
|
|
|
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
|
|
2018-06-21 21:30:38 +02:00
|
|
|
import os
|
2018-06-21 22:02:47 +02:00
|
|
|
import sys
|
2018-06-21 21:30:38 +02:00
|
|
|
import gzip
|
2018-06-20 22:28:52 +02:00
|
|
|
|
|
|
|
|
ORDER = 'big'
|
2018-06-23 18:58:38 +02:00
|
|
|
IRD_ORDER = 'little'
|
2018-06-20 22:28:52 +02:00
|
|
|
SECTOR = 2048
|
2018-06-21 21:30:38 +02:00
|
|
|
|
|
|
|
|
def bytes_to_int(byte):
|
|
|
|
|
return int.from_bytes(byte, ORDER)
|
|
|
|
|
|
2018-06-23 18:58:38 +02:00
|
|
|
def ird_bytes_to_int(byte):
|
|
|
|
|
return int.from_bytes(byte, IRD_ORDER)
|
|
|
|
|
|
|
|
|
|
def read_seven_bit_encoded_int(fileobj):
|
|
|
|
|
# Read out an Int32 7 bits at a time. The high bit
|
|
|
|
|
# of the byte when on means to continue reading more bytes
|
|
|
|
|
count = 0
|
|
|
|
|
shift = 0
|
|
|
|
|
byte = -1
|
|
|
|
|
while (byte & 0x80) != 0 or byte == -1:
|
|
|
|
|
# Check for a corrupted stream. Read a max of 5 bytes.
|
|
|
|
|
if shift == (5 * 7):
|
|
|
|
|
raise ValueError
|
|
|
|
|
byte = ird_bytes_to_int(fileobj.read(1))
|
|
|
|
|
count |= (byte & 0x7F) << shift
|
|
|
|
|
shift += 7
|
|
|
|
|
print(byte, count, shift)
|
|
|
|
|
return count
|
|
|
|
|
|
|
|
|
|
|
2018-06-21 21:30:38 +02:00
|
|
|
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):
|
2018-06-23 18:58:38 +02:00
|
|
|
|
2018-06-21 21:30:38 +02:00
|
|
|
with open(filename, 'rb') as fileobj:
|
|
|
|
|
if self.is_compressed(fileobj):
|
|
|
|
|
self.uncompress(filename)
|
2018-06-23 18:58:38 +02:00
|
|
|
|
2018-06-21 21:30:38 +02:00
|
|
|
self.size = os.stat('ird').st_size
|
|
|
|
|
with open('ird', 'rb') as ird:
|
|
|
|
|
self.magic_string = ird.read(4)
|
2018-06-23 18:58:38 +02:00
|
|
|
self.version = ird_bytes_to_int(ird.read(1))
|
2018-06-21 21:30:38 +02:00
|
|
|
self.game_id = ird.read(9)
|
2018-06-23 18:58:38 +02:00
|
|
|
length = read_seven_bit_encoded_int(ird)
|
|
|
|
|
self.game_name = ird.read(length)
|
2018-06-21 21:30:38 +02:00
|
|
|
self.update_version = ird.read(4)
|
|
|
|
|
self.game_version = ird.read(5)
|
2018-06-23 18:58:38 +02:00
|
|
|
self.app_version = ird.read(5)
|
2018-06-21 21:30:38 +02:00
|
|
|
if self.version == 7:
|
|
|
|
|
self.identifier = ird.read(4)
|
2018-06-23 18:58:38 +02:00
|
|
|
if self.version < 9:
|
|
|
|
|
back = ird.tell()
|
|
|
|
|
length = read_seven_bit_encoded_int(ird)
|
|
|
|
|
if length:
|
|
|
|
|
self.header = ird.read(length)
|
|
|
|
|
else:
|
|
|
|
|
ird.seek(back)
|
|
|
|
|
back = ird.tell()
|
|
|
|
|
length = read_seven_bit_encoded_int(ird)
|
|
|
|
|
if length:
|
|
|
|
|
self.footer = ird.read(length)
|
|
|
|
|
else:
|
|
|
|
|
ird.seek(back)
|
|
|
|
|
self.region_count = ird_bytes_to_int(ird.read(1))
|
|
|
|
|
self.region_hash = []
|
|
|
|
|
for i in range(0, self.region_count):
|
|
|
|
|
self.region_hash.append(ird.read(16))
|
|
|
|
|
self.file_count = ird_bytes_to_int(ird.read(4))
|
|
|
|
|
print(vars(self) )
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return
|
|
|
|
|
sys.exit()
|
2018-06-21 22:02:47 +02:00
|
|
|
back = ird.tell()
|
|
|
|
|
prefix = bytes_to_int(ird.read(1))
|
|
|
|
|
length = prefix >> 1
|
|
|
|
|
if prefix & 0b00000001:
|
|
|
|
|
ird.seek(back)
|
2018-06-23 18:58:38 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2018-06-21 22:02:47 +02:00
|
|
|
|
|
|
|
|
self.header = ird.read(length)
|
|
|
|
|
back = ird.tell()
|
|
|
|
|
prefix = bytes_to_int(ird.read(1))
|
|
|
|
|
length = prefix >> 1
|
|
|
|
|
ird.seek(back)
|
|
|
|
|
self.footer = ird.read(length)
|
|
|
|
|
self.region_count
|
2018-06-21 21:30:38 +02:00
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
|
2018-06-21 22:02:47 +02:00
|
|
|
print(self.pic)
|
2018-06-21 21:30:38 +02:00
|
|
|
print(self.uid)
|
2018-06-21 22:02:47 +02:00
|
|
|
print(self.game_id)
|
2018-06-21 21:30:38 +02:00
|
|
|
|
|
|
|
|
if filename != 'ird':
|
2018-06-21 22:02:47 +02:00
|
|
|
os.remove('ird')
|
2018-06-21 21:30:38 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|