Auto download IRD
This commit is contained in:
parent
cf0a529cdb
commit
77a2f33642
4 changed files with 60 additions and 6 deletions
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
import shutil
|
||||||
import requests
|
import requests
|
||||||
from bs4 import BeautifulSoup
|
from bs4 import BeautifulSoup
|
||||||
|
|
||||||
|
|
@ -32,6 +33,8 @@ except ImportError:
|
||||||
# Magic numbers / Constant variables
|
# Magic numbers / Constant variables
|
||||||
|
|
||||||
SECTOR = 2048
|
SECTOR = 2048
|
||||||
|
ALL_IRD_NET_LOC = 'http://jonnysp.bplaced.net/data.php'
|
||||||
|
GET_IRD_NET_LOC = 'http://jonnysp.bplaced.net/ird/'
|
||||||
|
|
||||||
# Utility functions
|
# Utility functions
|
||||||
|
|
||||||
|
|
@ -73,8 +76,42 @@ def error(msg):
|
||||||
print('ERROR: %s' % msg)
|
print('ERROR: %s' % msg)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
def warning(msg):
|
||||||
|
print('WARNING: %s. Continuing regardless' % msg)
|
||||||
|
|
||||||
|
|
||||||
|
def download_ird(ird_name):
|
||||||
|
ird_link = GET_IRD_NET_LOC + ird_name
|
||||||
|
r = requests.get(ird_link, stream=True)
|
||||||
|
|
||||||
|
with open(ird_name, 'wb') as ird_file:
|
||||||
|
r.raw.decode_content = True
|
||||||
|
shutil.copyfileobj(r.raw, ird_file)
|
||||||
|
|
||||||
|
|
||||||
|
def ird_by_game_id(game_id):
|
||||||
|
gameid = game_id.replace('-','')
|
||||||
|
r = requests.get(ALL_IRD_NET_LOC, headers = {'User-Agent': 'Anonymous (You)' }, timeout=5)
|
||||||
|
soup = BeautifulSoup(r.text, "html.parser")
|
||||||
|
|
||||||
|
ird_name = False
|
||||||
|
for elem in soup.find_all("a"):
|
||||||
|
url = elem.get('href').split('/')[-1].replace('\\"','')
|
||||||
|
if gameid in url:
|
||||||
|
ird_name = url
|
||||||
|
|
||||||
|
if not ird_name:
|
||||||
|
error("Unable to download IRD, couldn't find link")
|
||||||
|
|
||||||
|
download_ird(ird_name)
|
||||||
|
|
||||||
|
return(ird_name)
|
||||||
|
|
||||||
|
|
||||||
# Main functions
|
# Main functions
|
||||||
|
|
||||||
|
|
||||||
def decrypt(args):
|
def decrypt(args):
|
||||||
|
|
||||||
input_iso = iso.ISO(args)
|
input_iso = iso.ISO(args)
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with libray. If not, see <https://www.gnu.org/licenses/>.
|
# along with libray. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import zlib
|
import zlib
|
||||||
|
|
|
||||||
|
|
@ -45,14 +45,24 @@ class ISO:
|
||||||
|
|
||||||
self.regions = self.read_regions(input_iso, args.iso)
|
self.regions = self.read_regions(input_iso, args.iso)
|
||||||
|
|
||||||
|
input_iso.seek(core.SECTOR)
|
||||||
|
playstation = input_iso.read(16)
|
||||||
|
self.game_id = input_iso.read(16).decode('utf8').strip()
|
||||||
|
|
||||||
if args.verbose:
|
if args.verbose:
|
||||||
self.print_info()
|
self.print_info()
|
||||||
|
|
||||||
|
if not args.ird:
|
||||||
|
core.warning('No IRD file specified, downloading required file')
|
||||||
|
args.ird = core.ird_by_game_id(self.game_id) # Download ird
|
||||||
|
|
||||||
self.ird = ird.IRD(args)
|
self.ird = ird.IRD(args)
|
||||||
|
|
||||||
if self.ird.region_count != len(self.regions)-1:
|
if self.ird.region_count != len(self.regions)-1:
|
||||||
core.error('ISO corrupted. Expected %s regions, found %s regions' % (self.ird.region_count, len(self.regions)-1))
|
core.error('Corrupt ISO. Expected %s regions, found %s regions' % (self.ird.region_count, len(self.regions)-1))
|
||||||
sys.exit()
|
|
||||||
|
if self.regions[-1]['start'] > self.size:
|
||||||
|
core.error('Corrupt ISO. Expected filesize larger than %.2f GiB, actual size is %.2f GiB' % (self.regions[-1]['start'] / 1024**3, self.size / 1024**3 ) )
|
||||||
|
|
||||||
cipher = AES.new(core.ISO_SECRET, AES.MODE_CBC, core.ISO_IV)
|
cipher = AES.new(core.ISO_SECRET, AES.MODE_CBC, core.ISO_IV)
|
||||||
self.disc_key = cipher.encrypt(self.ird.data1)
|
self.disc_key = cipher.encrypt(self.ird.data1)
|
||||||
|
|
@ -65,7 +75,7 @@ class ISO:
|
||||||
with open(args.iso, 'rb') as input_iso:
|
with open(args.iso, 'rb') as input_iso:
|
||||||
with open(args.output, 'wb') as output_iso:
|
with open(args.output, 'wb') as output_iso:
|
||||||
|
|
||||||
pbar = tqdm(total=self.size)
|
pbar = tqdm(total= (self.size // 2048) - 4 )
|
||||||
|
|
||||||
for i, region in enumerate(self.regions):
|
for i, region in enumerate(self.regions):
|
||||||
input_iso.seek(region['start'])
|
input_iso.seek(region['start'])
|
||||||
|
|
@ -73,7 +83,10 @@ class ISO:
|
||||||
if not region['enc']:
|
if not region['enc']:
|
||||||
while input_iso.tell() < region['end']:
|
while input_iso.tell() < region['end']:
|
||||||
data = input_iso.read(core.SECTOR)
|
data = input_iso.read(core.SECTOR)
|
||||||
pbar.update(core.SECTOR)
|
if not data:
|
||||||
|
core.warning("Trying to read past the end of the file")
|
||||||
|
break
|
||||||
|
pbar.update(1)
|
||||||
output_iso.write(data)
|
output_iso.write(data)
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
|
|
@ -85,7 +98,10 @@ class ISO:
|
||||||
num >>= 8
|
num >>= 8
|
||||||
|
|
||||||
data = input_iso.read(core.SECTOR)
|
data = input_iso.read(core.SECTOR)
|
||||||
pbar.update(core.SECTOR)
|
if not data:
|
||||||
|
core.warning("Trying to read past the end of the file")
|
||||||
|
break
|
||||||
|
pbar.update(1)
|
||||||
|
|
||||||
cipher = AES.new(self.disc_key, AES.MODE_CBC, bytes(iv))
|
cipher = AES.new(self.disc_key, AES.MODE_CBC, bytes(iv))
|
||||||
decrypted = cipher.decrypt(data)
|
decrypted = cipher.decrypt(data)
|
||||||
|
|
|
||||||
|
|
@ -34,9 +34,9 @@ if __name__ == '__main__':
|
||||||
parser = argparse.ArgumentParser(description='A Libre (FLOSS) Python application for unencrypting, extracting, repackaging, and encrypting PS3 ISOs')
|
parser = argparse.ArgumentParser(description='A Libre (FLOSS) Python application for unencrypting, extracting, repackaging, and encrypting PS3 ISOs')
|
||||||
parser.add_argument('-v', '--verbose', help="Increase verbosity", action='count')
|
parser.add_argument('-v', '--verbose', help="Increase verbosity", action='count')
|
||||||
parser.add_argument('-o', '--output', dest='output', type=str, help="Output filename", default='output.iso')
|
parser.add_argument('-o', '--output', dest='output', type=str, help="Output filename", default='output.iso')
|
||||||
|
parser.add_argument('-k', '--ird', dest='ird', type=str, help="Path to .ird file", default="")
|
||||||
required = parser.add_argument_group('required arguments')
|
required = parser.add_argument_group('required arguments')
|
||||||
required.add_argument('-i', '--iso', dest='iso', type=str, help="Path to .iso file", required=True)
|
required.add_argument('-i', '--iso', dest='iso', type=str, help="Path to .iso file", required=True)
|
||||||
required.add_argument('-k', '--ird', dest='ird', type=str, help="Path to .ird file", required=True)
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
core.decrypt(args)
|
core.decrypt(args)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue