Some cleaning up, changelog
This commit is contained in:
parent
cee1c05820
commit
81a43952a8
6 changed files with 77 additions and 25 deletions
|
|
@ -18,6 +18,7 @@
|
|||
# You should have received a copy of the GNU General Public License
|
||||
# along with libray. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
import os
|
||||
import sys
|
||||
import shutil
|
||||
|
|
@ -38,12 +39,15 @@ GET_IRD_NET_LOC = 'http://jonnysp.bplaced.net/ird/'
|
|||
|
||||
# Utility functions
|
||||
|
||||
def to_int(data, order='big'):
|
||||
|
||||
def to_int(data, byteorder='big'):
|
||||
"""Convert bytes to integer"""
|
||||
if isinstance(data, bytes):
|
||||
return int.from_bytes(data, order)
|
||||
return int.from_bytes(data, byteorder)
|
||||
|
||||
|
||||
def to_bytes(data):
|
||||
"""Convert a string of HEX to bytes"""
|
||||
if isinstance(data, str):
|
||||
return bytes(bytearray.fromhex(data))
|
||||
|
||||
|
|
@ -53,12 +57,13 @@ ISO_IV = to_bytes("69474772af6fdab342743aefaa186287")
|
|||
|
||||
|
||||
def filesize(filename):
|
||||
"""Get size of a file in bytes from os.stat"""
|
||||
return os.stat(filename).st_size
|
||||
|
||||
|
||||
def read_seven_bit_encoded_int(fileobj, order):
|
||||
# Read out an Int32 7 bits at a time. The high bit
|
||||
# of the byte when on means to continue reading more bytes
|
||||
"""Read an Int32, 7 bits at a time."""
|
||||
# The highest bit of the byte when on, means to continue reading more bytes.
|
||||
count = 0
|
||||
shift = 0
|
||||
byte = -1
|
||||
|
|
@ -73,15 +78,18 @@ def read_seven_bit_encoded_int(fileobj, order):
|
|||
|
||||
|
||||
def error(msg):
|
||||
"""Print fatal error message and terminate"""
|
||||
print('ERROR: %s' % msg)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def warning(msg):
|
||||
"""Print a warning message"""
|
||||
print('WARNING: %s. Continuing regardless' % msg)
|
||||
|
||||
|
||||
def download_ird(ird_name):
|
||||
"""Download an .ird from GET_IRD_NET_LOC"""
|
||||
ird_link = GET_IRD_NET_LOC + ird_name
|
||||
r = requests.get(ird_link, stream=True)
|
||||
|
||||
|
|
@ -91,6 +99,7 @@ def download_ird(ird_name):
|
|||
|
||||
|
||||
def ird_by_game_id(game_id):
|
||||
"""Using a game_id, download the responding .ird from ALL_IRD_NET_LOC"""
|
||||
gameid = game_id.replace('-','')
|
||||
r = requests.get(ALL_IRD_NET_LOC, headers = {'User-Agent': 'Anonymous (You)' }, timeout=5)
|
||||
soup = BeautifulSoup(r.text, "html.parser")
|
||||
|
|
@ -113,6 +122,10 @@ def ird_by_game_id(game_id):
|
|||
|
||||
|
||||
def decrypt(args):
|
||||
"""Try to decrypt a given .iso using relevant .ird using args from argparse
|
||||
|
||||
If no .ird is given this will try to automatically download an .ird file with the encryption/decryption key for the given game .iso
|
||||
"""
|
||||
|
||||
input_iso = iso.ISO(args)
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import sys
|
|||
import zlib
|
||||
import shutil
|
||||
|
||||
|
||||
try:
|
||||
from libray import core
|
||||
except ImportError:
|
||||
|
|
@ -31,7 +32,19 @@ except ImportError:
|
|||
|
||||
|
||||
class IRD:
|
||||
"""Class for handling .ird files
|
||||
|
||||
Attributes:
|
||||
version: IRD version number
|
||||
game_id: PS3 game identifier
|
||||
game_name: Name of PS3 game
|
||||
update_version: PS3 firmware update version
|
||||
game_version: PS3 game version
|
||||
app_version: PS3 app version
|
||||
region_count: How many encrypted regions are in the .iso
|
||||
file_count: How many files are supposed to be in the .iso
|
||||
data1: Encryption key
|
||||
"""
|
||||
|
||||
ORDER = 'little'
|
||||
TEMP_FILE = 'ird'
|
||||
|
|
@ -39,8 +52,9 @@ class IRD:
|
|||
|
||||
|
||||
def __init__(self, args):
|
||||
"""IRD constructor using args from argparse"""
|
||||
|
||||
self.uncompress(args.ird) # TODO: Try/Except
|
||||
self.uncompress(args.ird) # TODO: Try/Except?
|
||||
|
||||
self.size = core.filesize(self.TEMP_FILE)
|
||||
with open(self.TEMP_FILE, 'rb') as input_ird:
|
||||
|
|
@ -95,18 +109,9 @@ class IRD:
|
|||
os.remove(self.TEMP_FILE)
|
||||
|
||||
|
||||
def get_if_exists(self, input_ird):
|
||||
starting_address = input_ird.tell()
|
||||
length = core.read_seven_bit_encoded_int(input_ird, self.ORDER)
|
||||
print(length)
|
||||
if length:
|
||||
return input_ird.read(length)
|
||||
|
||||
input_ird.seek(starting_address)
|
||||
return None
|
||||
|
||||
|
||||
def uncompress(self, filename):
|
||||
"""Uncompress IRD. Assumes given .ird file is not compressed, but then tries to decompress it with zlib/gzfile if it was not uncompressed"""
|
||||
|
||||
uncompress = False
|
||||
with open(filename, 'rb') as input_ird:
|
||||
if input_ird.read(4) != self.MAGIC_STRING:
|
||||
|
|
@ -120,8 +125,10 @@ class IRD:
|
|||
shutil.copyfile(filename, self.TEMP_FILE)
|
||||
|
||||
|
||||
|
||||
def print_info(self):
|
||||
# TODO: This could probably have been a __str__? Who cares?
|
||||
"""Print some info about the IRD"""
|
||||
|
||||
print('Info from IRD:')
|
||||
print('Version: %s' % self.version)
|
||||
print('Game ID: %s' % self.game_id)
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import sys
|
|||
from tqdm import tqdm
|
||||
from Crypto.Cipher import AES
|
||||
|
||||
|
||||
try:
|
||||
from libray import core
|
||||
from libray import ird
|
||||
|
|
@ -32,12 +33,23 @@ except ImportError:
|
|||
|
||||
|
||||
class ISO:
|
||||
|
||||
"""Class for handling PS3 .iso files
|
||||
|
||||
Attributes:
|
||||
size: Size of .iso in bytes
|
||||
number_of_regions: Number of regions in the .iso
|
||||
regions: List with info of every region
|
||||
game_id: PS3 game id
|
||||
ird: IRD object (see ird.py)
|
||||
disc_key: data1 from .ird, encrypted
|
||||
"""
|
||||
|
||||
NUM_INFO_BYTES = 4
|
||||
|
||||
|
||||
def __init__(self, args):
|
||||
"""ISO constructor using args from argparse"""
|
||||
|
||||
with open(args.iso, 'rb') as input_iso:
|
||||
self.size = core.filesize(args.iso)
|
||||
self.number_of_regions = core.to_int(input_iso.read(self.NUM_INFO_BYTES))
|
||||
|
|
@ -69,6 +81,7 @@ class ISO:
|
|||
|
||||
|
||||
def decrypt(self, args):
|
||||
"""Decrypt self using args from argparse"""
|
||||
|
||||
print('Decrypting with disc key: %s' % self.disc_key.hex())
|
||||
|
||||
|
|
@ -110,7 +123,9 @@ class ISO:
|
|||
|
||||
pbar.close()
|
||||
|
||||
|
||||
def read_regions(self, input_iso, filename):
|
||||
"""List with information (start, end, whether it's encrypted) for every region"""
|
||||
regions = []
|
||||
|
||||
encrypted = False
|
||||
|
|
@ -128,6 +143,9 @@ class ISO:
|
|||
|
||||
|
||||
def print_info(self):
|
||||
# TODO: This could probably have been a __str__? Who cares?
|
||||
"""Print some info about the ISO"""
|
||||
|
||||
print('Info from ISO:')
|
||||
print('Regions: %s (%s)' % (self.number_of_regions, self.number_of_regions*2) )
|
||||
for i, region in enumerate(self.regions):
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
import argparse
|
||||
|
||||
|
||||
try:
|
||||
from libray import core
|
||||
except ImportError:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue