Some improvements to content editing. Has not been tested, but is implemented.

This commit is contained in:
givememystuffplease 2009-07-17 16:22:58 +00:00
parent 55a96ca677
commit ab6575995f
7 changed files with 652 additions and 84 deletions

View File

@ -95,7 +95,8 @@
this.shamelessvariablelabel = new System.Windows.Forms.Label();
this.button3 = new System.Windows.Forms.Button();
this.contentsEdit = new System.Windows.Forms.ListBox();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.contentModBox = new System.Windows.Forms.GroupBox();
this.button16 = new System.Windows.Forms.Button();
this.button13 = new System.Windows.Forms.Button();
this.button15 = new System.Windows.Forms.Button();
this.button14 = new System.Windows.Forms.Button();
@ -106,10 +107,11 @@
this.button10 = new System.Windows.Forms.Button();
this.radioButton1 = new System.Windows.Forms.RadioButton();
this.radioButton2 = new System.Windows.Forms.RadioButton();
this.button17 = new System.Windows.Forms.Button();
this.databaseStrip.SuspendLayout();
this.tmdgpbox.SuspendLayout();
this.ticketgpbox.SuspendLayout();
this.groupBox1.SuspendLayout();
this.contentModBox.SuspendLayout();
this.SuspendLayout();
//
// TMDButton
@ -685,7 +687,7 @@
//
this.button7.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
this.button7.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.button7.Location = new System.Drawing.Point(278, 459);
this.button7.Location = new System.Drawing.Point(278, 322);
this.button7.Name = "button7";
this.button7.Size = new System.Drawing.Size(249, 27);
this.button7.TabIndex = 28;
@ -728,43 +730,57 @@
this.contentsEdit.FormattingEnabled = true;
this.contentsEdit.Location = new System.Drawing.Point(9, 19);
this.contentsEdit.Name = "contentsEdit";
this.contentsEdit.Size = new System.Drawing.Size(138, 134);
this.contentsEdit.ScrollAlwaysVisible = true;
this.contentsEdit.Size = new System.Drawing.Size(198, 173);
this.contentsEdit.TabIndex = 32;
//
// groupBox1
// contentModBox
//
this.groupBox1.Controls.Add(this.button13);
this.groupBox1.Controls.Add(this.button15);
this.groupBox1.Controls.Add(this.button14);
this.groupBox1.Controls.Add(this.button12);
this.groupBox1.Controls.Add(this.contentsEdit);
this.groupBox1.Controls.Add(this.button8);
this.groupBox1.Controls.Add(this.button11);
this.groupBox1.Controls.Add(this.button9);
this.groupBox1.Controls.Add(this.button10);
this.groupBox1.Location = new System.Drawing.Point(278, 290);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(249, 160);
this.groupBox1.TabIndex = 41;
this.groupBox1.TabStop = false;
this.groupBox1.Text = "Edit Title Contents";
this.contentModBox.Controls.Add(this.button16);
this.contentModBox.Controls.Add(this.button13);
this.contentModBox.Controls.Add(this.button15);
this.contentModBox.Controls.Add(this.button14);
this.contentModBox.Controls.Add(this.button12);
this.contentModBox.Controls.Add(this.contentsEdit);
this.contentModBox.Controls.Add(this.button8);
this.contentModBox.Controls.Add(this.button11);
this.contentModBox.Controls.Add(this.button9);
this.contentModBox.Controls.Add(this.button10);
this.contentModBox.Location = new System.Drawing.Point(268, 208);
this.contentModBox.Name = "contentModBox";
this.contentModBox.Size = new System.Drawing.Size(249, 272);
this.contentModBox.TabIndex = 41;
this.contentModBox.TabStop = false;
this.contentModBox.Text = "Edit Title Contents";
this.contentModBox.Visible = false;
//
// button16
//
this.button16.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
this.button16.Image = global::NUS_Downloader.Properties.Resources.bug_add;
this.button16.Location = new System.Drawing.Point(136, 198);
this.button16.Name = "button16";
this.button16.Size = new System.Drawing.Size(26, 26);
this.button16.TabIndex = 44;
this.button16.UseVisualStyleBackColor = true;
//
// button13
//
this.button13.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
this.button13.Image = global::NUS_Downloader.Properties.Resources.bug_add;
this.button13.Location = new System.Drawing.Point(217, 53);
this.button13.Image = global::NUS_Downloader.Properties.Resources.link;
this.button13.Location = new System.Drawing.Point(104, 198);
this.button13.Name = "button13";
this.button13.Size = new System.Drawing.Size(26, 26);
this.button13.TabIndex = 43;
this.button13.UseVisualStyleBackColor = true;
this.button13.Click += new System.EventHandler(this.button13_Click);
//
// button15
//
this.button15.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
this.button15.Location = new System.Drawing.Point(153, 95);
this.button15.Location = new System.Drawing.Point(9, 235);
this.button15.Name = "button15";
this.button15.Size = new System.Drawing.Size(90, 26);
this.button15.Size = new System.Drawing.Size(70, 26);
this.button15.TabIndex = 42;
this.button15.Text = "Revert";
this.button15.UseVisualStyleBackColor = true;
@ -773,18 +789,19 @@
// button14
//
this.button14.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
this.button14.Location = new System.Drawing.Point(153, 127);
this.button14.Location = new System.Drawing.Point(85, 235);
this.button14.Name = "button14";
this.button14.Size = new System.Drawing.Size(90, 26);
this.button14.Size = new System.Drawing.Size(158, 26);
this.button14.TabIndex = 41;
this.button14.Text = "Overwrite";
this.button14.Text = "Overwrite Title Contents...";
this.button14.UseVisualStyleBackColor = true;
this.button14.Click += new System.EventHandler(this.button14_Click);
//
// button12
//
this.button12.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
this.button12.Image = global::NUS_Downloader.Properties.Resources.connect;
this.button12.Location = new System.Drawing.Point(217, 19);
this.button12.Image = ((System.Drawing.Image)(resources.GetObject("button12.Image")));
this.button12.Location = new System.Drawing.Point(72, 198);
this.button12.Name = "button12";
this.button12.Size = new System.Drawing.Size(26, 26);
this.button12.TabIndex = 40;
@ -794,8 +811,8 @@
// button8
//
this.button8.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
this.button8.Image = global::NUS_Downloader.Properties.Resources.arrow_up;
this.button8.Location = new System.Drawing.Point(153, 19);
this.button8.Image = ((System.Drawing.Image)(resources.GetObject("button8.Image")));
this.button8.Location = new System.Drawing.Point(213, 19);
this.button8.Name = "button8";
this.button8.Size = new System.Drawing.Size(26, 26);
this.button8.TabIndex = 33;
@ -805,8 +822,8 @@
// button11
//
this.button11.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
this.button11.Image = global::NUS_Downloader.Properties.Resources.package_add;
this.button11.Location = new System.Drawing.Point(185, 19);
this.button11.Image = ((System.Drawing.Image)(resources.GetObject("button11.Image")));
this.button11.Location = new System.Drawing.Point(9, 198);
this.button11.Name = "button11";
this.button11.Size = new System.Drawing.Size(26, 26);
this.button11.TabIndex = 36;
@ -816,8 +833,8 @@
// button9
//
this.button9.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
this.button9.Image = global::NUS_Downloader.Properties.Resources.arrow_down;
this.button9.Location = new System.Drawing.Point(153, 53);
this.button9.Image = ((System.Drawing.Image)(resources.GetObject("button9.Image")));
this.button9.Location = new System.Drawing.Point(213, 53);
this.button9.Name = "button9";
this.button9.Size = new System.Drawing.Size(26, 26);
this.button9.TabIndex = 34;
@ -827,8 +844,8 @@
// button10
//
this.button10.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
this.button10.Image = global::NUS_Downloader.Properties.Resources.package_delete;
this.button10.Location = new System.Drawing.Point(185, 53);
this.button10.Image = ((System.Drawing.Image)(resources.GetObject("button10.Image")));
this.button10.Location = new System.Drawing.Point(41, 198);
this.button10.Name = "button10";
this.button10.Size = new System.Drawing.Size(26, 26);
this.button10.TabIndex = 35;
@ -839,7 +856,7 @@
//
this.radioButton1.BackColor = System.Drawing.Color.Transparent;
this.radioButton1.Checked = true;
this.radioButton1.Image = global::NUS_Downloader.Properties.Resources.wilolgoi;
this.radioButton1.Image = ((System.Drawing.Image)(resources.GetObject("radioButton1.Image")));
this.radioButton1.Location = new System.Drawing.Point(12, 385);
this.radioButton1.Name = "radioButton1";
this.radioButton1.Size = new System.Drawing.Size(60, 31);
@ -850,7 +867,7 @@
//
// radioButton2
//
this.radioButton2.Image = global::NUS_Downloader.Properties.Resources.dsi;
this.radioButton2.Image = ((System.Drawing.Image)(resources.GetObject("radioButton2.Image")));
this.radioButton2.ImageAlign = System.Drawing.ContentAlignment.TopCenter;
this.radioButton2.Location = new System.Drawing.Point(78, 385);
this.radioButton2.Name = "radioButton2";
@ -859,16 +876,27 @@
this.radioButton2.UseVisualStyleBackColor = true;
this.radioButton2.CheckedChanged += new System.EventHandler(this.radioButton2_CheckedChanged);
//
// button17
//
this.button17.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
this.button17.Location = new System.Drawing.Point(278, 290);
this.button17.Name = "button17";
this.button17.Size = new System.Drawing.Size(249, 26);
this.button17.TabIndex = 42;
this.button17.Text = "Modify Individual Titles...";
this.button17.UseVisualStyleBackColor = true;
this.button17.Click += new System.EventHandler(this.button17_Click);
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(539, 492);
this.Controls.Add(this.groupBox1);
this.Controls.Add(this.contentModBox);
this.Controls.Add(this.button17);
this.Controls.Add(this.button3);
this.Controls.Add(this.shamelessvariablelabel);
this.Controls.Add(this.label12);
this.Controls.Add(this.button6);
this.Controls.Add(this.button1);
this.Controls.Add(this.ticketgpbox);
this.Controls.Add(this.button5);
@ -876,8 +904,8 @@
this.Controls.Add(this.tmdgpbox);
this.Controls.Add(this.truchabox);
this.Controls.Add(this.databaseButton);
this.Controls.Add(this.button7);
this.Controls.Add(this.decryptbox);
this.Controls.Add(this.button7);
this.Controls.Add(this.ignoreticket);
this.Controls.Add(this.wadnamebox);
this.Controls.Add(this.getcerts);
@ -894,6 +922,7 @@
this.Controls.Add(this.downloadstartbtn);
this.Controls.Add(this.titleidbox);
this.Controls.Add(this.TMDButton);
this.Controls.Add(this.button6);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.MaximizeBox = false;
@ -907,7 +936,7 @@
this.tmdgpbox.PerformLayout();
this.ticketgpbox.ResumeLayout(false);
this.ticketgpbox.PerformLayout();
this.groupBox1.ResumeLayout(false);
this.contentModBox.ResumeLayout(false);
this.ResumeLayout(false);
this.PerformLayout();
@ -987,10 +1016,12 @@
private System.Windows.Forms.Button button10;
private System.Windows.Forms.Button button11;
private System.Windows.Forms.Button button12;
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.GroupBox contentModBox;
private System.Windows.Forms.Button button14;
private System.Windows.Forms.Button button15;
private System.Windows.Forms.Button button13;
private System.Windows.Forms.Button button16;
private System.Windows.Forms.Button button17;
}
}

