mirror of
https://github.com/NinjaCheetah/NUSGet.git
synced 2025-04-25 23:21:02 -04:00
Added ability to re-encrypt vWii WAD Title Keys with the common key
This allows the creation of WADs that can be installed from *within* vWii mode, instead of just from Wii U mode.
This commit is contained in:
parent
95dd93b85f
commit
ec16050d6f
34
NUSGet.py
34
NUSGet.py
@ -1,6 +1,5 @@
|
|||||||
# NUSGet.py, licensed under the MIT license
|
# NUSGet.py, licensed under the MIT license
|
||||||
# Copyright 2024 NinjaCheetah
|
# Copyright 2024 NinjaCheetah
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
import json
|
import json
|
||||||
@ -125,8 +124,8 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|||||||
self.log_text += new_text + "\n"
|
self.log_text += new_text + "\n"
|
||||||
self.ui.log_text_browser.setText(self.log_text)
|
self.ui.log_text_browser.setText(self.log_text)
|
||||||
# Always auto-scroll to the bottom of the log.
|
# Always auto-scroll to the bottom of the log.
|
||||||
scrollBar = self.ui.log_text_browser.verticalScrollBar()
|
scroll_bar = self.ui.log_text_browser.verticalScrollBar()
|
||||||
scrollBar.setValue(scrollBar.maximum())
|
scroll_bar.setValue(scroll_bar.maximum())
|
||||||
|
|
||||||
def load_title_data(self, selected_title, selected_version, selected_region=None):
|
def load_title_data(self, selected_title, selected_version, selected_region=None):
|
||||||
# Use the information passed from the double click callback to prepare a title for downloading.
|
# Use the information passed from the double click callback to prepare a title for downloading.
|
||||||
@ -168,15 +167,15 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|||||||
# Throw an error and make a message box appear if you haven't selected any options to output the title.
|
# Throw an error and make a message box appear if you haven't selected any options to output the title.
|
||||||
if (self.ui.pack_wad_chkbox.isChecked() is False and self.ui.keep_enc_chkbox.isChecked() is False and
|
if (self.ui.pack_wad_chkbox.isChecked() is False and self.ui.keep_enc_chkbox.isChecked() is False and
|
||||||
self.ui.create_dec_chkbox.isChecked() is False):
|
self.ui.create_dec_chkbox.isChecked() is False):
|
||||||
msgBox = QMessageBox()
|
msg_box = QMessageBox()
|
||||||
msgBox.setIcon(QMessageBox.Icon.Critical)
|
msg_box.setIcon(QMessageBox.Icon.Critical)
|
||||||
msgBox.setStandardButtons(QMessageBox.StandardButton.Ok)
|
msg_box.setStandardButtons(QMessageBox.StandardButton.Ok)
|
||||||
msgBox.setDefaultButton(QMessageBox.StandardButton.Ok)
|
msg_box.setDefaultButton(QMessageBox.StandardButton.Ok)
|
||||||
msgBox.setWindowTitle("No Output Selected")
|
msg_box.setWindowTitle("No Output Selected")
|
||||||
msgBox.setText("You have not selected any format to output the data in!")
|
msg_box.setText("You have not selected any format to output the data in!")
|
||||||
msgBox.setInformativeText("Please select at least one option for how you would like the download to be "
|
msg_box.setInformativeText("Please select at least one option for how you would like the download to be "
|
||||||
"saved.")
|
"saved.")
|
||||||
msgBox.exec()
|
msg_box.exec()
|
||||||
return
|
return
|
||||||
# Lock the UI prior to the download beginning to avoid spawning multiple threads or changing info part way in.
|
# Lock the UI prior to the download beginning to avoid spawning multiple threads or changing info part way in.
|
||||||
self.ui.tid_entry.setEnabled(False)
|
self.ui.tid_entry.setEnabled(False)
|
||||||
@ -187,6 +186,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|||||||
self.ui.create_dec_chkbox.setEnabled(False)
|
self.ui.create_dec_chkbox.setEnabled(False)
|
||||||
self.ui.use_local_chkbox.setEnabled(False)
|
self.ui.use_local_chkbox.setEnabled(False)
|
||||||
self.ui.use_wiiu_nus_chkbox.setEnabled(False)
|
self.ui.use_wiiu_nus_chkbox.setEnabled(False)
|
||||||
|
self.ui.pack_vwii_mode_chkbox.setEnabled(False)
|
||||||
self.ui.wad_file_entry.setEnabled(False)
|
self.ui.wad_file_entry.setEnabled(False)
|
||||||
self.log_text = ""
|
self.log_text = ""
|
||||||
self.ui.log_text_browser.setText(self.log_text)
|
self.ui.log_text_browser.setText(self.log_text)
|
||||||
@ -241,6 +241,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|||||||
self.ui.create_dec_chkbox.setEnabled(True)
|
self.ui.create_dec_chkbox.setEnabled(True)
|
||||||
self.ui.use_local_chkbox.setEnabled(True)
|
self.ui.use_local_chkbox.setEnabled(True)
|
||||||
self.ui.use_wiiu_nus_chkbox.setEnabled(True)
|
self.ui.use_wiiu_nus_chkbox.setEnabled(True)
|
||||||
|
self.ui.pack_vwii_mode_chkbox.setEnabled(True)
|
||||||
if self.ui.pack_wad_chkbox.isChecked() is True:
|
if self.ui.pack_wad_chkbox.isChecked() is True:
|
||||||
self.ui.wad_file_entry.setEnabled(True)
|
self.ui.wad_file_entry.setEnabled(True)
|
||||||
|
|
||||||
@ -358,6 +359,15 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|||||||
return -3
|
return -3
|
||||||
# If pack WAD is still true, pack the TMD, ticket, and contents all into a WAD.
|
# If pack WAD is still true, pack the TMD, ticket, and contents all into a WAD.
|
||||||
if pack_wad_enabled is True:
|
if pack_wad_enabled is True:
|
||||||
|
# If the option to pack for vWii mode instead of Wii U mode is enabled, then the Title Key needs to be
|
||||||
|
# re-encrypted with the common key instead of the vWii key, so that the title can be installed from within
|
||||||
|
# vWii mode. (vWii mode does not have access to the vWii key, only Wii U mode has that.)
|
||||||
|
if self.ui.pack_vwii_mode_chkbox.isChecked() is True and (tid[3] == "7" or tid[7] == "7"):
|
||||||
|
progress_callback.emit(" - Re-encrypting Title Key with the common key...")
|
||||||
|
title_key_dec = title.ticket.get_title_key()
|
||||||
|
title_key_common = libWiiPy.encrypt_title_key(title_key_dec, 0, title.tmd.title_id)
|
||||||
|
title.ticket.common_key_index = 0
|
||||||
|
title.ticket.title_key_enc = title_key_common
|
||||||
# Get the WAD certificate chain, courtesy of libWiiPy.
|
# Get the WAD certificate chain, courtesy of libWiiPy.
|
||||||
progress_callback.emit(" - Building certificate...")
|
progress_callback.emit(" - Building certificate...")
|
||||||
title.wad.set_cert_data(libWiiPy.download_cert(wiiu_endpoint=wiiu_nus_enabled))
|
title.wad.set_cert_data(libWiiPy.download_cert(wiiu_endpoint=wiiu_nus_enabled))
|
||||||
|
@ -78,6 +78,11 @@ class Ui_MainWindow(object):
|
|||||||
|
|
||||||
self.verticalLayout_4.addWidget(self.vwii_title_tree)
|
self.verticalLayout_4.addWidget(self.vwii_title_tree)
|
||||||
|
|
||||||
|
self.pack_vwii_mode_chkbox = QCheckBox(self.vwii_tab)
|
||||||
|
self.pack_vwii_mode_chkbox.setObjectName(u"pack_vwii_mode_chkbox")
|
||||||
|
|
||||||
|
self.verticalLayout_4.addWidget(self.pack_vwii_mode_chkbox)
|
||||||
|
|
||||||
self.platform_tabs.addTab(self.vwii_tab, "")
|
self.platform_tabs.addTab(self.vwii_tab, "")
|
||||||
|
|
||||||
self.verticalLayout.addWidget(self.platform_tabs)
|
self.verticalLayout.addWidget(self.platform_tabs)
|
||||||
@ -163,7 +168,7 @@ class Ui_MainWindow(object):
|
|||||||
MainWindow.setCentralWidget(self.centralwidget)
|
MainWindow.setCentralWidget(self.centralwidget)
|
||||||
self.menubar = QMenuBar(MainWindow)
|
self.menubar = QMenuBar(MainWindow)
|
||||||
self.menubar.setObjectName(u"menubar")
|
self.menubar.setObjectName(u"menubar")
|
||||||
self.menubar.setGeometry(QRect(0, 0, 610, 30))
|
self.menubar.setGeometry(QRect(0, 0, 610, 29))
|
||||||
MainWindow.setMenuBar(self.menubar)
|
MainWindow.setMenuBar(self.menubar)
|
||||||
|
|
||||||
self.retranslateUi(MainWindow)
|
self.retranslateUi(MainWindow)
|
||||||
@ -178,6 +183,7 @@ class Ui_MainWindow(object):
|
|||||||
MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"MainWindow", None))
|
MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"MainWindow", None))
|
||||||
self.label_2.setText(QCoreApplication.translate("MainWindow", u"Available Titles", None))
|
self.label_2.setText(QCoreApplication.translate("MainWindow", u"Available Titles", None))
|
||||||
self.platform_tabs.setTabText(self.platform_tabs.indexOf(self.wii_tab), QCoreApplication.translate("MainWindow", u"Wii", None))
|
self.platform_tabs.setTabText(self.platform_tabs.indexOf(self.wii_tab), QCoreApplication.translate("MainWindow", u"Wii", None))
|
||||||
|
self.pack_vwii_mode_chkbox.setText(QCoreApplication.translate("MainWindow", u"Pack for vWii mode instead of Wii U mode", None))
|
||||||
self.platform_tabs.setTabText(self.platform_tabs.indexOf(self.vwii_tab), QCoreApplication.translate("MainWindow", u"vWii", None))
|
self.platform_tabs.setTabText(self.platform_tabs.indexOf(self.vwii_tab), QCoreApplication.translate("MainWindow", u"vWii", None))
|
||||||
self.tid_entry.setText("")
|
self.tid_entry.setText("")
|
||||||
self.tid_entry.setPlaceholderText(QCoreApplication.translate("MainWindow", u"Title ID", None))
|
self.tid_entry.setPlaceholderText(QCoreApplication.translate("MainWindow", u"Title ID", None))
|
||||||
@ -188,8 +194,8 @@ class Ui_MainWindow(object):
|
|||||||
self.log_text_browser.setHtml(QCoreApplication.translate("MainWindow", u"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
|
self.log_text_browser.setHtml(QCoreApplication.translate("MainWindow", u"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
|
||||||
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
|
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
|
||||||
"p, li { white-space: pre-wrap; }\n"
|
"p, li { white-space: pre-wrap; }\n"
|
||||||
"</style></head><body style=\" font-family:'Noto Sans'; font-size:10pt; font-weight:400; font-style:normal;\">\n"
|
"</style></head><body style=\" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;\">\n"
|
||||||
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;\"><br /></p></body></html>", None))
|
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><br /></p></body></html>", None))
|
||||||
self.pack_wad_chkbox.setText(QCoreApplication.translate("MainWindow", u"Pack WAD", None))
|
self.pack_wad_chkbox.setText(QCoreApplication.translate("MainWindow", u"Pack WAD", None))
|
||||||
self.wad_file_entry.setPlaceholderText(QCoreApplication.translate("MainWindow", u"File Name", None))
|
self.wad_file_entry.setPlaceholderText(QCoreApplication.translate("MainWindow", u"File Name", None))
|
||||||
self.keep_enc_chkbox.setText(QCoreApplication.translate("MainWindow", u"Keep encrypted contents", None))
|
self.keep_enc_chkbox.setText(QCoreApplication.translate("MainWindow", u"Keep encrypted contents", None))
|
||||||
|
@ -107,6 +107,13 @@
|
|||||||
</column>
|
</column>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="pack_vwii_mode_chkbox">
|
||||||
|
<property name="text">
|
||||||
|
<string>Pack for vWii mode instead of Wii U mode</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
@ -165,8 +172,8 @@
|
|||||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||||
p, li { white-space: pre-wrap; }
|
p, li { white-space: pre-wrap; }
|
||||||
</style></head><body style=" font-family:'Noto Sans'; font-size:10pt; font-weight:400; font-style:normal;">
|
</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;">
|
||||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html></string>
|
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html></string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@ -238,7 +245,7 @@ p, li { white-space: pre-wrap; }
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>610</width>
|
<width>610</width>
|
||||||
<height>30</height>
|
<height>29</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
pyside6
|
pyside6
|
||||||
nuitka
|
nuitka
|
||||||
git+https://github.com/NinjaCheetah/libWiipy
|
git+https://github.com/NinjaCheetah/libWiiPy
|
||||||
zstandard
|
zstandard
|
Loading…
x
Reference in New Issue
Block a user