mirror of
https://github.com/NinjaCheetah/libWiiPy.git
synced 2025-04-26 05:11:02 -04:00
Added methods to fakesign a TMD or Ticket
This commit is contained in:
parent
535de7f228
commit
a56fa6e051
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
import io
|
import io
|
||||||
import binascii
|
import binascii
|
||||||
|
import hashlib
|
||||||
from dataclasses import dataclass as _dataclass
|
from dataclasses import dataclass as _dataclass
|
||||||
from .crypto import decrypt_title_key
|
from .crypto import decrypt_title_key
|
||||||
from typing import List
|
from typing import List
|
||||||
@ -162,8 +163,7 @@ class Ticket:
|
|||||||
|
|
||||||
def dump(self) -> bytes:
|
def dump(self) -> bytes:
|
||||||
"""
|
"""
|
||||||
Dumps the Ticket object back into bytes. This also sets the raw Ticket attribute of Ticket object to the
|
Dumps the Ticket object back into bytes.
|
||||||
dumped data, and triggers load() again to ensure that the raw data and object match.
|
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
@ -226,6 +226,37 @@ class Ticket:
|
|||||||
ticket_data += title_limit_data
|
ticket_data += title_limit_data
|
||||||
return ticket_data
|
return ticket_data
|
||||||
|
|
||||||
|
def fakesign(self) -> None:
|
||||||
|
"""
|
||||||
|
Fakesigns this Ticket for the trucha bug.
|
||||||
|
|
||||||
|
This is done by brute-forcing a Ticket body hash starting with 00, causing it to pass signature verification on
|
||||||
|
older IOS versions that incorrectly check the hash using strcmp() instead of memcmp(). The signature will also
|
||||||
|
be erased and replaced with all NULL bytes.
|
||||||
|
|
||||||
|
This modifies the Ticket object in place. You will need to call this method after any changes, and before
|
||||||
|
dumping the Ticket object back into bytes.
|
||||||
|
"""
|
||||||
|
# Clear the signature, so that the hash derived from it is guaranteed to always be
|
||||||
|
# '0000000000000000000000000000000000000000'.
|
||||||
|
self.signature = b'\x00' * 256
|
||||||
|
current_int = 0
|
||||||
|
test_hash = ''
|
||||||
|
while test_hash[:2] != '00':
|
||||||
|
current_int += 1
|
||||||
|
# We're using the first 2 bytes of this unused region of the Ticket as a 16-bit integer, and incrementing
|
||||||
|
# that to brute-force the hash we need.
|
||||||
|
data_to_edit = self.unknown2
|
||||||
|
data_to_edit = int.to_bytes(current_int, 2) + data_to_edit[2:]
|
||||||
|
self.unknown2 = data_to_edit
|
||||||
|
# Trim off the first 320 bytes, because we're only looking for the hash of the Ticket's body.
|
||||||
|
# This is a try-except because an OverflowError will be thrown if the number being used to brute-force the
|
||||||
|
# hash gets too big, as it is only a 16-bit integer. If that happens, then fakesigning has failed.
|
||||||
|
try:
|
||||||
|
test_hash = hashlib.sha1(self.dump()[320:]).hexdigest()
|
||||||
|
except OverflowError:
|
||||||
|
raise Exception("An error occurred during fakesigning. Ticket could not be fakesigned!")
|
||||||
|
|
||||||
def get_title_id(self) -> str:
|
def get_title_id(self) -> str:
|
||||||
"""
|
"""
|
||||||
Gets the Title ID of the ticket's associated title.
|
Gets the Title ID of the ticket's associated title.
|
||||||
|
@ -234,3 +234,18 @@ class Title:
|
|||||||
"""
|
"""
|
||||||
# Load the decrypted content.
|
# Load the decrypted content.
|
||||||
self.content.load_content(dec_content, index, self.ticket.get_title_key())
|
self.content.load_content(dec_content, index, self.ticket.get_title_key())
|
||||||
|
|
||||||
|
def fakesign(self) -> None:
|
||||||
|
"""
|
||||||
|
Fakesigns this Title for the trucha bug.
|
||||||
|
|
||||||
|
This is done by brute-forcing a TMD and Ticket body hash starting with 00, causing it to pass signature
|
||||||
|
verification on older IOS versions that incorrectly check the hash using strcmp() instead of memcmp(). The TMD
|
||||||
|
and Ticket signatures will also be erased and replaced with all NULL bytes.
|
||||||
|
|
||||||
|
This modifies the TMD and Ticket objects that are part of this Title in place. You will need to call this method
|
||||||
|
after any changes to the TMD or Ticket, and before dumping the Title object into a WAD to ensure that the WAD
|
||||||
|
is properly fakesigned.
|
||||||
|
"""
|
||||||
|
self.tmd.fakesign()
|
||||||
|
self.ticket.fakesign()
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
import io
|
import io
|
||||||
import binascii
|
import binascii
|
||||||
|
import hashlib
|
||||||
import struct
|
import struct
|
||||||
from typing import List
|
from typing import List
|
||||||
from ..types import _ContentRecord
|
from ..types import _ContentRecord
|
||||||
@ -159,8 +160,7 @@ class TMD:
|
|||||||
|
|
||||||
def dump(self) -> bytes:
|
def dump(self) -> bytes:
|
||||||
"""
|
"""
|
||||||
Dumps the TMD object back into bytes. This also sets the raw TMD attribute of TMD object to the dumped data,
|
Dumps the TMD object back into bytes.
|
||||||
and triggers load() again to ensure that the raw data and object match.
|
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
@ -227,6 +227,33 @@ class TMD:
|
|||||||
tmd_data += content_data
|
tmd_data += content_data
|
||||||
return tmd_data
|
return tmd_data
|
||||||
|
|
||||||
|
def fakesign(self) -> None:
|
||||||
|
"""
|
||||||
|
Fakesigns this TMD for the trucha bug.
|
||||||
|
|
||||||
|
This is done by brute-forcing a TMD body hash starting with 00, causing it to pass signature verification on
|
||||||
|
older IOS versions that incorrectly check the hash using strcmp() instead of memcmp(). The signature will also
|
||||||
|
be erased and replaced with all NULL bytes.
|
||||||
|
|
||||||
|
This modifies the TMD object in place. You will need to call this method after any changes, and before dumping
|
||||||
|
the TMD object back into bytes.
|
||||||
|
"""
|
||||||
|
# Clear the signature, so that the hash derived from it is guaranteed to always be
|
||||||
|
# '0000000000000000000000000000000000000000'.
|
||||||
|
self.signature = b'\x00' * 256
|
||||||
|
current_int = 0
|
||||||
|
test_hash = ''
|
||||||
|
while test_hash[:2] != '00':
|
||||||
|
current_int += 1
|
||||||
|
self.minor_version = current_int
|
||||||
|
# Trim off the first 320 bytes, because we're only looking for the hash of the TMD's body.
|
||||||
|
# This is a try-except because an OverflowError will be thrown if the number being used to brute-force the
|
||||||
|
# hash gets too big, as it is only a 16-bit integer. If that happens, then fakesigning has failed.
|
||||||
|
try:
|
||||||
|
test_hash = hashlib.sha1(self.dump()[320:]).hexdigest()
|
||||||
|
except OverflowError:
|
||||||
|
raise Exception("An error occurred during fakesigning. TMD could not be fakesigned!")
|
||||||
|
|
||||||
def get_title_region(self) -> str:
|
def get_title_region(self) -> str:
|
||||||
"""
|
"""
|
||||||
Gets the region of the TMD's associated title.
|
Gets the region of the TMD's associated title.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user