Release 0.0.7
This commit is contained in:
parent
82bc798677
commit
ef82f69e99
2 changed files with 50 additions and 18 deletions
|
|
@ -3,10 +3,11 @@ All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
|
|
||||||
## [0.0.7] - Unreleased
|
## [0.0.7] - 2021-06-29
|
||||||
### Added
|
### Added
|
||||||
- PARAM.SFO reader (sfo.py)
|
- PARAM.SFO reader (sfo.py)
|
||||||
- Now searches for PARAM.SFO first and uses game title from there instead of crc32.
|
- Now searches for PARAM.SFO first and uses game title from there instead of crc32.
|
||||||
|
- To identify keys, checks if .iso has a unique size, then if it has the name from PARAM.SFO in it + size, then downloads .ird
|
||||||
- long_description in setup.py for description on PyPI
|
- long_description in setup.py for description on PyPI
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
|
||||||
|
|
@ -111,15 +111,24 @@ class ISO:
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
|
|
||||||
data = input_iso.read(4)
|
data = input_iso.read(8)
|
||||||
|
|
||||||
if not data:
|
if not data:
|
||||||
break
|
break
|
||||||
|
|
||||||
if data == b'\x00\x50\x53\x46':
|
#if data == b'PS3LICDA':
|
||||||
|
# print(data)
|
||||||
|
|
||||||
|
if data[0:4] == b'\x00\x50\x53\x46':
|
||||||
found_param = True
|
found_param = True
|
||||||
|
|
||||||
|
#input_iso.seek(input_iso.tell() - 8)
|
||||||
|
#param = sfo.SFO(input_iso)
|
||||||
|
#print(param['TITLE'])
|
||||||
|
#print(param['TITLE_ID'])
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
||||||
input_iso.seek((core.SECTOR * counter))
|
input_iso.seek((core.SECTOR * counter))
|
||||||
|
|
||||||
counter += 1
|
counter += 1
|
||||||
|
|
@ -127,10 +136,11 @@ class ISO:
|
||||||
game_title = ''
|
game_title = ''
|
||||||
|
|
||||||
if found_param:
|
if found_param:
|
||||||
input_iso.seek(input_iso.tell() - 4)
|
input_iso.seek(input_iso.tell() - 8)
|
||||||
try:
|
try:
|
||||||
param = sfo.SFO(input_iso)
|
param = sfo.SFO(input_iso)
|
||||||
core.vprint('PARAM.SFO found', args)
|
core.vprint('PARAM.SFO found', args)
|
||||||
|
|
||||||
game_title = core.multiman_title(param['TITLE'])
|
game_title = core.multiman_title(param['TITLE'])
|
||||||
|
|
||||||
if args.verbose and not args.quiet:
|
if args.verbose and not args.quiet:
|
||||||
|
|
@ -141,11 +151,14 @@ class ISO:
|
||||||
if not args.output:
|
if not args.output:
|
||||||
args.output = '%s [%s].iso' % (game_title, param['TITLE_ID'])
|
args.output = '%s [%s].iso' % (game_title, param['TITLE_ID'])
|
||||||
|
|
||||||
except:
|
except Exception:
|
||||||
core.warning('Failed reading SFO')
|
|
||||||
|
core.warning('Failed reading SFO', args)
|
||||||
|
|
||||||
cipher = AES.new(core.ISO_SECRET, AES.MODE_CBC, core.ISO_IV)
|
cipher = AES.new(core.ISO_SECRET, AES.MODE_CBC, core.ISO_IV)
|
||||||
|
|
||||||
|
# TODO: clean up this logic
|
||||||
|
|
||||||
if not args.decryption_key:
|
if not args.decryption_key:
|
||||||
if not args.ird:
|
if not args.ird:
|
||||||
# No key or .ird specified. Let's first check if keys.db is packaged with this release
|
# No key or .ird specified. Let's first check if keys.db is packaged with this release
|
||||||
|
|
@ -161,10 +174,7 @@ class ISO:
|
||||||
db = sqlite3.connect((pathlib.Path(__file__).resolve() / 'data/') / 'keys.db')
|
db = sqlite3.connect((pathlib.Path(__file__).resolve() / 'data/') / 'keys.db')
|
||||||
c = db.cursor()
|
c = db.cursor()
|
||||||
|
|
||||||
if not game_title:
|
|
||||||
raise ValueError
|
|
||||||
|
|
||||||
core.vprint('Trying to find redump key based on size and game title', args)
|
|
||||||
|
|
||||||
#core.vprint('Calculating crc32', args)
|
#core.vprint('Calculating crc32', args)
|
||||||
|
|
||||||
|
|
@ -174,22 +184,40 @@ class ISO:
|
||||||
|
|
||||||
#keys = c.execute('SELECT * FROM games WHERE crc32=?', [crc32.lower()]).fetchall()
|
#keys = c.execute('SELECT * FROM games WHERE crc32=?', [crc32.lower()]).fetchall()
|
||||||
|
|
||||||
keys = c.execute('SELECT * FROM games WHERE lower(name) LIKE ? AND size = ?', ['%' + game_title.lower() + '%', str(self.size)]).fetchall()
|
# First check if there's only one game with this exact size
|
||||||
|
|
||||||
if keys:
|
core.vprint('Trying to find redump key based on size', args)
|
||||||
|
|
||||||
|
keys = c.execute('SELECT * FROM games WHERE size = ?', [str(self.size)]).fetchall()
|
||||||
|
|
||||||
|
if len(keys) == 1:
|
||||||
|
|
||||||
self.disc_key = keys[0][-1]
|
self.disc_key = keys[0][-1]
|
||||||
|
|
||||||
if not self.disc_key:
|
|
||||||
raise ValueError
|
|
||||||
|
|
||||||
core.vprint('Found potential redump key: "%s"' % keys[0][0], args)
|
|
||||||
|
|
||||||
redump = True
|
redump = True
|
||||||
|
|
||||||
else:
|
# If not, see if we can filter it out based on name and size
|
||||||
|
|
||||||
|
if not redump:
|
||||||
|
|
||||||
|
core.vprint('Trying to find redump key based on size and game title', args)
|
||||||
|
|
||||||
|
if not game_title:
|
||||||
|
raise ValueError
|
||||||
|
|
||||||
|
keys = c.execute('SELECT * FROM games WHERE lower(name) LIKE ? AND size = ?', ['%' + game_title.lower() + '%', str(self.size)]).fetchall()
|
||||||
|
|
||||||
|
if keys:
|
||||||
|
|
||||||
|
self.disc_key = keys[0][-1]
|
||||||
|
|
||||||
|
redump = True
|
||||||
|
|
||||||
|
if not self.disc_key:
|
||||||
raise ValueError
|
raise ValueError
|
||||||
|
|
||||||
|
core.vprint('Found potential redump key: "%s"' % keys[0][0], args)
|
||||||
|
|
||||||
except:
|
except:
|
||||||
core.vprint('No keys found', args)
|
core.vprint('No keys found', args)
|
||||||
|
|
||||||
|
|
@ -220,7 +248,6 @@ class ISO:
|
||||||
"""Decrypt self using args from argparse."""
|
"""Decrypt self using args from argparse."""
|
||||||
|
|
||||||
core.vprint('Decrypting with disc key: %s' % self.disc_key.hex(), args)
|
core.vprint('Decrypting with disc key: %s' % self.disc_key.hex(), args)
|
||||||
core.vprint('Decrypted .iso is output to: %s' % args.output, args)
|
|
||||||
|
|
||||||
with open(args.iso, 'rb') as input_iso:
|
with open(args.iso, 'rb') as input_iso:
|
||||||
|
|
||||||
|
|
@ -229,6 +256,8 @@ class ISO:
|
||||||
else:
|
else:
|
||||||
output_name = args.output
|
output_name = args.output
|
||||||
|
|
||||||
|
core.vprint('Decrypted .iso is output to: %s' % output_name, args)
|
||||||
|
|
||||||
with open(output_name, 'wb') as output_iso:
|
with open(output_name, 'wb') as output_iso:
|
||||||
|
|
||||||
if not args.quiet:
|
if not args.quiet:
|
||||||
|
|
@ -289,6 +318,8 @@ class ISO:
|
||||||
else:
|
else:
|
||||||
output_name = args.output
|
output_name = args.output
|
||||||
|
|
||||||
|
core.vprint('Re-encrypted .iso is output to: %s' % output_name, args)
|
||||||
|
|
||||||
with open(output_name, 'wb') as output_iso:
|
with open(output_name, 'wb') as output_iso:
|
||||||
|
|
||||||
if not args.quiet:
|
if not args.quiet:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue