mirror of
https://github.com/WB3000/nusdownloader.git
synced 2024-11-17 07:09:21 +01:00
Bugs fixed; Trucha features improved upon.
This commit is contained in:
parent
b27d83228c
commit
2937fb408d
1
NUS Downloader/Form1.Designer.cs
generated
1
NUS Downloader/Form1.Designer.cs
generated
@ -752,6 +752,7 @@
|
|||||||
this.button16.Size = new System.Drawing.Size(26, 26);
|
this.button16.Size = new System.Drawing.Size(26, 26);
|
||||||
this.button16.TabIndex = 44;
|
this.button16.TabIndex = 44;
|
||||||
this.button16.UseVisualStyleBackColor = true;
|
this.button16.UseVisualStyleBackColor = true;
|
||||||
|
this.button16.Click += new System.EventHandler(this.button16_Click);
|
||||||
//
|
//
|
||||||
// button13
|
// button13
|
||||||
//
|
//
|
||||||
|
@ -965,6 +965,13 @@ namespace NUS_Downloader
|
|||||||
System.Threading.Thread.Sleep(1000);
|
System.Threading.Thread.Sleep(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Re-Gather information...
|
||||||
|
byte[] tmdrefresh = FileLocationToByteArray(titledirectory + tmdfull);
|
||||||
|
tmdcontents = GetContentNames(tmd, ContentCount(tmdrefresh));
|
||||||
|
tmdsizes = GetContentSizes(tmd, ContentCount(tmdrefresh));
|
||||||
|
tmdhashes = GetContentHashes(tmd, ContentCount(tmdrefresh));
|
||||||
|
tmdindices = GetContentIndices(tmd, ContentCount(tmdrefresh));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
WriteStatus("Trucha Signing TMD...");
|
WriteStatus("Trucha Signing TMD...");
|
||||||
Array.Resize(ref tmd, 484 + (Convert.ToInt32(contentstrnum) * 36));
|
Array.Resize(ref tmd, 484 + (Convert.ToInt32(contentstrnum) * 36));
|
||||||
@ -1140,15 +1147,6 @@ namespace NUS_Downloader
|
|||||||
|
|
||||||
wadfs.Write(contbuf, 0, contbuf.Length);
|
wadfs.Write(contbuf, 0, contbuf.Length);
|
||||||
|
|
||||||
/*if (int.Parse(contentsizes[i], System.Globalization.NumberStyles.HexNumber) != contbuf.Length)
|
|
||||||
{
|
|
||||||
// Content size mismatch
|
|
||||||
WriteStatus(contentnames[i] + " wrote (0x" + Convert.ToString((wadfs.Length - contbuf.Length), 16) + ") (Mismatch)");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
WriteStatus(contentnames[i] + " wrote (0x" + Convert.ToString((wadfs.Length - contbuf.Length), 16) + ")");
|
|
||||||
} */
|
|
||||||
WriteStatus(contentnames[i] + " wrote (0x" + Convert.ToString((wadfs.Length - contbuf.Length), 16) + ")");
|
WriteStatus(contentnames[i] + " wrote (0x" + Convert.ToString((wadfs.Length - contbuf.Length), 16) + ")");
|
||||||
HandleMismatch(int.Parse(contentsizes[i], System.Globalization.NumberStyles.HexNumber), contbuf.Length);
|
HandleMismatch(int.Parse(contentsizes[i], System.Globalization.NumberStyles.HexNumber), contbuf.Length);
|
||||||
|
|
||||||
@ -1262,7 +1260,7 @@ namespace NUS_Downloader
|
|||||||
statusbox.Text = "";
|
statusbox.Text = "";
|
||||||
WriteStatus("NUS Downloader (NUSD)");
|
WriteStatus("NUS Downloader (NUSD)");
|
||||||
WriteStatus("You are running version: " + version);
|
WriteStatus("You are running version: " + version);
|
||||||
WriteStatus("This program coded by WB3000");
|
WriteStatus("This application created by WB3000");
|
||||||
WriteStatus("");
|
WriteStatus("");
|
||||||
string currentdir = Application.StartupPath;
|
string currentdir = Application.StartupPath;
|
||||||
if (currentdir.EndsWith(Convert.ToString(Path.DirectorySeparatorChar)) == false)
|
if (currentdir.EndsWith(Convert.ToString(Path.DirectorySeparatorChar)) == false)
|
||||||
@ -1287,8 +1285,8 @@ namespace NUS_Downloader
|
|||||||
else
|
else
|
||||||
WriteStatus("Database: OK");
|
WriteStatus("Database: OK");
|
||||||
|
|
||||||
if (IsWin7())
|
/* if (IsWin7())
|
||||||
WriteStatus("Windows 7 Features: Enabled");
|
WriteStatus("Windows 7 Features: Enabled"); */
|
||||||
|
|
||||||
WriteStatus("");
|
WriteStatus("");
|
||||||
WriteStatus("Special thanks to:");
|
WriteStatus("Special thanks to:");
|
||||||
@ -1569,12 +1567,33 @@ namespace NUS_Downloader
|
|||||||
break;
|
break;
|
||||||
case "version":
|
case "version":
|
||||||
string[] versions = ChildrenOfTheNode[z].InnerText.Split(',');
|
string[] versions = ChildrenOfTheNode[z].InnerText.Split(',');
|
||||||
XMLToolStripItem.DropDownItems.Add("Latest Version");
|
// Add to region things?
|
||||||
if (ChildrenOfTheNode[z].InnerText != "")
|
if (XMLToolStripItem.DropDownItems.Count > 0)
|
||||||
{
|
{
|
||||||
for (int y = 0; y < versions.Length; y++)
|
for (int b = 0; b < XMLToolStripItem.DropDownItems.Count; b++)
|
||||||
{
|
{
|
||||||
XMLToolStripItem.DropDownItems.Add("v" + versions[y]);
|
if (ChildrenOfTheNode[z].InnerText != "")
|
||||||
|
{
|
||||||
|
ToolStripMenuItem regitem = (ToolStripMenuItem)XMLToolStripItem.DropDownItems[b];
|
||||||
|
regitem.DropDownItems.Add("Latest Version");
|
||||||
|
for (int y = 0; y < versions.Length; y++)
|
||||||
|
{
|
||||||
|
regitem.DropDownItems.Add("v" + versions[y]);
|
||||||
|
}
|
||||||
|
// TODO : wat...
|
||||||
|
regitem.DropDownItemClicked += new ToolStripItemClickedEventHandler(wwitem_regionclicked);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
XMLToolStripItem.DropDownItems.Add("Latest Version");
|
||||||
|
if (ChildrenOfTheNode[z].InnerText != "")
|
||||||
|
{
|
||||||
|
for (int y = 0; y < versions.Length; y++)
|
||||||
|
{
|
||||||
|
XMLToolStripItem.DropDownItems.Add("v" + versions[y]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1717,6 +1736,7 @@ namespace NUS_Downloader
|
|||||||
void sysitem_versionclicked(object sender, ToolStripItemClickedEventArgs e)
|
void sysitem_versionclicked(object sender, ToolStripItemClickedEventArgs e)
|
||||||
{
|
{
|
||||||
titleidbox.Text = e.ClickedItem.OwnerItem.Text.Substring(0, 16);
|
titleidbox.Text = e.ClickedItem.OwnerItem.Text.Substring(0, 16);
|
||||||
|
|
||||||
if (e.ClickedItem.Text != "Latest Version")
|
if (e.ClickedItem.Text != "Latest Version")
|
||||||
{
|
{
|
||||||
if (e.ClickedItem.Text.Contains("v"))
|
if (e.ClickedItem.Text.Contains("v"))
|
||||||
@ -1753,7 +1773,7 @@ namespace NUS_Downloader
|
|||||||
{
|
{
|
||||||
ignoreticket.Checked = false;
|
ignoreticket.Checked = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Change WAD name if packed is already checked...
|
// Change WAD name if packed is already checked...
|
||||||
if (packbox.Checked)
|
if (packbox.Checked)
|
||||||
{
|
{
|
||||||
@ -1770,6 +1790,11 @@ namespace NUS_Downloader
|
|||||||
{
|
{
|
||||||
WriteStatus("\n" + e.ClickedItem.OwnerItem.ToolTipText);
|
WriteStatus("\n" + e.ClickedItem.OwnerItem.ToolTipText);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DEBUG:
|
||||||
|
//WriteStatus("item text: " + e.ClickedItem.Text);
|
||||||
|
//WriteStatus("Owner of item: " + e.ClickedItem.OwnerItem.Text);
|
||||||
|
//WriteStatus("Owner of Owner of item: " + e.ClickedItem.OwnerItem.OwnerItem.Text);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleMismatch(int contentsize, int actualsize)
|
void HandleMismatch(int contentsize, int actualsize)
|
||||||
@ -1778,7 +1803,7 @@ namespace NUS_Downloader
|
|||||||
{
|
{
|
||||||
if ((contentsize - actualsize) > 16)
|
if ((contentsize - actualsize) > 16)
|
||||||
{
|
{
|
||||||
statusbox.Text += " (BAD Mismatch)";
|
statusbox.Text += " (BAD Mismatch) (Dif: " + (contentsize - actualsize);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2455,10 +2480,10 @@ namespace NUS_Downloader
|
|||||||
|
|
||||||
contents[c].Size = new byte[8];
|
contents[c].Size = new byte[8];
|
||||||
// TODOCHECK THIS OVER
|
// TODOCHECK THIS OVER
|
||||||
contents[c].Size = InttoByteArray(contentbytes.Length, 8);
|
contents[c].Size = NewIntegertoByteArray(contentbytes.Length, 8);
|
||||||
|
|
||||||
contents[c].Index = new byte[2];
|
contents[c].Index = new byte[2];
|
||||||
contents[c].Index = InttoByteArray(c, 2);
|
contents[c].Index = NewIntegertoByteArray(c, 2);
|
||||||
|
|
||||||
contents[c].Type = new byte[2];
|
contents[c].Type = new byte[2];
|
||||||
contents[c].Type[1] = 0x01;
|
contents[c].Type[1] = 0x01;
|
||||||
@ -2606,7 +2631,7 @@ namespace NUS_Downloader
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
// Write all this stuff to the TMD...
|
// Collect everything into a single byte[]...
|
||||||
byte[] contentSection = new byte[contents.Length * 36];
|
byte[] contentSection = new byte[contents.Length * 36];
|
||||||
for (int h = 0; h < contents.Length; h++)
|
for (int h = 0; h < contents.Length; h++)
|
||||||
{
|
{
|
||||||
@ -2645,6 +2670,7 @@ namespace NUS_Downloader
|
|||||||
tmd = ZeroSignature(tmd);
|
tmd = ZeroSignature(tmd);
|
||||||
tmd = TruchaSign(tmd);
|
tmd = TruchaSign(tmd);
|
||||||
|
|
||||||
|
// Write all this stuff to the TMD...
|
||||||
FileStream testtmd = new FileStream(fileinfo[0] + fileinfo[1], FileMode.Open);
|
FileStream testtmd = new FileStream(fileinfo[0] + fileinfo[1], FileMode.Open);
|
||||||
testtmd.Write(tmd, 0, tmd.Length);
|
testtmd.Write(tmd, 0, tmd.Length);
|
||||||
testtmd.Close();
|
testtmd.Close();
|
||||||
@ -2736,5 +2762,121 @@ namespace NUS_Downloader
|
|||||||
//WriteStatus(" - Int->Byte[]: " + DisplayBytes(resultArray, " "));
|
//WriteStatus(" - Int->Byte[]: " + DisplayBytes(resultArray, " "));
|
||||||
return resultArray;
|
return resultArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void button16_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
// add trucha bug to content...
|
||||||
|
if (contentsEdit.SelectedIndex < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
WriteStatus("Attempting to add 'bugs' back into content...");
|
||||||
|
string[] fileinfo = shamelessvariablelabel.Text.Split(',');
|
||||||
|
byte[] new_hash_check = new byte[] {0x20, 0x07, 0x4B, 0x0B};
|
||||||
|
byte[] old_hash_check = new byte[] {0x20, 0x07, 0x23, 0xA2};
|
||||||
|
|
||||||
|
// If decrypted...
|
||||||
|
// - check right away for bug...
|
||||||
|
// - add bug, then end...
|
||||||
|
// if encrypted...
|
||||||
|
// - decrypt content...
|
||||||
|
// - find bug/patch...
|
||||||
|
// - recalculate hash...
|
||||||
|
// - write back into TMD...
|
||||||
|
// - trucha sign content...
|
||||||
|
|
||||||
|
if (contentsEdit.Items[contentsEdit.SelectedIndex].ToString().Contains(".app"))
|
||||||
|
{
|
||||||
|
// Content is decrypted/new to the title...
|
||||||
|
string filename = contentsEdit.Items[contentsEdit.SelectedIndex].ToString().Substring(contentsEdit.Items[contentsEdit.SelectedIndex].ToString().IndexOf("] [") + 3, 12);
|
||||||
|
byte[] contentbt = FileLocationToByteArray(fileinfo[0] + filename);
|
||||||
|
|
||||||
|
int[] oldresults = ByteArrayContainsByteArray(contentbt, old_hash_check);
|
||||||
|
int[] newresults = ByteArrayContainsByteArray(contentbt, new_hash_check);
|
||||||
|
|
||||||
|
if (oldresults[0] != 0)
|
||||||
|
{
|
||||||
|
WriteStatus(String.Format(" - {0} Old-school ES Signing Fix(es) Found...", oldresults[0]));
|
||||||
|
for (int s = 1; s < oldresults.Length - 1; s++)
|
||||||
|
{
|
||||||
|
PatchTrucha(contentbt, oldresults[s]);
|
||||||
|
WriteStatus(String.Format(" - Bug restored at 0x{0}", int.Parse(oldresults[s].ToString(), System.Globalization.NumberStyles.HexNumber)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newresults[0] != 0)
|
||||||
|
{
|
||||||
|
WriteStatus(String.Format(" - {0} New-school ES Signing Fix(es) Found...", newresults[0]));
|
||||||
|
for (int s = 1; s < newresults.Length - 1; s++)
|
||||||
|
{
|
||||||
|
PatchTrucha(contentbt, newresults[s]);
|
||||||
|
WriteStatus(String.Format(" + Bug restored at 0x{0}.", int.Parse(newresults[s].ToString(), System.Globalization.NumberStyles.HexNumber)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Content is part of original TMD and must be decrypted...
|
||||||
|
string filename = contentsEdit.Items[contentsEdit.SelectedIndex].ToString().Substring(contentsEdit.Items[contentsEdit.SelectedIndex].ToString().IndexOf("] [") + 3, 8);
|
||||||
|
|
||||||
|
byte[] ticket = FileLocationToByteArray(fileinfo[0] + "cetk");
|
||||||
|
byte[] etitlekey = new byte[16];
|
||||||
|
for (int a = 0; a < 16; a++)
|
||||||
|
{
|
||||||
|
etitlekey[a] = ticket[0x1BF + a];
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Add more key support
|
||||||
|
byte[] commonkey = LoadCommonKey(@"\key.bin");
|
||||||
|
|
||||||
|
// IV (TITLEID00000000)
|
||||||
|
byte[] iv = new byte[16];
|
||||||
|
for (int b = 0; b < 8; b++)
|
||||||
|
{
|
||||||
|
iv[b] = ticket[0x1DC + b];
|
||||||
|
}
|
||||||
|
for (int c = 0; c < 8; c++)
|
||||||
|
{
|
||||||
|
iv[c + 8] = 0x00;
|
||||||
|
}
|
||||||
|
|
||||||
|
initCrypt(iv, commonkey);
|
||||||
|
byte[] dtitlekey = Decrypt(etitlekey);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private int[] ByteArrayContainsByteArray(byte[] bigboy, byte[] littleman)
|
||||||
|
{
|
||||||
|
// bigboy.Contains(littleman);
|
||||||
|
// returns offset { cnt , ofst };
|
||||||
|
int[] offset = new int[5];
|
||||||
|
for (int a = 0; a < (bigboy.Length - littleman.Length); a++)
|
||||||
|
{
|
||||||
|
int matches = 0;
|
||||||
|
for (int b = 0; b < littleman.Length; b++)
|
||||||
|
{
|
||||||
|
if (bigboy[a + b] == littleman[b])
|
||||||
|
matches += 1;
|
||||||
|
}
|
||||||
|
if (matches == littleman.Length)
|
||||||
|
{
|
||||||
|
offset[offset[0] + 1] = a;
|
||||||
|
offset[0] += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] PatchTrucha(byte[] content, int offset)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
content[offset + i] = 0;
|
||||||
|
}
|
||||||
|
return content;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -253,7 +253,7 @@
|
|||||||
XTesb3QPLh88M+QwdP6m681Lt7xuXbu94vbgcOjwnZHokdE77DtTd1PuvriXeW/h/sYH6AdFD6UeVjxS
|
XTesb3QPLh88M+QwdP6m681Lt7xuXbu94vbgcOjwnZHokdE77DtTd1PuvriXeW/h/sYH6AdFD6UeVjxS
|
||||||
fNTws+7PbaOWo6fHXMf6Hwc/vj/OGn/2S8Yv7ycKnpCfVEyqTDZPmU2dmnafvvF05dOJZ+nPFmYKf5X+
|
fNTws+7PbaOWo6fHXMf6Hwc/vj/OGn/2S8Yv7ycKnpCfVEyqTDZPmU2dmnafvvF05dOJZ+nPFmYKf5X+
|
||||||
tfa5zvMffnP8rX82YnbiBf/Fp99LXsq/PPRq2aueuYC5R69TXy/MF72Rf3P4LeNt37vwd5MLWe+x7ys/
|
tfa5zvMffnP8rX82YnbiBf/Fp99LXsq/PPRq2aueuYC5R69TXy/MF72Rf3P4LeNt37vwd5MLWe+x7ys/
|
||||||
6H7o/ujz8cGn1E+f/gUDmPP8usTo0wAAAAlwSFlzAAALDwAACw8BkvkDpQAAAntJREFUWEftl6GOgkEM
|
6H7o/ujz8cGn1E+f/gUDmPP8usTo0wAAAAlwSFlzAAALDgAACw4BQL7hQQAAAntJREFUWEftl6GOgkEM
|
||||||
hHlwDAKHw+EwKCQWgcOikQjO8Ax795FMMtf0390EfsKRExsC2+3OtJ1umZRSJp+4PpIUiXorYrfb7QdT
|
hHlwDAKHw+EwKCQWgcOikQjO8Ax795FMMtf0390EfsKRExsC2+3OtJ1umZRSJp+4PpIUiXorYrfb7QdT
|
||||||
XkG1vexMF7Gv67Vo1cr2crmU8/k8CI6zAJQvgeXMarUqy+Wy7Pf7X+d973A4VH07tiYxHHOh1vF4TJ3z
|
XkG1vexMF7Gv67Vo1cr2crmU8/k8CI6zAJQvgeXMarUqy+Wy7Pf7X+d973A4VH07tiYxHHOh1vF4TJ3z
|
||||||
+2KxKPP5vGy329QG4iKAPwHdbDZlOp2W2Wx29+HBWa/Xg3u1IDeJEV1AcDErAw1g2QCOlQXgdDrd90SC
|
+2KxKPP5vGy329QG4iKAPwHdbDZlOp2W2Wx29+HBWa/Xg3u1IDeJEV1AcDErAw1g2QCOlQXgdDrd90SC
|
||||||
@ -314,7 +314,7 @@
|
|||||||
XTesb3QPLh88M+QwdP6m681Lt7xuXbu94vbgcOjwnZHokdE77DtTd1PuvriXeW/h/sYH6AdFD6UeVjxS
|
XTesb3QPLh88M+QwdP6m681Lt7xuXbu94vbgcOjwnZHokdE77DtTd1PuvriXeW/h/sYH6AdFD6UeVjxS
|
||||||
fNTws+7PbaOWo6fHXMf6Hwc/vj/OGn/2S8Yv7ycKnpCfVEyqTDZPmU2dmnafvvF05dOJZ+nPFmYKf5X+
|
fNTws+7PbaOWo6fHXMf6Hwc/vj/OGn/2S8Yv7ycKnpCfVEyqTDZPmU2dmnafvvF05dOJZ+nPFmYKf5X+
|
||||||
tfa5zvMffnP8rX82YnbiBf/Fp99LXsq/PPRq2aueuYC5R69TXy/MF72Rf3P4LeNt37vwd5MLWe+x7ys/
|
tfa5zvMffnP8rX82YnbiBf/Fp99LXsq/PPRq2aueuYC5R69TXy/MF72Rf3P4LeNt37vwd5MLWe+x7ys/
|
||||||
6H7o/ujz8cGn1E+f/gUDmPP8usTo0wAAAAlwSFlzAAALDwAACw8BkvkDpQAAAwJJREFUWEfdmNG1IUEQ
|
6H7o/ujz8cGn1E+f/gUDmPP8usTo0wAAAAlwSFlzAAALDgAACw4BQL7hQQAAAwJJREFUWEfdmNG1IUEQ
|
||||||
hrEBIAIyQASIgI1giYCzASADIkAEiAARLBFgA1g874Ne3+ypuT013YN73Qf3Yc7M9HRX1V/1199NyhiT
|
hrEBIAIyQASIgI1giYCzASADIkAEiAARLBFgA1g874Ne3+ypuT013YN73Qf3Yc7M9HRX1V/1199NyhiT
|
||||||
+orXlwRFoV4S2GazMcvl0hwOhysGN+NeCli/3zfFYvFajpRJp9PBnff5fB4D+DLA2u12AESuWq0WAdjp
|
+orXlwRFoV4S2GazMcvl0hwOhysGN+NeCli/3zfFYvFajpRJp9PBnff5fB4D+DLA2u12AESuWq0WAdjp
|
||||||
/oyAewlgVMoG1Ww2zeVyMeVyORxPpzJmtVqF4EJg+/3eYKDX6wX3wWAQPvOuL76Px2OzXq+9PHfxHz+T
|
/oyAewlgVMoG1Ww2zeVyMeVyORxPpzJmtVqF4EJg+/3eYKDX6wX3wWAQPvOuL76Px2OzXq+9PHfxHz+T
|
||||||
|
Loading…
Reference in New Issue
Block a user