mirror of
https://github.com/NinjaCheetah/WiiPy.git
synced 2025-12-18 12:00:21 -05:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ebd6702056 | |||
| 4b7eae8e85 | |||
| 935f5eb7df | |||
| dfb527388c | |||
| 46784f126e |
@ -78,7 +78,8 @@ def handle_emunand_info(args):
|
|||||||
else:
|
else:
|
||||||
print(f" IOS{int(ios[-2:], 16)} ({ios.upper()})")
|
print(f" IOS{int(ios[-2:], 16)} ({ios.upper()})")
|
||||||
tmd = emunand.get_title_tmd(ios)
|
tmd = emunand.get_title_tmd(ios)
|
||||||
print(f" Version: {tmd.title_version} ({tmd.title_version_converted})")
|
print(f" Version: {tmd.title_version} "
|
||||||
|
f"({libWiiPy.title.title_ver_dec_to_standard(tmd.title_version, tmd.title_id, bool(tmd.vwii))})")
|
||||||
print("")
|
print("")
|
||||||
|
|
||||||
print(f"Installed Titles:")
|
print(f"Installed Titles:")
|
||||||
@ -180,8 +181,13 @@ def handle_emunand_install_missing(args):
|
|||||||
print(f"\nAll missing IOSes have been installed!")
|
print(f"\nAll missing IOSes have been installed!")
|
||||||
|
|
||||||
|
|
||||||
|
def _emunand_logger(log):
|
||||||
|
print(log)
|
||||||
|
|
||||||
|
|
||||||
def handle_emunand_title(args):
|
def handle_emunand_title(args):
|
||||||
emunand = libWiiPy.nand.EmuNAND(args.emunand)
|
logger = _emunand_logger if args.verbose else lambda _: None
|
||||||
|
emunand = libWiiPy.nand.EmuNAND(args.emunand, logger)
|
||||||
if args.skip_hash:
|
if args.skip_hash:
|
||||||
skip_hash = True
|
skip_hash = True
|
||||||
else:
|
else:
|
||||||
|
|||||||
@ -4,7 +4,9 @@
|
|||||||
import binascii
|
import binascii
|
||||||
import pathlib
|
import pathlib
|
||||||
import re
|
import re
|
||||||
|
|
||||||
import libWiiPy
|
import libWiiPy
|
||||||
|
|
||||||
from modules.core import fatal_error
|
from modules.core import fatal_error
|
||||||
|
|
||||||
|
|
||||||
@ -22,11 +24,12 @@ def _print_tmd_info(tmd: libWiiPy.title.TMD, signing_cert=None):
|
|||||||
else:
|
else:
|
||||||
print(f" Title ID: {tmd.title_id.upper()}")
|
print(f" Title ID: {tmd.title_id.upper()}")
|
||||||
# This type of version number really only applies to the System Menu and IOS.
|
# This type of version number really only applies to the System Menu and IOS.
|
||||||
|
title_version_converted = libWiiPy.title.title_ver_dec_to_standard(tmd.title_version, tmd.title_id, bool(tmd.vwii))
|
||||||
if tmd.title_id.startswith("00000001"):
|
if tmd.title_id.startswith("00000001"):
|
||||||
if tmd.title_id == "0000000100000001":
|
if tmd.title_id == "0000000100000001":
|
||||||
print(f" Title Version: {tmd.title_version} (boot2v{tmd.title_version})")
|
print(f" Title Version: {tmd.title_version} (boot2v{tmd.title_version})")
|
||||||
else:
|
else:
|
||||||
print(f" Title Version: {tmd.title_version} ({tmd.title_version_converted})")
|
print(f" Title Version: {tmd.title_version} ({title_version_converted})")
|
||||||
else:
|
else:
|
||||||
print(f" Title Version: {tmd.title_version}")
|
print(f" Title Version: {tmd.title_version}")
|
||||||
print(f" TMD Version: {tmd.tmd_version}")
|
print(f" TMD Version: {tmd.tmd_version}")
|
||||||
@ -52,7 +55,7 @@ def _print_tmd_info(tmd: libWiiPy.title.TMD, signing_cert=None):
|
|||||||
else:
|
else:
|
||||||
print(f" Certificate Info: {tmd.signature_issuer} (Unknown)")
|
print(f" Certificate Info: {tmd.signature_issuer} (Unknown)")
|
||||||
if tmd.title_id == "0000000100000002":
|
if tmd.title_id == "0000000100000002":
|
||||||
match tmd.title_version_converted[-1:]:
|
match title_version_converted[-1:]:
|
||||||
case "U":
|
case "U":
|
||||||
region = "USA"
|
region = "USA"
|
||||||
case "E":
|
case "E":
|
||||||
@ -70,8 +73,8 @@ def _print_tmd_info(tmd: libWiiPy.title.TMD, signing_cert=None):
|
|||||||
print(f" Region: {region}")
|
print(f" Region: {region}")
|
||||||
print(f" Title Type: {tmd.get_title_type()}")
|
print(f" Title Type: {tmd.get_title_type()}")
|
||||||
print(f" vWii Title: {bool(tmd.vwii)}")
|
print(f" vWii Title: {bool(tmd.vwii)}")
|
||||||
print(f" DVD Video Access: {tmd.get_access_right(tmd.AccessFlags.DVD_VIDEO)}")
|
print(f" DVD Video Access: {tmd.get_access_right(libWiiPy.title.AccessFlags.DVD_VIDEO)}")
|
||||||
print(f" AHB Access: {tmd.get_access_right(tmd.AccessFlags.AHB)}")
|
print(f" AHB Access: {tmd.get_access_right(libWiiPy.title.AccessFlags.AHB)}")
|
||||||
if signing_cert is not None:
|
if signing_cert is not None:
|
||||||
try:
|
try:
|
||||||
if libWiiPy.title.verify_tmd_sig(signing_cert, tmd):
|
if libWiiPy.title.verify_tmd_sig(signing_cert, tmd):
|
||||||
@ -105,22 +108,23 @@ def _print_ticket_info(ticket: libWiiPy.title.Ticket, signing_cert=None):
|
|||||||
# Get all important keys from the TMD and print them out nicely.
|
# Get all important keys from the TMD and print them out nicely.
|
||||||
print(f"Ticket Info")
|
print(f"Ticket Info")
|
||||||
ascii_tid = ""
|
ascii_tid = ""
|
||||||
|
decoded_tid = binascii.hexlify(ticket.title_id).decode()
|
||||||
try:
|
try:
|
||||||
ascii_tid = str(bytes.fromhex(ticket.title_id.decode()[8:].replace("00", "30")).decode("ascii"))
|
ascii_tid = str(bytes.fromhex(decoded_tid[8:].replace("00", "30")).decode("ascii"))
|
||||||
except UnicodeDecodeError or binascii.Error:
|
except UnicodeDecodeError:
|
||||||
pass
|
pass
|
||||||
pattern = r"^[a-z0-9!@#$%^&*]{4}$"
|
pattern = r"^[a-z0-9!@#$%^&*]{4}$"
|
||||||
if re.fullmatch(pattern, ascii_tid, re.IGNORECASE):
|
if re.fullmatch(pattern, ascii_tid, re.IGNORECASE):
|
||||||
print(f" Title ID: {ticket.title_id.decode().upper()} ({ascii_tid})")
|
print(f" Title ID: {decoded_tid.upper()} ({ascii_tid})")
|
||||||
else:
|
else:
|
||||||
print(f" Title ID: {ticket.title_id.decode().upper()}")
|
print(f" Title ID: {decoded_tid.upper()}")
|
||||||
# This type of version number really only applies to the System Menu and IOS.
|
# This type of version number really only applies to the System Menu and IOS.
|
||||||
if ticket.title_id.decode().startswith("00000001"):
|
if decoded_tid.startswith("00000001"):
|
||||||
if ticket.title_id.decode() == "0000000100000001":
|
if decoded_tid == "0000000100000001":
|
||||||
print(f" Title Version: {ticket.title_version} (boot2v{ticket.title_version})")
|
print(f" Title Version: {ticket.title_version} (boot2v{ticket.title_version})")
|
||||||
else:
|
else:
|
||||||
print(f" Title Version: {ticket.title_version} "
|
print(f" Title Version: {ticket.title_version} "
|
||||||
f"({libWiiPy.title.title_ver_dec_to_standard(ticket.title_version, ticket.title_id.decode())})")
|
f"({libWiiPy.title.title_ver_dec_to_standard(ticket.title_version, decoded_tid)})")
|
||||||
else:
|
else:
|
||||||
print(f" Title Version: {ticket.title_version}")
|
print(f" Title Version: {ticket.title_version}")
|
||||||
print(f" Ticket Version: {ticket.ticket_version}")
|
print(f" Ticket Version: {ticket.ticket_version}")
|
||||||
@ -135,6 +139,7 @@ def _print_ticket_info(ticket: libWiiPy.title.Ticket, signing_cert=None):
|
|||||||
print(f" Certificate Issuer: Root-CA00000002 (Development)")
|
print(f" Certificate Issuer: Root-CA00000002 (Development)")
|
||||||
else:
|
else:
|
||||||
print(f" Certificate Info: {ticket.signature_issuer} (Unknown)")
|
print(f" Certificate Info: {ticket.signature_issuer} (Unknown)")
|
||||||
|
key = ""
|
||||||
match ticket.common_key_index:
|
match ticket.common_key_index:
|
||||||
case 0:
|
case 0:
|
||||||
if ticket.is_dev:
|
if ticket.is_dev:
|
||||||
|
|||||||
@ -44,7 +44,7 @@ def handle_nus_content(args):
|
|||||||
except ValueError:
|
except ValueError:
|
||||||
fatal_error("The specified Title ID or Content ID could not be found!")
|
fatal_error("The specified Title ID or Content ID could not be found!")
|
||||||
|
|
||||||
if decrypt_content is True:
|
if decrypt_content:
|
||||||
output_path = output_path.with_suffix(".app")
|
output_path = output_path.with_suffix(".app")
|
||||||
tmd = libWiiPy.title.TMD()
|
tmd = libWiiPy.title.TMD()
|
||||||
tmd.load(libWiiPy.title.download_tmd(tid, version))
|
tmd.load(libWiiPy.title.download_tmd(tid, version))
|
||||||
@ -175,7 +175,7 @@ def handle_nus_title(args):
|
|||||||
|
|
||||||
# Try to decrypt the contents for this title if a ticket was available.
|
# Try to decrypt the contents for this title if a ticket was available.
|
||||||
if output_dir is not None:
|
if output_dir is not None:
|
||||||
if can_decrypt is True:
|
if can_decrypt:
|
||||||
for content in range(len(title.tmd.content_records)):
|
for content in range(len(title.tmd.content_records)):
|
||||||
print(f" - Decrypting content {content + 1} of {len(title.tmd.content_records)} "
|
print(f" - Decrypting content {content + 1} of {len(title.tmd.content_records)} "
|
||||||
f"(Content ID: {title.tmd.content_records[content].content_id})...")
|
f"(Content ID: {title.tmd.content_records[content].content_id})...")
|
||||||
|
|||||||
4
wiipy.py
4
wiipy.py
@ -18,7 +18,7 @@ from commands.title.nus import *
|
|||||||
from commands.title.tmd import *
|
from commands.title.tmd import *
|
||||||
from commands.title.wad import *
|
from commands.title.wad import *
|
||||||
|
|
||||||
wiipy_ver = "1.5.0"
|
wiipy_ver = "1.6.0"
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
# Main argument parser.
|
# Main argument parser.
|
||||||
@ -111,6 +111,8 @@ if __name__ == "__main__":
|
|||||||
"accepts a WAD file to read the TID from)")
|
"accepts a WAD file to read the TID from)")
|
||||||
emunand_title_parser.add_argument("-s", "--skip-hash", help="skips validating the hashes of decrypted "
|
emunand_title_parser.add_argument("-s", "--skip-hash", help="skips validating the hashes of decrypted "
|
||||||
"content (install only)", action="store_true")
|
"content (install only)", action="store_true")
|
||||||
|
emunand_title_parser.add_argument("-v", "--verbose", action="store_true",
|
||||||
|
help="show verbose installation/uninstallation details")
|
||||||
|
|
||||||
# Argument parser for the fakesign subcommand.
|
# Argument parser for the fakesign subcommand.
|
||||||
fakesign_parser = subparsers.add_parser("fakesign", help="fakesign a TMD, Ticket, or WAD (trucha bug)",
|
fakesign_parser = subparsers.add_parser("fakesign", help="fakesign a TMD, Ticket, or WAD (trucha bug)",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user