Add -r / --re-encrypt
This commit is contained in:
parent
46317877c1
commit
5e9bd4f257
6 changed files with 93 additions and 12 deletions
10
CHANGELOG.md
10
CHANGELOG.md
|
|
@ -3,6 +3,14 @@ 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.6] - 2020-06-02
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Issue #6: fix decrypting using disc key not working
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Added .iso re-encryption with -r / --re-encrypt, default output is game_id_e.iso (example: BLUS-0000_e.iso)
|
||||||
|
|
||||||
## [0.0.5] - 2020-08-03
|
## [0.0.5] - 2020-08-03
|
||||||
### Fixed
|
### Fixed
|
||||||
- Issue #4: fix broken progressbar
|
- Issue #4: fix broken progressbar
|
||||||
|
|
@ -15,7 +23,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
|
|
||||||
## [0.0.3] - 2020-08-03
|
## [0.0.3] - 2020-08-03
|
||||||
### Changed
|
### Changed
|
||||||
- Default output iso name is game_id.iso instead of output.iso
|
- Default output iso name is game_id.iso instead of output.iso (example: BLUS-0000.iso)
|
||||||
- Added quiet mode, enabled with the -q or --quiet flag argument
|
- Added quiet mode, enabled with the -q or --quiet flag argument
|
||||||
- Added the ability to manually specify decryption key with -d or --decryption-key
|
- Added the ability to manually specify decryption key with -d or --decryption-key
|
||||||
|
|
||||||
|
|
|
||||||
10
README.md
10
README.md
|
|
@ -42,10 +42,9 @@ This will essentially automatically do the manual method for you.
|
||||||
## How do I use it?
|
## How do I use it?
|
||||||
|
|
||||||
```
|
```
|
||||||
usage: libray [-h] -i ISO [-o OUTPUT] [-k IRD] [-d DECRYPTION_KEY] [-v] [-q]
|
usage: libray [-h] -i ISO [-o OUTPUT] [-k IRD] [-d DECRYPTION_KEY] [-v] [-q] [-r]
|
||||||
|
|
||||||
A Libre (FLOSS) Python application for unencrypting, extracting, repackaging,
|
A Libre (FLOSS) Python application for unencrypting, extracting, repackaging, and encrypting PS3 ISOs
|
||||||
and encrypting PS3 ISOs
|
|
||||||
|
|
||||||
required arguments:
|
required arguments:
|
||||||
-i ISO, --iso ISO Path to .iso file or stream
|
-i ISO, --iso ISO Path to .iso file or stream
|
||||||
|
|
@ -58,6 +57,7 @@ optional arguments:
|
||||||
Manually specify key
|
Manually specify key
|
||||||
-v, --verbose Increase verbosity
|
-v, --verbose Increase verbosity
|
||||||
-q, --quiet Quiet mode, only prints on error
|
-q, --quiet Quiet mode, only prints on error
|
||||||
|
-r, --re-encrypt Re-encrypt .iso
|
||||||
```
|
```
|
||||||
|
|
||||||
First off, even before you install libray, you will need a compatible Blu-Ray drive that can read PS3 discs.
|
First off, even before you install libray, you will need a compatible Blu-Ray drive that can read PS3 discs.
|
||||||
|
|
@ -98,9 +98,9 @@ Then, if you want to feed it into RPCS3 just extract the contents of the .ISO:
|
||||||
7z x nfs_ps3_decrypted.iso
|
7z x nfs_ps3_decrypted.iso
|
||||||
```
|
```
|
||||||
|
|
||||||
And move the resulting folders into the appropriate folder for RPCS3:
|
And move the resulting folders into a folder named after the game ID into the appropriate folder for RPCS3:
|
||||||
|
|
||||||
- Linux: /home/username/.config/rpcs3/dev_hdd0/disc/
|
- Linux: /home/username/.config/rpcs3/dev_hdd0/disc/BLUS0000
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,7 @@ def download_ird(ird_name):
|
||||||
"""Download an .ird from GET_IRD_NET_LOC"""
|
"""Download an .ird from GET_IRD_NET_LOC"""
|
||||||
|
|
||||||
# Check if file already exists and skip if it does
|
# Check if file already exists and skip if it does
|
||||||
if os.path.exists(ird_name):
|
if os.path.exists(ird_name): # TODO: might want to check that the file is valid first, could do a HEAD agains the url
|
||||||
return
|
return
|
||||||
|
|
||||||
ird_link = GET_IRD_NET_LOC + ird_name
|
ird_link = GET_IRD_NET_LOC + ird_name
|
||||||
|
|
@ -119,7 +119,7 @@ def ird_by_game_id(game_id):
|
||||||
try:
|
try:
|
||||||
r = requests.get(ALL_IRD_NET_LOC, headers = {'User-Agent': 'Anonymous (You)' }, timeout=5)
|
r = requests.get(ALL_IRD_NET_LOC, headers = {'User-Agent': 'Anonymous (You)' }, timeout=5)
|
||||||
except requests.exceptions.ReadTimeout:
|
except requests.exceptions.ReadTimeout:
|
||||||
core.error('Server timed out, fix your connection or manually specify a key/ird.')
|
error('Server timed out, fix your connection or manually specify a key/ird.')
|
||||||
soup = BeautifulSoup(r.text, "html.parser")
|
soup = BeautifulSoup(r.text, "html.parser")
|
||||||
|
|
||||||
ird_name = False
|
ird_name = False
|
||||||
|
|
@ -140,7 +140,7 @@ def ird_by_game_id(game_id):
|
||||||
|
|
||||||
|
|
||||||
def decrypt(args):
|
def decrypt(args):
|
||||||
"""Try to decrypt a given .iso using relevant .ird using args from argparse
|
"""Try to decrypt a given .iso using relevant .ird or encryption key 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
|
If no .ird is given this will try to automatically download an .ird file with the encryption/decryption key for the given game .iso
|
||||||
"""
|
"""
|
||||||
|
|
@ -150,4 +150,12 @@ def decrypt(args):
|
||||||
input_iso.decrypt(args)
|
input_iso.decrypt(args)
|
||||||
|
|
||||||
|
|
||||||
|
def encrypt(args):
|
||||||
|
"""Try to re-encrypt a decrypted .iso using relevant .ird or encryption key 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)
|
||||||
|
|
||||||
|
input_iso.encrypt(args)
|
||||||
|
|
|
||||||
|
|
@ -180,10 +180,67 @@ class ISO:
|
||||||
print('Decryption complete.')
|
print('Decryption complete.')
|
||||||
|
|
||||||
|
|
||||||
|
def encrypt(self, args):
|
||||||
|
"""Encrypt self using args from argparse."""
|
||||||
|
|
||||||
|
if not args.quiet:
|
||||||
|
print('Re-encrypting with disc key: %s' % self.disc_key.hex())
|
||||||
|
|
||||||
|
with open(args.iso, 'rb') as input_iso:
|
||||||
|
|
||||||
|
if not args.output:
|
||||||
|
output_name = '%s_e.iso' % self.game_id
|
||||||
|
else:
|
||||||
|
output_name = args.output
|
||||||
|
|
||||||
|
with open(output_name, 'wb') as output_iso:
|
||||||
|
|
||||||
|
if not args.quiet:
|
||||||
|
pbar = tqdm(total= (self.size // 2048) )
|
||||||
|
|
||||||
|
for region in self.regions:
|
||||||
|
input_iso.seek(region['start'])
|
||||||
|
|
||||||
|
# Unencrypted region, just copy it
|
||||||
|
if not region['enc']:
|
||||||
|
while input_iso.tell() < region['end']:
|
||||||
|
data = input_iso.read(core.SECTOR)
|
||||||
|
if not data and not args.quiet:
|
||||||
|
core.warning('Trying to read past the end of the file')
|
||||||
|
break
|
||||||
|
output_iso.write(data)
|
||||||
|
|
||||||
|
if not args.quiet:
|
||||||
|
pbar.update(1)
|
||||||
|
continue
|
||||||
|
# Decrypted region, re-encrypt it
|
||||||
|
else:
|
||||||
|
while input_iso.tell() < region['end']:
|
||||||
|
num = input_iso.tell() // 2048
|
||||||
|
iv = bytearray([0 for i in range(0,16)])
|
||||||
|
for j in range(0,16):
|
||||||
|
iv[16 - j - 1] = (num & 0xFF)
|
||||||
|
num >>= 8
|
||||||
|
|
||||||
|
data = input_iso.read(core.SECTOR)
|
||||||
|
if not data and not args.quiet:
|
||||||
|
core.warning('Trying to read past the end of the file')
|
||||||
|
break
|
||||||
|
|
||||||
|
cipher = AES.new(self.disc_key, AES.MODE_CBC, bytes(iv))
|
||||||
|
encrypted = cipher.encrypt(data)
|
||||||
|
|
||||||
|
output_iso.write(encrypted)
|
||||||
|
|
||||||
|
if not args.quiet:
|
||||||
|
pbar.update(1)
|
||||||
|
|
||||||
|
|
||||||
def print_info(self):
|
def print_info(self):
|
||||||
# TODO: This could probably have been a __str__? Who cares?
|
# TODO: This could probably have been a __str__? Who cares?
|
||||||
"""Print some info about the ISO."""
|
"""Print some info about the ISO."""
|
||||||
|
print('Game ID: %s' % self.game_id)
|
||||||
|
print('Key: %s' % self.disc_key.hex())
|
||||||
print('Info from ISO:')
|
print('Info from ISO:')
|
||||||
print('Regions: %s' % self.number_of_regions)
|
print('Regions: %s' % self.number_of_regions)
|
||||||
for i, region in enumerate(self.regions):
|
for i, region in enumerate(self.regions):
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,15 @@ if __name__ == '__main__':
|
||||||
optional.add_argument('-d', '--decryption-key', dest='decryption_key', type=str, help='Manually specify key', default='')
|
optional.add_argument('-d', '--decryption-key', dest='decryption_key', type=str, help='Manually specify key', default='')
|
||||||
optional.add_argument('-v', '--verbose', dest='verbose', help='Increase verbosity', action='count')
|
optional.add_argument('-v', '--verbose', dest='verbose', help='Increase verbosity', action='count')
|
||||||
optional.add_argument('-q', '--quiet', dest='quiet', help='Quiet mode, only prints on error', action='store_true')
|
optional.add_argument('-q', '--quiet', dest='quiet', help='Quiet mode, only prints on error', action='store_true')
|
||||||
|
# -e is reserved for "extract" so re-encrypt is "-r"
|
||||||
|
optional.add_argument('-r', '--re-encrypt', dest='reencrypt', help='Re-encrypt .iso', action='store_true')
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
core.decrypt(args)
|
if args.reencrypt:
|
||||||
|
|
||||||
|
core.encrypt(args)
|
||||||
|
|
||||||
|
else:
|
||||||
|
|
||||||
|
core.decrypt(args)
|
||||||
|
|
|
||||||
2
setup.py
2
setup.py
|
|
@ -5,7 +5,7 @@ from setuptools import setup
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
name="libray",
|
name="libray",
|
||||||
version="0.0.5",
|
version="0.0.6",
|
||||||
description='A Libre (FLOSS) Python application for unencrypting, extracting, repackaging, and encrypting PS3 ISOs',
|
description='A Libre (FLOSS) Python application for unencrypting, extracting, repackaging, and encrypting PS3 ISOs',
|
||||||
author="Nichlas Severinsen",
|
author="Nichlas Severinsen",
|
||||||
author_email="ns@nsz.no",
|
author_email="ns@nsz.no",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue