Add fake ticket and cert generation

This commit is contained in:
Xpl0itU 2023-07-23 17:28:20 +02:00
parent 3c44a9751d
commit 7e8c2facdf
5 changed files with 100 additions and 20 deletions

View file

@ -1,6 +1,7 @@
package wiiudownloader
import (
"bytes"
"fmt"
"os"
"path"
@ -49,3 +50,26 @@ func getDefaultCert(progressWindow *ProgressWindow, client *grab.Client) ([]byte
}
return nil, fmt.Errorf("failed to download OSv10 cetk, length: %d", len(cetkData))
}
func GenerateCert(tmdData []byte, contentCount uint16, progressWindow *ProgressWindow, client *grab.Client) (bytes.Buffer, error) {
cert := bytes.Buffer{}
cert0, err := getCert(tmdData, 0, contentCount)
if err != nil {
return bytes.Buffer{}, err
}
cert.Write(cert0)
cert1, err := getCert(tmdData, 1, contentCount)
if err != nil {
return bytes.Buffer{}, err
}
cert.Write(cert1)
defaultCert, err := getDefaultCert(progressWindow, client)
if err != nil {
return bytes.Buffer{}, err
}
cert.Write(defaultCert)
return cert, nil
}

View file

@ -1,12 +1,17 @@
package main
import (
"bytes"
"encoding/binary"
"fmt"
"os"
"path/filepath"
"strconv"
"strings"
"sync"
wiiudownloader "github.com/Xpl0itU/WiiUDownloader"
"github.com/cavaliergopher/grab/v3"
"github.com/gotk3/gotk3/glib"
"github.com/gotk3/gotk3/gtk"
)
@ -218,6 +223,72 @@ func (mw *MainWindow) ShowAll() {
})
toolsSubMenu.Append(decryptContentsMenuItem)
generateFakeTicketCert, err := gtk.MenuItemNewWithLabel("Generate fake ticket and cert")
if err != nil {
mw.logger.Fatal("Unable to create menu item:", err)
}
generateFakeTicketCert.Connect("activate", func() {
dialog, err := gtk.FileChooserNativeDialogNew("Select the game's title.tmd", mw.window, gtk.FILE_CHOOSER_ACTION_OPEN, "Select", "Cancel")
if err != nil {
mw.logger.Fatal("Unable to create dialog:", err)
}
tmdFilter, err := gtk.FileFilterNew()
if err != nil {
return
}
tmdFilter.AddPattern("*.tmd")
dialog.AddFilter(tmdFilter)
res := dialog.Run()
if res != int(gtk.RESPONSE_ACCEPT) {
return
}
tmdPath := dialog.FileChooser.GetFilename()
parentDir := filepath.Dir(tmdPath)
tmdData, err := os.ReadFile(tmdPath)
if err != nil {
return
}
var contentCount uint16
if err := binary.Read(bytes.NewReader(tmdData[478:480]), binary.BigEndian, &contentCount); err != nil {
return
}
var titleVersion uint16
if err := binary.Read(bytes.NewReader(tmdData[476:478]), binary.BigEndian, &titleVersion); err != nil {
return
}
var titleID uint64
if err := binary.Read(bytes.NewReader(tmdData[0x018C:0x0194]), binary.BigEndian, &titleID); err != nil {
return
}
titleKey, err := wiiudownloader.GenerateKey(fmt.Sprintf("%016x", titleID))
if err != nil {
return
}
wiiudownloader.GenerateTicket(filepath.Join(parentDir, "title.tik"), titleID, titleKey, titleVersion)
cert, err := wiiudownloader.GenerateCert(tmdData, contentCount, &mw.progressWindow, grab.NewClient())
if err != nil {
return
}
certPath := filepath.Join(parentDir, "title.cert")
certFile, err := os.Create(certPath)
if err != nil {
return
}
if err := binary.Write(certFile, binary.BigEndian, cert.Bytes()); err != nil {
return
}
defer certFile.Close()
})
toolsSubMenu.Append(generateFakeTicketCert)
toolsMenu.SetSubmenu(toolsSubMenu)
menuBar.Append(toolsMenu)
mainvBox.PackStart(menuBar, false, false, 0)

View file

@ -175,11 +175,11 @@ func DownloadTitle(titleID string, outputDirectory string, doDecryption bool, pr
tikPath := filepath.Join(outputDir, "title.tik")
downloadURL = fmt.Sprintf("%s/%s", baseURL, "cetk")
if err := downloadFile(progressWindow, client, downloadURL, tikPath, false); err != nil {
titleKey, err := generateKey(titleID)
titleKey, err := GenerateKey(titleID)
if err != nil {
return err
}
if err := generateTicket(tikPath, titleEntry.TitleID, titleKey, titleVersion); err != nil {
if err := GenerateTicket(tikPath, titleEntry.TitleID, titleKey, titleVersion); err != nil {
return err
}
}
@ -194,25 +194,10 @@ func DownloadTitle(titleID string, outputDirectory string, doDecryption bool, pr
return err
}
cert := bytes.Buffer{}
cert0, err := getCert(tmdData, 0, contentCount)
cert, err := GenerateCert(tmdData, contentCount, progressWindow, client)
if err != nil {
return err
}
cert.Write(cert0)
cert1, err := getCert(tmdData, 1, contentCount)
if err != nil {
return err
}
cert.Write(cert1)
defaultCert, err := getDefaultCert(progressWindow, client)
if err != nil {
return err
}
cert.Write(defaultCert)
certPath := filepath.Join(outputDir, "title.cert")
certFile, err := os.Create(certPath)

View file

@ -32,7 +32,7 @@ func encryptAES(data []byte, key []byte, iv []byte) ([]byte, error) {
return encrypted, nil
}
func generateKey(tid string) ([]byte, error) {
func GenerateKey(tid string) ([]byte, error) {
tmp := []byte(tid)
for tmp[0] == '0' && tmp[1] == '0' {
tmp = tmp[2:]

View file

@ -6,7 +6,7 @@ import (
"os"
)
func generateTicket(path string, titleID uint64, titleKey []byte, titleVersion uint16) error {
func GenerateTicket(path string, titleID uint64, titleKey []byte, titleVersion uint16) error {
ticketFile, err := os.Create(path)
if err != nil {
return err