View File

@ -6,6 +6,7 @@ using System.Security.Cryptography;
using System.Xml;
using System.Drawing;
namespace NUS_Downloader
{
public partial class Form1 : Form
@ -19,8 +20,6 @@ namespace NUS_Downloader
static bool dsidecrypt = false;
const string certs_MD5 = "7677AD47BAA5D6E3E313E72661FBDC16";
// Images do not compare unless globalized...
Image green = Properties.Resources.bullet_green;
Image orange = Properties.Resources.bullet_orange;
@ -40,6 +39,19 @@ namespace NUS_Downloader
public int FooterSize;
};
public struct TitleContent
{
public byte[] ContentID;
public byte[] Index;
public byte[] Type;
public byte[] Size;
public byte[] SHAHash;
};
public enum ContentTypes : int {
Shared = 0x8001, Normal = 0x0001
}
// This is the standard entry to the GUI
public Form1()
{
@ -141,6 +153,8 @@ namespace NUS_Downloader
{
this.Text = "NUSD - " + version + " - WB3000";
this.Size = this.MinimumSize;
}
private bool BootChecks()
@ -289,6 +303,7 @@ namespace NUS_Downloader
string[] tmdsizes = GetContentSizes(tmd, nbr_cont);
byte[] tmdhashes = GetContentHashes(tmd, nbr_cont);
byte[] tmdindices = GetContentIndices(tmd, nbr_cont);
int[] tmdtypes = GetContentTypes(tmd, nbr_cont);
// Loop through each content and display name, hash, index
for (int i = 0; i < nbr_cont; i++)
@ -299,9 +314,9 @@ namespace NUS_Downloader
{
hash[x] = tmdhashes[(i*20)+x];
}
WriteStatus(" - Hash: " + DisplayBytes(hash, ""));
WriteStatus(" - Hash: " + DisplayBytes(hash, "").Substring(0, 8) + "...");
WriteStatus(" - Index: " + tmdindices[i]);
WriteStatus(" - Shared: " + (tmdtypes[i] == 0x8001));
}
}
}
@ -546,6 +561,26 @@ namespace NUS_Downloader
return contenthashes;
}
// Returns array of shared/normal values for a tmd...
private int[] GetContentTypes(byte[] tmdfile, int length)
{
int[] contenttypes = new int[length];
int startoffset = 0x1EA;
for (int i = 0; i < length; i++)
{
if (tmdfile[startoffset] == 0x80)
contenttypes[i] = (int)ContentTypes.Shared;
else
contenttypes[i] = (int)ContentTypes.Normal;
startoffset += 36;
// DEBUG:
//WriteStatus(contenttypes[i].ToString());
}
return contenttypes;
}
private byte[] GetContentIndices(byte[] tmdfile, int length)
{
byte[] contentindices = new byte[length];
@ -805,24 +840,25 @@ namespace NUS_Downloader
// IV (00+IDX+more000)
byte[] iv = new byte[16];
for (int x = 0; x < 8; x++)
for (int x = 0; x < 16; x++)
{
iv[x] = 0x00;
}
for (int x = 0; x < 7; x++)
{
iv[x + 8] = 0x00;
}
iv[1] = tmdindices[i];
initCrypt(iv, titlekey);
// Create decrypted file
/* Create decrypted file
string zeros = "000000";
FileStream decfs = new FileStream(RemoveIllegalCharacters(titledirectory + @"\" + zeros + i.ToString("X2") + ".app"), FileMode.Create);
FileStream decfs = new FileStream(titledirectory + @"\" + zeros + i.ToString("X2") + ".app", FileMode.Create);
decfs.Write(Decrypt(contbuf), 0, int.Parse(tmdsizes[i], System.Globalization.NumberStyles.HexNumber));
decfs.Close();
WriteStatus(" - Decrypted: " + zeros + i.ToString("X2") + ".app");
WriteStatus(" - Decrypted: " + zeros + i.ToString("X2") + ".app"); */
FileStream decfs = new FileStream(titledirectory + @"\" + tmdcontents[i] + ".app", FileMode.Create);
decfs.Write(Decrypt(contbuf), 0, int.Parse(tmdsizes[i], System.Globalization.NumberStyles.HexNumber));
decfs.Close();
WriteStatus(" - Decrypted: " + tmdcontents[i] + ".app");
// Hash Check...
byte[] hash = new byte[20];
@ -1060,7 +1096,7 @@ namespace NUS_Downloader
wadnamebox.Text = wadnamebox.Text.Replace("[v]", "v" + titleversion.Text);
// Create wad file
FileStream wadfs = new FileStream(RemoveIllegalCharacters(totaldirectory + @"\" + wadnamebox.Text), FileMode.Create);
FileStream wadfs = new FileStream(totaldirectory + @"\" + RemoveIllegalCharacters(wadnamebox.Text), FileMode.Create);
// Add wad stuffs
WADHeader wad = new WADHeader();
@ -1232,40 +1268,27 @@ namespace NUS_Downloader
if (currentdir.EndsWith(Convert.ToString(Path.DirectorySeparatorChar)) == false)
currentdir += Path.DirectorySeparatorChar;
if (File.Exists(currentdir + "key.bin") == false)
{
WriteStatus("Wii Decryption: Need (key.bin)");
}
else
{
WriteStatus("Wii Decryption: OK");
}
if (File.Exists(currentdir + "kkey.bin") == false)
{
WriteStatus("Wii Korea Decryption: Need (kkey.bin)");
}
else
{
WriteStatus("Wii Korea Decryption: OK");
}
if (File.Exists(currentdir + "dsikey.bin") == false)
{
WriteStatus("DSi Decryption: Need (dsikey.bin)");
}
else
{
WriteStatus("DSi Decryption: OK");
}
if (File.Exists(currentdir + "database.xml") == false)
{
WriteStatus("Database: Need (database.xml)");
}
else
{
WriteStatus("Database: OK");
}
if (IsWin7())
WriteStatus("Windows 7 Features: Enabled");
WriteStatus("");
WriteStatus("Special thanks to:");
@ -1276,7 +1299,7 @@ namespace NUS_Downloader
WriteStatus(" * Anyone who helped beta test on GBATemp!");
WriteStatus(" * Famfamfam for the Silk Icon Set.");
}
private void getcerts_Click(object sender, EventArgs e)
{
// Get a certs.sys from NUS...
@ -1287,7 +1310,7 @@ namespace NUS_Downloader
currentdir += Path.DirectorySeparatorChar;
// Create certs file
FileStream certsfs = new FileStream(RemoveIllegalCharacters(currentdir + @"\cert.sys"), FileMode.Create);
FileStream certsfs = new FileStream(currentdir + @"\cert.sys", FileMode.Create);
// Getting it from SystemMenu 3.2
DownloadNUSFile("0000000100000002", "tmd.289", currentdir + @"\", 0, true);
@ -1699,12 +1722,13 @@ namespace NUS_Downloader
if (e.ClickedItem.Text.Contains("v"))
{
if (e.ClickedItem.Text.Contains(" "))
titleversion.Text = e.ClickedItem.Text.Substring(1, e.ClickedItem.Text.IndexOf(' '));
titleversion.Text = e.ClickedItem.Text.Substring(1, e.ClickedItem.Text.IndexOf(' ') - 1);
else
titleversion.Text = e.ClickedItem.Text.Substring(1, e.ClickedItem.Text.Length - 1);
}
else
{
// Apparently it's a region code..
titleidbox.Text = titleidbox.Text.Replace("XX", e.ClickedItem.Text.Substring(0, 2));
titleversion.Text = "";
}
@ -2010,7 +2034,7 @@ namespace NUS_Downloader
tmd = ZeroSignature(tmd);
tmd = TruchaSign(tmd);
FileStream testtmd = new FileStream(RemoveIllegalCharacters(fileinfo[0] + fileinfo[1]), FileMode.Open);
FileStream testtmd = new FileStream(fileinfo[0] + fileinfo[1], FileMode.Open);
testtmd.Write(tmd, 0, tmd.Length);
testtmd.Close();
}
@ -2068,7 +2092,7 @@ namespace NUS_Downloader
cetkbuff = TruchaSign(cetkbuff);
// Write changes to cetk.
FileStream testtik = new FileStream(RemoveIllegalCharacters(fileinfo[0] + "cetk"), FileMode.Open);
FileStream testtik = new FileStream(fileinfo[0] + "cetk", FileMode.Open);
testtik.Write(cetkbuff, 0, cetkbuff.Length);
testtik.Close();
}
@ -2243,13 +2267,18 @@ namespace NUS_Downloader
string[] tmdcontents = GetContentNames(tmd, nbr_cont);
byte[] tmdindices = GetContentIndices(tmd, nbr_cont);
int[] tmdtypes = GetContentTypes(tmd, nbr_cont);
// Loop and add contents to listbox...
for (int a = 0; a < nbr_cont; a++)
{
contentsEdit.Items.Add(String.Format("[{0}] [{1}]", tmdindices[a], tmdcontents[a]));
if (tmdtypes[a] == 0x8001)
contentsEdit.Items[a] += " [S]";
}
// Identify Boot Content...
contentsEdit.Items[boot_idx] += " [BOOT]";
@ -2258,7 +2287,7 @@ namespace NUS_Downloader
private void button8_Click(object sender, EventArgs e)
{
// Move selected content upwards (down an index)...
if (contentsEdit.SelectedIndex <= 0)
if (contentsEdit.SelectedIndex < 0)
return;
int sel_idx = contentsEdit.SelectedIndex;
@ -2290,7 +2319,7 @@ namespace NUS_Downloader
private void button12_Click(object sender, EventArgs e)
{
// Set a new boot index...
if (contentsEdit.SelectedIndex <= 0)
if (contentsEdit.SelectedIndex < 0)
return;
for (int a = 0; a < contentsEdit.Items.Count; a++)
@ -2306,14 +2335,14 @@ namespace NUS_Downloader
{
// Add a file to the contents...
OpenFileDialog opencont = new OpenFileDialog();
opencont.Filter = "All Files|*";
opencont.Filter = "Decrypted Contents|*.app|All Files|*";
opencont.Multiselect = false;
opencont.Title = "Locate a Content";
if (opencont.ShowDialog() != DialogResult.Cancel)
{
if ((opencont.SafeFileName.Length != 8) && (OnlyHexInString(opencont.SafeFileName) == false))
if ((OnlyHexInString(opencont.SafeFileName.Substring(0,8)) == false))
{
MessageBox.Show("Please locate/rename a file to be (8 HEX CHARACTERS) long!", "Bad!", MessageBoxButtons.OK);
MessageBox.Show("Please locate/rename a file to be (8 HEX CHARACTERS) long + (.app) extention!", "Bad!", MessageBoxButtons.OK);
return;
}
@ -2329,6 +2358,12 @@ namespace NUS_Downloader
// D: TODO?
string[] fileinfo = shamelessvariablelabel.Text.Split(',');
if (File.Exists(fileinfo[0] + opencont.SafeFileName) )
{
MessageBox.Show("Rename the file you are adding, it already exists in the title directory!", "Bad!", MessageBoxButtons.OK);
return;
}
if (fileinfo[0] + opencont.SafeFileName != opencont.FileName)
{
// Move the file into the directory...
@ -2346,7 +2381,7 @@ namespace NUS_Downloader
private void button10_Click(object sender, EventArgs e)
{
// Remove a content from the list...
if ((contentsEdit.SelectedIndex <= 0) || (contentsEdit.Items.Count <= 1))
if ((contentsEdit.SelectedIndex < 0) || (contentsEdit.Items.Count <= 1))
return;
string[] fileinfo = shamelessvariablelabel.Text.Split(',');
@ -2359,6 +2394,291 @@ namespace NUS_Downloader
contentsEdit.Items.RemoveAt(contentsEdit.SelectedIndex);
}
private void button14_Click(object sender, EventArgs e)
{
// Write changes to TMD of contents...
WriteStatus("Updating TMD with content information...");
string[] fileinfo = shamelessvariablelabel.Text.Split(',');
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);
// Holds all the content data...
TitleContent[] contents = new TitleContent[contentsEdit.Items.Count];
// Previous TMD for analysis
byte[] tmd = FileLocationToByteArray(fileinfo[0] + fileinfo[1]);
for (int c = 0; c < contentsEdit.Items.Count; c++)
{
string itemstr = contentsEdit.Items[c].ToString();
contents[c] = new TitleContent();
if (itemstr.Contains(".app"))
{
// This is already decrypted, we're going to add it to the TMD...
string filename = itemstr.Substring(5, 12);
byte[] contentbytes = FileLocationToByteArray(fileinfo[0] + filename);
WriteStatus(" - Encrypting " + filename + "...");
// Gather the contentID (crappy way to do it)...
contents[c].ContentID = new byte[4];
contents[c].ContentID[0] = byte.Parse(filename.Substring(0, 2), System.Globalization.NumberStyles.HexNumber);
contents[c].ContentID[1] = byte.Parse(filename.Substring(2, 2), System.Globalization.NumberStyles.HexNumber);
contents[c].ContentID[2] = byte.Parse(filename.Substring(4, 2), System.Globalization.NumberStyles.HexNumber);
contents[c].ContentID[3] = byte.Parse(filename.Substring(6, 2), System.Globalization.NumberStyles.HexNumber);
// Grab SHA1/size of file
contents[c].SHAHash = new byte[20];
contents[c].SHAHash = ComputeSHA(contentbytes);
contents[c].Size = new byte[8];
// TODOCHECK THIS OVER
contents[c].Size = InttoByteArray(contentbytes.Length, 8);
contents[c].Index = new byte[2];
contents[c].Index = InttoByteArray(c, 2);
contents[c].Type = new byte[2];
contents[c].Type[1] = 0x01;
if (contentsEdit.Items[c].ToString().Contains(" [S]"))
contents[c].Type[0] = 0x80;
else
contents[c].Type[0] = 0x00;
// Pad to be 16 byte aligned
contentbytes = AlignByteArray(contentbytes, 16);
// Encrypt with correct index IV/titlekey
byte[] ivindex = new byte[16];
for (int d = 0; d < ivindex.Length; d++)
{
ivindex[d] = 0x00;
}
ivindex[0] = contents[c].Index[0];
ivindex[1] = contents[c].Index[1];
initCrypt(ivindex, dtitlekey);
FileStream encryptwrite = new FileStream(fileinfo[0] + filename.Substring(0, 8), FileMode.Create);
encryptwrite.Write(Encrypt(contentbytes), 0, contentbytes.Length);
encryptwrite.Close();
WriteStatus(" - " + filename.Substring(0, 8) + " written!");
}
else
{
// An encrypted content...it was from the original TMD, leave alone? (hmmm)
string filename = itemstr.Substring(5, 8);
byte[] contentbytes = FileLocationToByteArray(fileinfo[0] + filename);
WriteStatus("Gathering " + filename + " information...");
// Grab previous values from TMD...
int nbr_cont = ContentCount(tmd);
string[] tmdoldcontents = GetContentNames(tmd, nbr_cont);
string[] tmdsizes = GetContentSizes(tmd, nbr_cont);
byte[] tmdhashes = GetContentHashes(tmd, nbr_cont);
int thiscontentidx = 0;
for (int f = 0; f < nbr_cont; f++)
{
if (tmdoldcontents[f] == filename)
thiscontentidx = f;
}
if (thiscontentidx != c)
{
// We have to decrypt the content, and then encrypt to keep IV in line...
byte[] ivindex = new byte[16];
for (int d = 0; d < ivindex.Length; d++)
{
ivindex[d] = 0x00;
}
// TODO: Complete this...
ivindex[0] = 0x00;
ivindex[1] = (byte)thiscontentidx;
initCrypt(ivindex, dtitlekey);
byte[] hash = new byte[20];
for (int x = 0; x < 20; x++)
{
hash[x] = tmdhashes[(thiscontentidx * 20) + x];
}
byte[] decContent = Decrypt(contentbytes);
Array.Resize(ref decContent, int.Parse(tmdsizes[c], System.Globalization.NumberStyles.HexNumber));
if ((Convert.ToBase64String(ComputeSHA(decContent))) == Convert.ToBase64String(hash))
{
WriteStatus(" - Hash Check: Content is Unchanged...");
contents[c].SHAHash = hash;
}
else
{
WriteStatus(" - Hash Check: Content changed (probably REALLY BAD)...");
contents[c].SHAHash = ComputeSHA(decContent);
}
// Re-encrypt
byte[] newiv = new byte[16];
for (int g = 0; g < newiv.Length; g++)
{
newiv[g] = 0x00;
}
// TODO: Complete this...
ivindex[0] = 0x00;
ivindex[1] = (byte)c;
// Pad back to 0x16 alignment
AlignByteArray(decContent, 0x16);
initCrypt(newiv, dtitlekey);
byte[] encContent = Encrypt(decContent);
File.Delete(fileinfo[0] + filename.Substring(0, 8));
FileStream encryptwrite = new FileStream(fileinfo[0] + filename.Substring(0, 8), FileMode.OpenOrCreate);
encryptwrite.Write(encContent, 0, encContent.Length);
encryptwrite.Close();
WriteStatus(" - Encrypted Content Again!");
}
else
{
// Hopefully this content has not been touched...
// TODO: um, i'm 12 and what is this?
}
contents[c].ContentID = new byte[4];
contents[c].ContentID[0] = byte.Parse(filename.Substring(0, 2), System.Globalization.NumberStyles.HexNumber);
contents[c].ContentID[1] = byte.Parse(filename.Substring(2, 2), System.Globalization.NumberStyles.HexNumber);
contents[c].ContentID[2] = byte.Parse(filename.Substring(4, 2), System.Globalization.NumberStyles.HexNumber);
contents[c].ContentID[3] = byte.Parse(filename.Substring(6, 2), System.Globalization.NumberStyles.HexNumber);
contents[c].Index = new byte[2];
contents[c].Index = InttoByteArray(c, 2); // TODOTODOTODO
contents[c].Type = new byte[2];
contents[c].Type[0] = 0x01;
if (contentsEdit.Items[c].ToString().Contains(" [S]"))
contents[c].Type[0] = 0x80;
else
contents[c].Type[0] = 0x00;
contents[c].Size = new byte[8];
// TODOCHECK THIS OVER
contents[c].Size = InttoByteArray(contentbytes.Length, 8);
}
// Write all this stuff to the TMD...
byte[] contentSection = new byte[contents.Length * 36];
for (int h = 0; h < contents.Length; h++)
{
for (int i = 0; i < contents[h].ContentID.Length; i++)
{
contentSection[(h * 36) + i] = contents[h].ContentID[i];
}
for (int j = 0; j < contents[h].Index.Length; j++)
{
contentSection[(h * 36) + (contents[h].ContentID.Length + j)] = contents[h].Index[j];
}
for (int k = 0; k < contents[h].Type.Length; k++)
{
contentSection[(h * 36) + (contents[h].ContentID.Length + contents[h].Index.Length + k)] = contents[h].Type[k];
}
for (int l = 0; l < contents[h].Size.Length; l++)
{
contentSection[(h * 36) + (contents[h].ContentID.Length + contents[h].Index.Length + contents[h].Type.Length + l)] = contents[h].Type[l];
}
for (int m = 0; m < contents[h].SHAHash.Length; m++)
{
contentSection[(h * 36) + (contents[h].ContentID.Length + contents[h].Index.Length + contents[h].Type.Length + contents[h].Size.Length + m)] = contents[h].Type[m];
}
}
for (int n = 0; n < contentSection.Length; n++)
{
tmd[0x1E4 + n] = contentSection[n];
}
// Fakesign the TMD again...
tmd = ZeroSignature(tmd);
tmd = TruchaSign(tmd);
FileStream testtmd = new FileStream(fileinfo[0] + fileinfo[1], FileMode.Open);
testtmd.Write(tmd, 0, tmd.Length);
testtmd.Close();
}
}
// Pad Byte[] to specific alignment...
private byte[] AlignByteArray(byte[] content, int alignto)
{
long thelength = content.Length - 1;
long remainder = 1;
while (remainder != 0)
{
thelength += 1;
remainder = thelength % alignto;
}
Array.Resize(ref content, (int)thelength);
return content;
}
private void button17_Click(object sender, EventArgs e)
{
// Move groupbox to display title modder...
contentModBox.Location = new Point(278, 12);
contentModBox.Visible = true;
}
private void button13_Click(object sender, EventArgs e)
{
// Share/Unshare Contents in the list...
if (contentsEdit.SelectedIndex < 0)
return;
if (contentsEdit.Items[contentsEdit.SelectedIndex].ToString().Contains(" [S]"))
contentsEdit.Items[contentsEdit.SelectedIndex] = contentsEdit.SelectedItem.ToString().Replace(" [S]", "");
else
{
if (contentsEdit.Items[contentsEdit.SelectedIndex].ToString().Contains(" [BOOT]"))
contentsEdit.Items[contentsEdit.SelectedIndex] = contentsEdit.SelectedItem.ToString().Replace(" [BOOT]", "") + " [S] [BOOT]";
else
contentsEdit.Items[contentsEdit.SelectedIndex] = contentsEdit.SelectedItem.ToString() + " [S]";
}
}
private bool IsWin7()
{
return (Environment.OSVersion.VersionString.Contains("6.1") == true);
}
}
}

View File

@ -132,6 +132,212 @@
* Always have a brick restoration method in place (BootMii boot2).</value>
</data>
<assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="button12.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29m
dHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAKgSURBVDhPlZPdT5JhGMY58MS/oDMO+zDXsuWSrVSm
K3WLrIOYbs5lztTFEDN0ipEmJMJ4FSHfXhUUSJyggMo08QPzIz8IdX6jZZnYah27JbarF1oumrZ58Jw9
92/X/XuuhwGAcZIj6diMFbUu+Quo+b2cupmk/w63ur6HNTm/MNUOH0vetcWpMK2rK01rkFtWUWVaxF3J
6N6xAN3wt3Cyf3eyvvczlPYtyMxeKDq9IB2bqLWuoqjRjcSSvv1jARqHT9g8sAPz+C6Mw9toev0B9d3r
EBsWIGlbwG2xE7H5XXFHAkjnxmlpz8RPAz1I9W1B2r6M8tZ5PKJm8VTvQZZ8BFdzzZqAuxBAIDbVv2tV
dQ/8qJwoRoXNAZVtDUTXKvgN08ghxiBsnEKKwI4r6XpOCEA79DWsoc/n1Tl3EDiStpYD8agQ6YTtgP/i
Lcq0s0iTDOKhagxx99sQlUqxQgCqXh+TsH/8vfPINpSdaxCo2/e5NebipBLjQUaVE3mEC/dqBhF9pwmR
iXXMEEB153uWzLwB/dAnPO9YgbpnHaU6DzJlGr9okIfr/HrcemwDO8uI8wmE9yxbHhYCEOlXOE8MS8Fn
Cggrotx4ZpyDkJpCtqIcpf35iE5V+CPYSuuZ+OrwP+U7lMgjPXZp+yKUlhUIyGnk1o4js2YED4g3yKat
38gV+y9xpOf+bW0QkKd2FwqbPVBYlmnLsxC1uIO2+ZqJ4N5JPAuibpLCoyrPoPssELx0o8IwH4xcpp1B
Bm07WWBFfLYJMVwtLqY0TEYmEIex/wYx0qrHUK6fowvyDjkKF5ILbYjJeKW5zNVxolJJ1oVkNTMigQgK
OzJBStkAbdqFLBm9J88aKAj7JL+TwS6wn7qWZwYr07QXzdXFnWQ4cPcXyBm6QmRn5bAAAAAASUVORK5C
YII=
</value>
</data>
<data name="button8.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29m
dHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAFHSURBVDhPY/j//z8DJRiv5uJj6ScLDqUewWcBTgOK
jqZd7DhV97/1RPX/jB2x53EZgmFAyfEMtqIjabfbT9X8X35t3v+lV+b8rz1Q/D9uTejNyGUBbOgGYRhQ
eDh1d97+pO/Nxyr/L74y6//CyzP+tx2u/R+xxP978DyvHQQNgClI3RL9f/6laf/nXJjyP3VN7P+gOZ4W
2LyBMwzi14b9n3V+8v8Z5yb8D5jlAdSLPbZwGgD07/+pZ/r+Tz7d/d9rkhPpBgD9+3/iqa7/fSfb/zt3
2ZBugM9U1/89x1v/dx5r+m/bZEa6AW699v/bjzb+bz1c99+sypB0A+xbLf83Har933Cw6r9BkTbpBljW
Gv+vO1D5v2Z/2X/tbDXSDTAu1f1ftbfkf8Xeov9qqUqkG6Cbp/FfM1P1v2qK4n+lBDnSDSA2iwMA5nrY
LX6N1KIAAAAASUVORK5CYII=
</value>
</data>
<data name="button11.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29m
dHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAMxSURBVDhPdZPrT5tlGIf7RRP/gSXzwz4ZQ2RTZ4wn
sgxxg85x0JhsiZ/YIprpEozRsMTNRcNGkbKSShejI1vMioSJo5WDFApjFmgZDFZoSylMOiinUvrCLFAK
7+Xd6jRx803uPHmf3L/rPj4aQPMoG2vKSx+zHr7ua3yzw/uzdu//+T0k9rfk7xBxqc96OLroucTcgA7P
Twfvj9Yf0I/8mPXkf0H/AMZbCx4TcdFYU24gNGRka2MWdW2a1cnrrM9YCd74hDtX908N/7Dv5NCVjCce
gFIAf2tBtr85/+ZU7xesL9+RqzVQFRKRW4w3vMW6r4J4sJ5Vr4mA9Ti3a151Dn73Ul5SmxRf9jfnqRG/
mVjYTeRuJ3dd4vhbOd5fP2ay7QQxXxWxobNsBGrYnK5nqb8UT+3b3DK9UKuRehPqRpB4eJCI20h4oJRQ
VzEByxGc1RlsLt2GmB8W21B/N4GnBGbMJCZKcRmfS2ikWcr2xj24P8rmTCMrQ+eJDZ8VO8WMJTd1x0IL
BL9H9Z4iZs9koXkfK54qnIY9isbbeEjZXhPAH+MC8UDYzrqnnJjrBAtNuSTGK2FCT9yhZanlFea7tMy3
F6AM6+mrTFc0noYcZSsF8MGqpBt1CsRGImBkpfsI8ZtaFHsGSz05LNgPMtucxawlh+V+Hb1fpykame9f
ACkBxQWRTqn3F5hrQPWfJtqnZdHxBg31+Xx68SjvXyig8HwmNVfepafsaUUzUpcVVxNzMrlJid4t0Vth
/po06ipq8CLhXi11tYf48toxmkZNDM/aMLR/yFHDHj4r2bWlcZsz2yfsJayFugQSgGWBhMwwfVkA1Sx2
Z3NMdwDLSBUWr1FGD/qOIgwdH/DayZ3bGtmsx2WzimQ5AlM3zrC13Ce9GJAs6lCnqpmzvU7u53tpGb2U
Ej/4rG4TL3+089+HJJu1Y+DbF8/JckRDjq+kqQKJOlhxV7C/eBcVtuOU2QpT+rK2wlQGAlh/6DH1f/N8
uqvqWbPzwm41PGjgXmsxZ07v5h19GpW290hGTp7JfwHoH/mUkzveW/FMdk95Wqd02uE491SeOOvEVpNp
/33qkn5/AiEv99RPttotAAAAAElFTkSuQmCC
</value>
</data>
<data name="button9.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29m
dHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAFESURBVDhPY/j//z8DJRin5pLjGf+Lj6X/LziU+j93
XxLQDuwW4TSg6Gja/9U3Fv1feX3B/4wdsaQbkH8g+f/ya/P+L70y53/ypkjSDcjaHf9/8ZVZ/xdenvE/
dlUw6Qakbon+P//StP9zLkz5H77Ij3QD4teG/Z91fvL/Gecm/A+Y5UG6AZHLAv5PPdP3f/Lp7v9ek5xI
NyB4ntf/iae6/vedbP/v3GVDugE+U13/9xxv/d95rOm/bZMZaQZ4T3G2CJ3l97/9aOP/1sN1/82qDIk3
AOjfHa49tt9z1qb+bzpU+7/hYNX/gEne/3Vy1b9rZKjsRk+RGCkR6F82u2aLm+EzA//XHaj8X7O/7L93
r9t/9TTl28pJCmwEDYApMC7VPe/b7/Hfq8f1v1qq0kWS8wJIg2am6hHVFMWT+HIrRVkZZDAAFl/VUw/P
Z/oAAAAASUVORK5CYII=
</value>
</data>
<data name="button10.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29m
dHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAM9SURBVDhPdZNtTJtVGIZfw7bE/dMYYkz8sUTNIm7O
xZgtZBFRoG50zGhm/KtbsiVLZkgUNCqJYXMM2EgFY1QyY9ZJUDZAytdWCrNAy8f4GG0phY2Olo8W2he2
tpSy9/Ipxpm4+SZP3uTk3Nd5zv3cRwGUR9V4kz5tvPHAFVf9/mvOy7pX/m/fQ2J388FUERe7Gg+EA46f
mBs4g+P3rLtjtW+V3fw185n/gh4AJlryNov46HhTrsc/ZGB9dRYtOsPK1BVivka8nfmMXHx9eviXfSeG
fk5//B/QBsDdkpftNh28Pt3zFbHQiCxFQVNJLPUzUXeImKuUuLeWFWcVnsYPuVG91zb4w2v6pDYpvuA2
6bUlt5FIcJSlWx3cssvGP0twtn7MVNtxIq4KIkNFrHqqWZupZbGvGMeld+iv2n1JkfsmtFUv8eAgS6MG
ggPF+C0n8TQcxlaZztriDYi4IdCGdrsKHAXgM5KYLMZueDmhiFnq/dU7cHeMNV89y0OniQwXSRXia8jd
WGOhGbw/ojkLiZgzWDDtY9lRge38DlVx1r+t3o8K4N6EQBwQNBNzlBCxH2ehKZfERDlMlhG36lhs3sO8
Rcf81TzU4TJ6y9NUxVGXo65vAFywIu2GbQJpJ+ExsNx1mPh1Hao5ncXuHBbMWcyaMpltyCHUd4aes9tV
Reb7N0CugGqHpQ657x8wV4fm/oJwr46A9U1c53Zj/eAprmVuouPQVsZKcuj+5gVVuVmTGdcSczK5KTm9
S05vgfnfxKiLaN7vCPboGC/fxcgne4iZysWHViI1+fSf2EnnsdSEMmrMuDppLiDqtwjEAyGB+I0wc0EA
lQS6srG8u5WoiDHI6AuegNPbCJ7NoH3/lpgiydoiyToq4fBMd37JeqhXvBiQLmrQpiuZa39jo21t8LLk
5t8vXPR0cl17EGVJVurA96+eknCE/davxVSBhK0sj5Ziee9J7lV/BCJa/VQhJOU9lkJbVorvocfU9+2u
NHvFTqPt3EtacPA8d1pO0p2/A/uR57XZgm0EPtvM1JHHMOs3rbdmpXz+yKeczHhP6YvZ3SXbO8Rpq/XU
c3rr+88Wyom3k23LfyYpTu77C4h89ngRLmtIAAAAAElFTkSuQmCC
</value>
</data>
<data name="radioButton1.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
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
</value>
</data>
<data name="radioButton2.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
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
</value>
</data>
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
AAABAAUAEBAAAAAAIABoBAAAVgAAACAgAAAAACAAqBAAAL4EAAAwMAAAAAAgAKglAABmFQAAQEAAAAAA

View File

@ -102,6 +102,7 @@
</ItemGroup>
<ItemGroup>
<Content Include="direction_down.ico" />
<None Include="Resources\link.png" />
<None Include="Resources\bug_add.png" />
<None Include="Resources\arrow_down.png" />
<None Include="Resources\arrow_up.png" />

View File

@ -130,6 +130,13 @@ namespace NUS_Downloader.Properties {
}
}
internal static System.Drawing.Bitmap link {
get {
object obj = ResourceManager.GetObject("link", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
internal static System.Drawing.Bitmap package_add {
get {
object obj = ResourceManager.GetObject("package_add", resourceCulture);

View File

@ -157,4 +157,7 @@
<data name="bug_add" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\bug_add.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="link" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\link.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root>

Binary file not shown.

After

Width:  |  Height:  |  Size: 343 B