mirror of
https://github.com/R-YaTian/TinkeDSi.git
synced 2025-06-18 16:45:43 -04:00
Add an option to "Recompress ARM9 binary", improve arm9 blz
Revert #5b6afa1 Update changelog, compile batch and translations [WIP] Basic command line support
This commit is contained in:
parent
7ac89ea4dc
commit
a39ebedf66
@ -130,7 +130,7 @@ namespace SDAT
|
|||||||
for (int i = 0; i < sounds.Length; i++)
|
for (int i = 0; i < sounds.Length; i++)
|
||||||
{
|
{
|
||||||
bw.Write(currOffset);
|
bw.Write(currOffset);
|
||||||
currOffset += (uint)sounds[i].data.data.Length + 0x0C;
|
currOffset += (uint)sounds[i].data.data.Length + 0x0A;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write data
|
// Write data
|
||||||
|
40
Tinke/Dialog/SaveOptions.Designer.cs
generated
40
Tinke/Dialog/SaveOptions.Designer.cs
generated
@ -32,6 +32,8 @@
|
|||||||
this.checkBox2 = new System.Windows.Forms.CheckBox();
|
this.checkBox2 = new System.Windows.Forms.CheckBox();
|
||||||
this.btn_OK = new System.Windows.Forms.Button();
|
this.btn_OK = new System.Windows.Forms.Button();
|
||||||
this.btn_Cancel = new System.Windows.Forms.Button();
|
this.btn_Cancel = new System.Windows.Forms.Button();
|
||||||
|
this.checkBox3 = new System.Windows.Forms.CheckBox();
|
||||||
|
this.checkBox4 = new System.Windows.Forms.CheckBox();
|
||||||
this.SuspendLayout();
|
this.SuspendLayout();
|
||||||
//
|
//
|
||||||
// checkBox1
|
// checkBox1
|
||||||
@ -39,7 +41,7 @@
|
|||||||
this.checkBox1.AutoSize = true;
|
this.checkBox1.AutoSize = true;
|
||||||
this.checkBox1.Location = new System.Drawing.Point(12, 12);
|
this.checkBox1.Location = new System.Drawing.Point(12, 12);
|
||||||
this.checkBox1.Name = "checkBox1";
|
this.checkBox1.Name = "checkBox1";
|
||||||
this.checkBox1.Size = new System.Drawing.Size(42, 16);
|
this.checkBox1.Size = new System.Drawing.Size(53, 19);
|
||||||
this.checkBox1.TabIndex = 0;
|
this.checkBox1.TabIndex = 0;
|
||||||
this.checkBox1.Text = "S1E";
|
this.checkBox1.Text = "S1E";
|
||||||
this.checkBox1.UseVisualStyleBackColor = true;
|
this.checkBox1.UseVisualStyleBackColor = true;
|
||||||
@ -47,9 +49,9 @@
|
|||||||
// checkBox2
|
// checkBox2
|
||||||
//
|
//
|
||||||
this.checkBox2.AutoSize = true;
|
this.checkBox2.AutoSize = true;
|
||||||
this.checkBox2.Location = new System.Drawing.Point(12, 34);
|
this.checkBox2.Location = new System.Drawing.Point(12, 37);
|
||||||
this.checkBox2.Name = "checkBox2";
|
this.checkBox2.Name = "checkBox2";
|
||||||
this.checkBox2.Size = new System.Drawing.Size(42, 16);
|
this.checkBox2.Size = new System.Drawing.Size(53, 19);
|
||||||
this.checkBox2.TabIndex = 2;
|
this.checkBox2.TabIndex = 2;
|
||||||
this.checkBox2.Text = "S1F";
|
this.checkBox2.Text = "S1F";
|
||||||
this.checkBox2.UseVisualStyleBackColor = true;
|
this.checkBox2.UseVisualStyleBackColor = true;
|
||||||
@ -58,7 +60,7 @@
|
|||||||
//
|
//
|
||||||
this.btn_OK.DialogResult = System.Windows.Forms.DialogResult.OK;
|
this.btn_OK.DialogResult = System.Windows.Forms.DialogResult.OK;
|
||||||
this.btn_OK.Image = global::Tinke.Properties.Resources.accept;
|
this.btn_OK.Image = global::Tinke.Properties.Resources.accept;
|
||||||
this.btn_OK.Location = new System.Drawing.Point(12, 56);
|
this.btn_OK.Location = new System.Drawing.Point(12, 112);
|
||||||
this.btn_OK.Name = "btn_OK";
|
this.btn_OK.Name = "btn_OK";
|
||||||
this.btn_OK.Size = new System.Drawing.Size(90, 30);
|
this.btn_OK.Size = new System.Drawing.Size(90, 30);
|
||||||
this.btn_OK.TabIndex = 3;
|
this.btn_OK.TabIndex = 3;
|
||||||
@ -71,7 +73,7 @@
|
|||||||
//
|
//
|
||||||
this.btn_Cancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
|
this.btn_Cancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
|
||||||
this.btn_Cancel.Image = global::Tinke.Properties.Resources.cancel;
|
this.btn_Cancel.Image = global::Tinke.Properties.Resources.cancel;
|
||||||
this.btn_Cancel.Location = new System.Drawing.Point(137, 56);
|
this.btn_Cancel.Location = new System.Drawing.Point(137, 112);
|
||||||
this.btn_Cancel.Name = "btn_Cancel";
|
this.btn_Cancel.Name = "btn_Cancel";
|
||||||
this.btn_Cancel.Size = new System.Drawing.Size(90, 30);
|
this.btn_Cancel.Size = new System.Drawing.Size(90, 30);
|
||||||
this.btn_Cancel.TabIndex = 4;
|
this.btn_Cancel.TabIndex = 4;
|
||||||
@ -80,10 +82,34 @@
|
|||||||
this.btn_Cancel.UseVisualStyleBackColor = true;
|
this.btn_Cancel.UseVisualStyleBackColor = true;
|
||||||
this.btn_Cancel.Click += new System.EventHandler(this.btn_Cancel_Click);
|
this.btn_Cancel.Click += new System.EventHandler(this.btn_Cancel_Click);
|
||||||
//
|
//
|
||||||
|
// checkBox3
|
||||||
|
//
|
||||||
|
this.checkBox3.AutoSize = true;
|
||||||
|
this.checkBox3.Location = new System.Drawing.Point(12, 62);
|
||||||
|
this.checkBox3.Name = "checkBox3";
|
||||||
|
this.checkBox3.Size = new System.Drawing.Size(53, 19);
|
||||||
|
this.checkBox3.TabIndex = 5;
|
||||||
|
this.checkBox3.Text = "S20";
|
||||||
|
this.checkBox3.UseVisualStyleBackColor = true;
|
||||||
|
this.checkBox3.CheckedChanged += new System.EventHandler(this.checkBox3_CheckedChanged);
|
||||||
|
//
|
||||||
|
// checkBox4
|
||||||
|
//
|
||||||
|
this.checkBox4.AutoSize = true;
|
||||||
|
this.checkBox4.Enabled = false;
|
||||||
|
this.checkBox4.Location = new System.Drawing.Point(12, 87);
|
||||||
|
this.checkBox4.Name = "checkBox4";
|
||||||
|
this.checkBox4.Size = new System.Drawing.Size(53, 19);
|
||||||
|
this.checkBox4.TabIndex = 6;
|
||||||
|
this.checkBox4.Text = "S21";
|
||||||
|
this.checkBox4.UseVisualStyleBackColor = true;
|
||||||
|
//
|
||||||
// SaveOptions
|
// SaveOptions
|
||||||
//
|
//
|
||||||
this.BackColor = System.Drawing.SystemColors.GradientInactiveCaption;
|
this.BackColor = System.Drawing.SystemColors.GradientInactiveCaption;
|
||||||
this.ClientSize = new System.Drawing.Size(239, 98);
|
this.ClientSize = new System.Drawing.Size(239, 154);
|
||||||
|
this.Controls.Add(this.checkBox4);
|
||||||
|
this.Controls.Add(this.checkBox3);
|
||||||
this.Controls.Add(this.btn_Cancel);
|
this.Controls.Add(this.btn_Cancel);
|
||||||
this.Controls.Add(this.btn_OK);
|
this.Controls.Add(this.btn_OK);
|
||||||
this.Controls.Add(this.checkBox2);
|
this.Controls.Add(this.checkBox2);
|
||||||
@ -107,5 +133,7 @@
|
|||||||
private System.Windows.Forms.CheckBox checkBox2;
|
private System.Windows.Forms.CheckBox checkBox2;
|
||||||
private System.Windows.Forms.Button btn_OK;
|
private System.Windows.Forms.Button btn_OK;
|
||||||
private System.Windows.Forms.Button btn_Cancel;
|
private System.Windows.Forms.Button btn_Cancel;
|
||||||
|
private System.Windows.Forms.CheckBox checkBox3;
|
||||||
|
private System.Windows.Forms.CheckBox checkBox4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,8 @@ namespace Tinke.Dialog
|
|||||||
btn_Cancel.Text = xml.Element("S1C").Value;
|
btn_Cancel.Text = xml.Element("S1C").Value;
|
||||||
checkBox1.Text = xml.Element("S1E").Value;
|
checkBox1.Text = xml.Element("S1E").Value;
|
||||||
checkBox2.Text = xml.Element("S1F").Value;
|
checkBox2.Text = xml.Element("S1F").Value;
|
||||||
|
checkBox3.Text = xml.Element("S20").Value;
|
||||||
|
checkBox4.Text = xml.Element("S21").Value;
|
||||||
}
|
}
|
||||||
catch { throw new NotImplementedException("There was an error reading the language file"); }
|
catch { throw new NotImplementedException("There was an error reading the language file"); }
|
||||||
}
|
}
|
||||||
@ -36,6 +38,16 @@ namespace Tinke.Dialog
|
|||||||
get { return checkBox2.Checked; }
|
get { return checkBox2.Checked; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool IsReCompress
|
||||||
|
{
|
||||||
|
get { return checkBox3.Checked; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsBetterCompress
|
||||||
|
{
|
||||||
|
get { return checkBox4.Checked; }
|
||||||
|
}
|
||||||
|
|
||||||
private void btn_OK_Click(object sender, EventArgs e)
|
private void btn_OK_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
this.Close();
|
this.Close();
|
||||||
@ -45,5 +57,17 @@ namespace Tinke.Dialog
|
|||||||
{
|
{
|
||||||
this.Close();
|
this.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void checkBox3_CheckedChanged(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (checkBox3.Checked)
|
||||||
|
{
|
||||||
|
checkBox4.Enabled = true;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
checkBox4.Checked = false;
|
||||||
|
checkBox4.Enabled= false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,83 +1,83 @@
|
|||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
// <copyright file="TWL.cs" company="none">
|
// <copyright file="TWL.cs" company="none">
|
||||||
|
|
||||||
// Copyright (C) 2017
|
// Copyright (C) 2017
|
||||||
//
|
//
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
// (at your option) any later version.
|
// (at your option) any later version.
|
||||||
//
|
//
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License for more details.
|
// GNU General Public License for more details.
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
//
|
//
|
||||||
// </copyright>
|
// </copyright>
|
||||||
|
|
||||||
// <author>MetLob</author>
|
// <author>MetLob</author>
|
||||||
// <email>metlob@mail333.com</email>
|
// <email>metlob@mail333.com</email>
|
||||||
// <date>13/10/2017 18:53:14</date>
|
// <date>13/10/2017 18:53:14</date>
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace Tinke.Nitro
|
namespace Tinke.Nitro
|
||||||
{
|
{
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
|
|
||||||
using DSDecmp.Formats;
|
using DSDecmp.Formats;
|
||||||
|
|
||||||
using Ekona;
|
using Ekona;
|
||||||
|
|
||||||
using Tinke.Tools;
|
using Tinke.Tools;
|
||||||
using Tinke.Tools.Cryptography;
|
using Tinke.Tools.Cryptography;
|
||||||
|
|
||||||
class TWL
|
class TWL
|
||||||
{
|
{
|
||||||
private static byte[] modcryptCmnKey =
|
private static byte[] modcryptCmnKey =
|
||||||
{
|
{
|
||||||
0x79, 0x3E, 0x4F, 0x1A, 0x5F, 0x0F, 0x68, 0x2A, 0x58, 0x02, 0x59, 0x29, 0x4E,
|
0x79, 0x3E, 0x4F, 0x1A, 0x5F, 0x0F, 0x68, 0x2A, 0x58, 0x02, 0x59, 0x29, 0x4E,
|
||||||
0xFB, 0xFE, 0xFF
|
0xFB, 0xFE, 0xFF
|
||||||
};
|
};
|
||||||
|
|
||||||
internal static byte[] hmac_sha1_key =
|
internal static byte[] hmac_sha1_key =
|
||||||
{
|
{
|
||||||
0x21,0x06,0xC0,0xDE,0xBA,0x98,0xCE,0x3F,0xA6,0x92,0xE3,0x9D,0x46,0xF2,0xED,0x01,
|
0x21,0x06,0xC0,0xDE,0xBA,0x98,0xCE,0x3F,0xA6,0x92,0xE3,0x9D,0x46,0xF2,0xED,0x01,
|
||||||
0x76,0xE3,0xCC,0x08,0x56,0x23,0x63,0xFA,0xCA,0xD4,0xEC,0xDF,0x9A,0x62,0x78,0x34,
|
0x76,0xE3,0xCC,0x08,0x56,0x23,0x63,0xFA,0xCA,0xD4,0xEC,0xDF,0x9A,0x62,0x78,0x34,
|
||||||
0x8F,0x6D,0x63,0x3C,0xFE,0x22,0xCA,0x92,0x20,0x88,0x97,0x23,0xD2,0xCF,0xAE,0xC2,
|
0x8F,0x6D,0x63,0x3C,0xFE,0x22,0xCA,0x92,0x20,0x88,0x97,0x23,0xD2,0xCF,0xAE,0xC2,
|
||||||
0x32,0x67,0x8D,0xFE,0xCA,0x83,0x64,0x98,0xAC,0xFD,0x3E,0x37,0x87,0x46,0x58,0x24,
|
0x32,0x67,0x8D,0xFE,0xCA,0x83,0x64,0x98,0xAC,0xFD,0x3E,0x37,0x87,0x46,0x58,0x24,
|
||||||
};
|
};
|
||||||
|
|
||||||
internal static byte[] rsaPublicKey =
|
internal static byte[] rsaPublicKey =
|
||||||
{
|
{
|
||||||
0x95, 0x6F, 0x79, 0x0D, 0xF0, 0x8B, 0xB8, 0x5A, 0x76, 0xAA, 0xEF, 0xA2, 0x7F, 0xE8, 0x74, 0x75,
|
0x95, 0x6F, 0x79, 0x0D, 0xF0, 0x8B, 0xB8, 0x5A, 0x76, 0xAA, 0xEF, 0xA2, 0x7F, 0xE8, 0x74, 0x75,
|
||||||
0x8B, 0xED, 0x9E, 0xDF, 0x9E, 0x9A, 0x67, 0x0C, 0xD8, 0x18, 0xBE, 0xB9, 0xB2, 0x88, 0x52, 0x03,
|
0x8B, 0xED, 0x9E, 0xDF, 0x9E, 0x9A, 0x67, 0x0C, 0xD8, 0x18, 0xBE, 0xB9, 0xB2, 0x88, 0x52, 0x03,
|
||||||
0xB3, 0xFA, 0x11, 0xAE, 0xAA, 0x18, 0x65, 0x13, 0xB5, 0xD6, 0xBB, 0x85, 0xA3, 0x84, 0xD0, 0xD0,
|
0xB3, 0xFA, 0x11, 0xAE, 0xAA, 0x18, 0x65, 0x13, 0xB5, 0xD6, 0xBB, 0x85, 0xA3, 0x84, 0xD0, 0xD0,
|
||||||
0xEF, 0xB3, 0x66, 0xCB, 0xC6, 0x05, 0x1A, 0xAA, 0x86, 0x82, 0x7A, 0xB7, 0x43, 0x11, 0xF5, 0x9C,
|
0xEF, 0xB3, 0x66, 0xCB, 0xC6, 0x05, 0x1A, 0xAA, 0x86, 0x82, 0x7A, 0xB7, 0x43, 0x11, 0xF5, 0x9C,
|
||||||
0x9B, 0xFC, 0x6C, 0x70, 0x79, 0xD5, 0xF1, 0x7B, 0xD0, 0x81, 0x9F, 0x52, 0x20, 0x56, 0x73, 0x8C,
|
0x9B, 0xFC, 0x6C, 0x70, 0x79, 0xD5, 0xF1, 0x7B, 0xD0, 0x81, 0x9F, 0x52, 0x20, 0x56, 0x73, 0x8C,
|
||||||
0x72, 0x1F, 0x40, 0xCF, 0x23, 0x61, 0x93, 0x25, 0x90, 0xA3, 0xC5, 0xDC, 0x94, 0xCF, 0xD1, 0x7A,
|
0x72, 0x1F, 0x40, 0xCF, 0x23, 0x61, 0x93, 0x25, 0x90, 0xA3, 0xC5, 0xDC, 0x94, 0xCF, 0xD1, 0x7A,
|
||||||
0x8C, 0xBC, 0x95, 0x4A, 0x91, 0x8A, 0xA8, 0x58, 0xF4, 0xD8, 0x04, 0xBA, 0xF7, 0xD3, 0xC1, 0xC4,
|
0x8C, 0xBC, 0x95, 0x4A, 0x91, 0x8A, 0xA8, 0x58, 0xF4, 0xD8, 0x04, 0xBA, 0xF7, 0xD3, 0xC1, 0xC4,
|
||||||
0xD7, 0xB8, 0xF0, 0x77, 0x01, 0x2F, 0xA1, 0x70, 0x26, 0x0B, 0x2C, 0x04, 0x90, 0x56, 0xF3, 0xA5
|
0xD7, 0xB8, 0xF0, 0x77, 0x01, 0x2F, 0xA1, 0x70, 0x26, 0x0B, 0x2C, 0x04, 0x90, 0x56, 0xF3, 0xA5
|
||||||
};
|
};
|
||||||
|
|
||||||
internal static byte[] rsaSignatureMask =
|
internal static byte[] rsaSignatureMask =
|
||||||
{
|
{
|
||||||
0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xCC, 0xCC, 0xCC, 0xCC,
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xCC, 0xCC, 0xCC, 0xCC,
|
||||||
0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC
|
0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC
|
||||||
};
|
};
|
||||||
|
|
||||||
internal static byte[] rsaFontKey =
|
internal static byte[] rsaFontKey =
|
||||||
{
|
{
|
||||||
0x9F, 0x80, 0xBC, 0x5F, 0xB6, 0xB6, 0x1D, 0x2A, 0x46, 0x02, 0x52, 0x64, 0xB2, 0xA3, 0x86, 0xCE,
|
0x9F, 0x80, 0xBC, 0x5F, 0xB6, 0xB6, 0x1D, 0x2A, 0x46, 0x02, 0x52, 0x64, 0xB2, 0xA3, 0x86, 0xCE,
|
||||||
@ -88,392 +88,392 @@ namespace Tinke.Nitro
|
|||||||
0x4E, 0x82, 0xF7, 0xB3, 0xE2, 0x9C, 0xE4, 0x72, 0xE3, 0xDC, 0x60, 0xAF, 0xCC, 0x18, 0xE2, 0xD4,
|
0x4E, 0x82, 0xF7, 0xB3, 0xE2, 0x9C, 0xE4, 0x72, 0xE3, 0xDC, 0x60, 0xAF, 0xCC, 0x18, 0xE2, 0xD4,
|
||||||
0xEF, 0xD2, 0x76, 0x47, 0x31, 0xE6, 0x14, 0x0E, 0x1D, 0x26, 0xB5, 0x85, 0x97, 0xBC, 0xC6, 0xB6,
|
0xEF, 0xD2, 0x76, 0x47, 0x31, 0xE6, 0x14, 0x0E, 0x1D, 0x26, 0xB5, 0x85, 0x97, 0xBC, 0xC6, 0xB6,
|
||||||
0xD8, 0xE7, 0x69, 0x2D, 0x2C, 0x26, 0xFB, 0x5F, 0x70, 0x9E, 0x19, 0x9C, 0x6B, 0x02, 0x6D, 0x97
|
0xD8, 0xE7, 0x69, 0x2D, 0x2C, 0x26, 0xFB, 0x5F, 0x70, 0x9E, 0x19, 0x9C, 0x6B, 0x02, 0x6D, 0x97
|
||||||
};
|
};
|
||||||
|
|
||||||
private uint firstDSiHashOffset;
|
private uint firstDSiHashOffset;
|
||||||
private uint dsiHashSize;
|
private uint dsiHashSize;
|
||||||
bool twlEncrypted;
|
bool twlEncrypted;
|
||||||
|
|
||||||
public byte[][] Overlays9Sha1Hmac { get; private set; }
|
public byte[][] Overlays9Sha1Hmac { get; private set; }
|
||||||
public byte[][] Header2Data { get; private set; }
|
public byte[][] Header2Data { get; private set; }
|
||||||
public byte[] DSi9Data { get; private set; }
|
public byte[] DSi9Data { get; private set; }
|
||||||
public byte[] DSi7Data { get; private set; }
|
public byte[] DSi7Data { get; private set; }
|
||||||
public byte[] Hashtable1Data { get; private set; }
|
public byte[] Hashtable1Data { get; private set; }
|
||||||
public byte[] Hashtable2Data { get; private set; }
|
public byte[] Hashtable2Data { get; private set; }
|
||||||
|
|
||||||
public TWL(string file, Estructuras.ROMHeader hdr, Estructuras.sFAT[] fat)
|
public TWL(string file, Estructuras.ROMHeader hdr, Estructuras.sFAT[] fat)
|
||||||
{
|
{
|
||||||
sFile[] overlays = Overlay.ReadBasicOverlays(file, hdr.ARM9overlayOffset, hdr.ARM9overlaySize, true, fat);
|
sFile[] overlays = Overlay.ReadBasicOverlays(file, hdr.ARM9overlayOffset, hdr.ARM9overlaySize, true, fat);
|
||||||
this.firstDSiHashOffset = hdr.digest_ntr_size / hdr.digest_sector_size * 0x14;
|
this.firstDSiHashOffset = hdr.digest_ntr_size / hdr.digest_sector_size * 0x14;
|
||||||
this.dsiHashSize = hdr.digest_twl_size / hdr.digest_sector_size * 0x14;
|
this.dsiHashSize = hdr.digest_twl_size / hdr.digest_sector_size * 0x14;
|
||||||
|
|
||||||
// Read data
|
// Read data
|
||||||
BinaryReader br = new BinaryReader(File.OpenRead(file));
|
BinaryReader br = new BinaryReader(File.OpenRead(file));
|
||||||
br.BaseStream.Position = hdr.sector_hashtable_start;
|
br.BaseStream.Position = hdr.sector_hashtable_start;
|
||||||
this.Hashtable1Data = br.ReadBytes((int)hdr.sector_hashtable_size);
|
this.Hashtable1Data = br.ReadBytes((int)hdr.sector_hashtable_size);
|
||||||
br.BaseStream.Position = hdr.block_hashtable_start;
|
br.BaseStream.Position = hdr.block_hashtable_start;
|
||||||
this.Hashtable2Data = br.ReadBytes((int)hdr.block_hashtable_size);
|
this.Hashtable2Data = br.ReadBytes((int)hdr.block_hashtable_size);
|
||||||
br.BaseStream.Position = hdr.dsi9_rom_offset;
|
br.BaseStream.Position = hdr.dsi9_rom_offset;
|
||||||
this.DSi9Data = br.ReadBytes(Math.Max((int)hdr.modcrypt1_size, (int)hdr.dsi9_size));
|
this.DSi9Data = br.ReadBytes(Math.Max((int)hdr.modcrypt1_size, (int)hdr.dsi9_size));
|
||||||
br.BaseStream.Position = hdr.dsi7_rom_offset;
|
br.BaseStream.Position = hdr.dsi7_rom_offset;
|
||||||
this.DSi7Data = br.ReadBytes(Math.Max((int)hdr.modcrypt2_size, (int)hdr.dsi7_size));
|
this.DSi7Data = br.ReadBytes(Math.Max((int)hdr.modcrypt2_size, (int)hdr.dsi7_size));
|
||||||
if (!hdr.trimmedRom)
|
if (!hdr.trimmedRom)
|
||||||
{
|
{
|
||||||
//br.BaseStream.Position = hdr.digest_twl_start - 0x3000;
|
//br.BaseStream.Position = hdr.digest_twl_start - 0x3000;
|
||||||
//this.Header2Data = br.ReadBytes(0x3000);
|
//this.Header2Data = br.ReadBytes(0x3000);
|
||||||
this.Header2Data = new byte[3][];
|
this.Header2Data = new byte[3][];
|
||||||
for (int i = 0; i < 3; i++)
|
for (int i = 0; i < 3; i++)
|
||||||
{
|
{
|
||||||
br.BaseStream.Position = hdr.digest_ntr_start + 0x4000;
|
br.BaseStream.Position = hdr.digest_ntr_start + 0x4000;
|
||||||
this.Header2Data[i] = br.ReadBytes(0x1000);
|
this.Header2Data[i] = br.ReadBytes(0x1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calc SHA1-HMAC of overlays9
|
// Calc SHA1-HMAC of overlays9
|
||||||
HMACSHA1 hmac = new HMACSHA1(TWL.hmac_sha1_key);
|
HMACSHA1 hmac = new HMACSHA1(TWL.hmac_sha1_key);
|
||||||
this.Overlays9Sha1Hmac = new byte[overlays.Length][];
|
this.Overlays9Sha1Hmac = new byte[overlays.Length][];
|
||||||
for (int i = 0; i < overlays.Length; i++)
|
for (int i = 0; i < overlays.Length; i++)
|
||||||
{
|
{
|
||||||
br.BaseStream.Position = overlays[i].offset;
|
br.BaseStream.Position = overlays[i].offset;
|
||||||
byte[] ovlData = br.ReadBytes((int)overlays[i].size);
|
byte[] ovlData = br.ReadBytes((int)overlays[i].size);
|
||||||
this.Overlays9Sha1Hmac[i] = hmac.ComputeHash(ovlData, 0, ovlData.Length);
|
this.Overlays9Sha1Hmac[i] = hmac.ComputeHash(ovlData, 0, ovlData.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for encryption modcrypt section
|
// Check for encryption modcrypt section
|
||||||
this.twlEncrypted = false; // (hdr.twlInternalFlags & 2) > 0;
|
this.twlEncrypted = false; // (hdr.twlInternalFlags & 2) > 0;
|
||||||
if (hdr.modcrypt1_start >= hdr.digest_twl_start && hdr.modcrypt1_start < 0xFFFFFFFF)
|
if (hdr.modcrypt1_start >= hdr.digest_twl_start && hdr.modcrypt1_start < 0xFFFFFFFF)
|
||||||
{
|
{
|
||||||
uint modcryptHashedSectorIndex = (hdr.modcrypt1_start - hdr.digest_twl_start) / hdr.digest_sector_size;
|
uint modcryptHashedSectorIndex = (hdr.modcrypt1_start - hdr.digest_twl_start) / hdr.digest_sector_size;
|
||||||
uint modcryptHashedSectorOff = modcryptHashedSectorIndex * hdr.digest_sector_size;
|
uint modcryptHashedSectorOff = modcryptHashedSectorIndex * hdr.digest_sector_size;
|
||||||
uint hashOff = modcryptHashedSectorIndex * 0x14;
|
uint hashOff = modcryptHashedSectorIndex * 0x14;
|
||||||
|
|
||||||
br.BaseStream.Position = hdr.digest_twl_start + modcryptHashedSectorOff;
|
br.BaseStream.Position = hdr.digest_twl_start + modcryptHashedSectorOff;
|
||||||
byte[] firstModcryptBlock = br.ReadBytes((int)hdr.digest_sector_size);
|
byte[] firstModcryptBlock = br.ReadBytes((int)hdr.digest_sector_size);
|
||||||
byte[] hash = hmac.ComputeHash(firstModcryptBlock, 0, (int)hdr.digest_sector_size);
|
byte[] hash = hmac.ComputeHash(firstModcryptBlock, 0, (int)hdr.digest_sector_size);
|
||||||
for (int i = 0; i < 20 && !twlEncrypted; i++) twlEncrypted = hash[i] != Hashtable1Data[this.firstDSiHashOffset + hashOff + i];
|
for (int i = 0; i < 20 && !twlEncrypted; i++) twlEncrypted = hash[i] != Hashtable1Data[this.firstDSiHashOffset + hashOff + i];
|
||||||
}
|
}
|
||||||
br.Close();
|
br.Close();
|
||||||
|
|
||||||
// Decrypt modcrypt sections
|
// Decrypt modcrypt sections
|
||||||
if (this.twlEncrypted)
|
if (this.twlEncrypted)
|
||||||
{
|
{
|
||||||
byte[] key = AES128KeyGenerate(hdr);
|
byte[] key = AES128KeyGenerate(hdr);
|
||||||
byte[] counter = new byte[16];
|
byte[] counter = new byte[16];
|
||||||
if (hdr.modcrypt1_size > 0 && hdr.modcrypt1_size < 0xFFFFFFFF)
|
if (hdr.modcrypt1_size > 0 && hdr.modcrypt1_size < 0xFFFFFFFF)
|
||||||
{
|
{
|
||||||
Array.Copy(hdr.hmac_arm9, 0, counter, 0, 16);
|
Array.Copy(hdr.hmac_arm9, 0, counter, 0, 16);
|
||||||
uint offset = hdr.modcrypt1_start - hdr.dsi9_rom_offset;
|
uint offset = hdr.modcrypt1_start - hdr.dsi9_rom_offset;
|
||||||
byte[] decrypted = AES128CTRCrypt(key, counter, this.DSi9Data, offset, hdr.modcrypt1_size);
|
byte[] decrypted = AES128CTRCrypt(key, counter, this.DSi9Data, offset, hdr.modcrypt1_size);
|
||||||
if (offset == 0 && decrypted.Length == this.DSi9Data.Length) this.DSi9Data = decrypted;
|
if (offset == 0 && decrypted.Length == this.DSi9Data.Length) this.DSi9Data = decrypted;
|
||||||
else Array.Copy(decrypted, 0, this.DSi9Data, offset, decrypted.Length);
|
else Array.Copy(decrypted, 0, this.DSi9Data, offset, decrypted.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hdr.modcrypt2_size > 0 && hdr.modcrypt2_size < 0xFFFFFFFF)
|
if (hdr.modcrypt2_size > 0 && hdr.modcrypt2_size < 0xFFFFFFFF)
|
||||||
{
|
{
|
||||||
Array.Copy(hdr.hmac_arm7, 0, counter, 0, 16);
|
Array.Copy(hdr.hmac_arm7, 0, counter, 0, 16);
|
||||||
uint offset = hdr.modcrypt2_start - hdr.dsi7_rom_offset;
|
uint offset = hdr.modcrypt2_start - hdr.dsi7_rom_offset;
|
||||||
byte[] decrypted = AES128CTRCrypt(key, counter, this.DSi7Data, offset, hdr.modcrypt2_size);
|
byte[] decrypted = AES128CTRCrypt(key, counter, this.DSi7Data, offset, hdr.modcrypt2_size);
|
||||||
if (offset == 0 && decrypted.Length == this.DSi7Data.Length) this.DSi7Data = decrypted;
|
if (offset == 0 && decrypted.Length == this.DSi7Data.Length) this.DSi7Data = decrypted;
|
||||||
else Array.Copy(decrypted, 0, this.DSi7Data, offset, decrypted.Length);
|
else Array.Copy(decrypted, 0, this.DSi7Data, offset, decrypted.Length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hmac.Clear();
|
hmac.Clear();
|
||||||
hmac.Dispose();
|
hmac.Dispose();
|
||||||
this.twlEncrypted = (hdr.twlInternalFlags & 2) > 0;
|
this.twlEncrypted = (hdr.twlInternalFlags & 2) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateOverlays9Sha1Hmac(ref sFile arm9, Estructuras.ROMHeader hdr, List<sFile> ov9, HMACSHA1 hmac = null)
|
public void UpdateOverlays9Sha1Hmac(ref sFile arm9, Estructuras.ROMHeader hdr, List<sFile> ov9, HMACSHA1 hmac = null)
|
||||||
{
|
{
|
||||||
if (hmac == null) hmac = new HMACSHA1(hmac_sha1_key);
|
if (hmac == null) hmac = new HMACSHA1(hmac_sha1_key);
|
||||||
byte[][] hashes = new byte[ov9.Count][];
|
byte[][] hashes = new byte[ov9.Count][];
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
for (int i = 0; i < ov9.Count; i++)
|
for (int i = 0; i < ov9.Count; i++)
|
||||||
{
|
{
|
||||||
Stream str = File.OpenRead(ov9[i].path);
|
Stream str = File.OpenRead(ov9[i].path);
|
||||||
byte[] buffer = new byte[ov9[i].size];
|
byte[] buffer = new byte[ov9[i].size];
|
||||||
str.Position = ov9[i].offset;
|
str.Position = ov9[i].offset;
|
||||||
str.Read(buffer, 0, buffer.Length);
|
str.Read(buffer, 0, buffer.Length);
|
||||||
str.Close();
|
str.Close();
|
||||||
hashes[i] = hmac.ComputeHash(buffer);
|
hashes[i] = hmac.ComputeHash(buffer);
|
||||||
for (int j = 0; j < hashes[i].Length && !changed; j++) changed |= hashes[i][j] != this.Overlays9Sha1Hmac[i][j];
|
for (int j = 0; j < hashes[i].Length && !changed; j++) changed |= hashes[i][j] != this.Overlays9Sha1Hmac[i][j];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (changed)
|
if (changed)
|
||||||
{
|
{
|
||||||
// Read arm9
|
// Read arm9
|
||||||
BinaryReader br = new BinaryReader(File.OpenRead(arm9.path));
|
BinaryReader br = new BinaryReader(File.OpenRead(arm9.path));
|
||||||
br.BaseStream.Position = arm9.offset;
|
br.BaseStream.Position = arm9.offset;
|
||||||
byte[] arm9Data = br.ReadBytes((int)arm9.size);
|
byte[] arm9Data = br.ReadBytes((int)arm9.size);
|
||||||
br.Close();
|
br.Close();
|
||||||
|
|
||||||
// Decompress arm9
|
// Decompress arm9
|
||||||
hdr.ARM9size = arm9.size;
|
hdr.ARM9size = arm9.size;
|
||||||
uint initptr = BitConverter.ToUInt32(hdr.reserved2, 0) & 0x3FFF;
|
uint initptr = BitConverter.ToUInt32(hdr.reserved2, 0) & 0x3FFF;
|
||||||
uint hdrptr = BitConverter.ToUInt32(arm9Data, (int)initptr + 0x14) - hdr.ARM9ramAddress;
|
uint hdrptr = BitConverter.ToUInt32(arm9Data, (int)initptr + 0x14) - hdr.ARM9ramAddress;
|
||||||
bool cmparm9 = ARM9BLZ.Decompress(arm9Data, hdr, out arm9Data);
|
uint cmparm9 = ARM9BLZ.Decompress(arm9Data, hdr, out arm9Data);
|
||||||
|
|
||||||
// Get hmac offset
|
// Get hmac offset
|
||||||
uint offset = 0;
|
uint offset = 0;
|
||||||
uint end = BitConverter.ToUInt32(arm9Data, (int)initptr + 8) - hdr.ARM9ramAddress;
|
uint end = BitConverter.ToUInt32(arm9Data, (int)initptr + 8) - hdr.ARM9ramAddress;
|
||||||
for (long i = end - 0x14 * ov9.Count; i >= 0 && offset == 0; i--)
|
for (long i = end - 0x14 * ov9.Count; i >= 0 && offset == 0; i--)
|
||||||
{
|
{
|
||||||
bool cond = arm9Data[i] == this.Overlays9Sha1Hmac[0][0];
|
bool cond = arm9Data[i] == this.Overlays9Sha1Hmac[0][0];
|
||||||
for (int j = 1; j < 20 && cond; j++) cond = arm9Data[i + j] == this.Overlays9Sha1Hmac[0][j];
|
for (int j = 1; j < 20 && cond; j++) cond = arm9Data[i + j] == this.Overlays9Sha1Hmac[0][j];
|
||||||
if (cond) offset = (uint)i;
|
if (cond) offset = (uint)i;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write new hash
|
// Write new hash
|
||||||
if (offset > 0)
|
if (offset > 0)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < ov9.Count; i++) Array.Copy(hashes[i], 0, arm9Data, offset + i * 0x14, 20);
|
for (int i = 0; i < ov9.Count; i++) Array.Copy(hashes[i], 0, arm9Data, offset + i * 0x14, 20);
|
||||||
if (!cmparm9) arm9Data = ARM9BLZ.Compress(arm9Data, hdr, arm9.size - hdrptr);
|
if (cmparm9 == 0) arm9Data = ARM9BLZ.Compress(arm9Data, hdr, arm9.size - hdrptr);
|
||||||
|
|
||||||
string arm9Binary = Path.GetTempFileName();
|
string arm9Binary = Path.GetTempFileName();
|
||||||
File.WriteAllBytes(arm9Binary, arm9Data);
|
File.WriteAllBytes(arm9Binary, arm9Data);
|
||||||
arm9.path = arm9Binary;
|
arm9.path = arm9Binary;
|
||||||
arm9.offset = 0;
|
arm9.offset = 0;
|
||||||
arm9.size = (uint)arm9Data.Length;
|
arm9.size = (uint)arm9Data.Length;
|
||||||
}
|
}
|
||||||
else Console.WriteLine("Overlays9 has been modified but can't update hashes in ARM9.bin!");
|
else Console.WriteLine("Overlays9 has been modified but can't update hashes in ARM9.bin!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ImportArm9iData(string filePath, uint offset, uint size)
|
public void ImportArm9iData(string filePath, uint offset, uint size)
|
||||||
{
|
{
|
||||||
uint sizePad = size;
|
uint sizePad = size;
|
||||||
if (size % 0x10 != 0) sizePad += 0x10 - size % 0x10;
|
if (size % 0x10 != 0) sizePad += 0x10 - size % 0x10;
|
||||||
this.DSi9Data = new byte[sizePad];
|
this.DSi9Data = new byte[sizePad];
|
||||||
for (long i = size; i < sizePad; i++) this.DSi9Data[i] = 0xFF;
|
for (long i = size; i < sizePad; i++) this.DSi9Data[i] = 0xFF;
|
||||||
|
|
||||||
Stream str = File.OpenRead(filePath);
|
Stream str = File.OpenRead(filePath);
|
||||||
str.Position = offset;
|
str.Position = offset;
|
||||||
str.Read(this.DSi9Data, 0, (int)size);
|
str.Read(this.DSi9Data, 0, (int)size);
|
||||||
str.Close();
|
str.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ImportArm7iData(string filePath, uint offset, uint size)
|
public void ImportArm7iData(string filePath, uint offset, uint size)
|
||||||
{
|
{
|
||||||
uint sizePad = size;
|
uint sizePad = size;
|
||||||
if (size % 0x10 != 0) sizePad += 0x10 - size % 0x10;
|
if (size % 0x10 != 0) sizePad += 0x10 - size % 0x10;
|
||||||
this.DSi7Data = new byte[sizePad];
|
this.DSi7Data = new byte[sizePad];
|
||||||
for (long i = size; i < sizePad; i++) this.DSi7Data[i] = 0xFF;
|
for (long i = size; i < sizePad; i++) this.DSi7Data[i] = 0xFF;
|
||||||
|
|
||||||
Stream str = File.OpenRead(filePath);
|
Stream str = File.OpenRead(filePath);
|
||||||
str.Position = offset;
|
str.Position = offset;
|
||||||
str.Read(this.DSi7Data, 0, (int)size);
|
str.Read(this.DSi7Data, 0, (int)size);
|
||||||
str.Close();
|
str.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Write(ref BinaryWriter bw, Estructuras.ROMHeader hdr, out byte[] digest_master_hash)
|
public void Write(ref BinaryWriter bw, Estructuras.ROMHeader hdr, out byte[] digest_master_hash)
|
||||||
{
|
{
|
||||||
// Write DSi ARM sections and padding
|
// Write DSi ARM sections and padding
|
||||||
while (bw.BaseStream.Position < hdr.sector_hashtable_start) bw.Write((byte)0xFF);
|
while (bw.BaseStream.Position < hdr.sector_hashtable_start) bw.Write((byte)0xFF);
|
||||||
bw.BaseStream.Position = hdr.sector_hashtable_start + hdr.sector_hashtable_size;
|
bw.BaseStream.Position = hdr.sector_hashtable_start + hdr.sector_hashtable_size;
|
||||||
while (bw.BaseStream.Position < hdr.block_hashtable_start) bw.Write((byte)0xFF);
|
while (bw.BaseStream.Position < hdr.block_hashtable_start) bw.Write((byte)0xFF);
|
||||||
bw.BaseStream.Position = hdr.block_hashtable_start + hdr.block_hashtable_size;
|
bw.BaseStream.Position = hdr.block_hashtable_start + hdr.block_hashtable_size;
|
||||||
while (bw.BaseStream.Position < hdr.dsi9_rom_offset) bw.Write((byte)0xFF);
|
while (bw.BaseStream.Position < hdr.dsi9_rom_offset) bw.Write((byte)0xFF);
|
||||||
if (this.Header2Data != null && !hdr.trimmedRom)
|
if (this.Header2Data != null && !hdr.trimmedRom)
|
||||||
//if (this.Header2Data != null)
|
//if (this.Header2Data != null)
|
||||||
{
|
{
|
||||||
bw.BaseStream.Position = hdr.digest_twl_start - 0x3000;
|
bw.BaseStream.Position = hdr.digest_twl_start - 0x3000;
|
||||||
for (int j = 0; j < 3; j++) bw.Write(this.Header2Data[j]);
|
for (int j = 0; j < 3; j++) bw.Write(this.Header2Data[j]);
|
||||||
}
|
}
|
||||||
|
|
||||||
bw.Write(this.DSi9Data, 0, this.DSi9Data.Length);
|
bw.Write(this.DSi9Data, 0, this.DSi9Data.Length);
|
||||||
while (bw.BaseStream.Position < hdr.dsi7_rom_offset) bw.Write((byte)0xFF);
|
while (bw.BaseStream.Position < hdr.dsi7_rom_offset) bw.Write((byte)0xFF);
|
||||||
bw.Write(this.DSi7Data, 0, this.DSi7Data.Length);
|
bw.Write(this.DSi7Data, 0, this.DSi7Data.Length);
|
||||||
while (bw.BaseStream.Position < hdr.total_rom_size) bw.Write((byte)0xFF);
|
while (bw.BaseStream.Position < hdr.total_rom_size) bw.Write((byte)0xFF);
|
||||||
long pos = bw.BaseStream.Position;
|
long pos = bw.BaseStream.Position;
|
||||||
|
|
||||||
// Compute NTR Secure Area Hashtable
|
// Compute NTR Secure Area Hashtable
|
||||||
int i = 0;
|
int i = 0;
|
||||||
HMACSHA1 hmac = new HMACSHA1(TWL.hmac_sha1_key);
|
HMACSHA1 hmac = new HMACSHA1(TWL.hmac_sha1_key);
|
||||||
BinaryReader br = new BinaryReader(bw.BaseStream);
|
BinaryReader br = new BinaryReader(bw.BaseStream);
|
||||||
br.BaseStream.Position = hdr.digest_ntr_start;
|
br.BaseStream.Position = hdr.digest_ntr_start;
|
||||||
byte[] saData = br.ReadBytes(0x4000);
|
byte[] saData = br.ReadBytes(0x4000);
|
||||||
uint gameCode = BitConverter.ToUInt32(Encoding.ASCII.GetBytes(hdr.gameCode), 0);
|
uint gameCode = BitConverter.ToUInt32(Encoding.ASCII.GetBytes(hdr.gameCode), 0);
|
||||||
SAEncryptor.EncryptSecureArea(gameCode, saData);
|
SAEncryptor.EncryptSecureArea(gameCode, saData);
|
||||||
while (i < 0x4000 / hdr.digest_sector_size)
|
while (i < 0x4000 / hdr.digest_sector_size)
|
||||||
{
|
{
|
||||||
byte[] hash = hmac.ComputeHash(saData, (int)(i * hdr.digest_sector_size), (int)hdr.digest_sector_size);
|
byte[] hash = hmac.ComputeHash(saData, (int)(i * hdr.digest_sector_size), (int)hdr.digest_sector_size);
|
||||||
bw.BaseStream.Position = hdr.sector_hashtable_start + i * 0x14;
|
bw.BaseStream.Position = hdr.sector_hashtable_start + i * 0x14;
|
||||||
bw.Write(hash);
|
bw.Write(hash);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute NTR Hashtable
|
// Compute NTR Hashtable
|
||||||
br.BaseStream.Position = hdr.digest_ntr_start + 0x4000;
|
br.BaseStream.Position = hdr.digest_ntr_start + 0x4000;
|
||||||
while (br.BaseStream.Position < hdr.digest_ntr_start + hdr.digest_ntr_size)
|
while (br.BaseStream.Position < hdr.digest_ntr_start + hdr.digest_ntr_size)
|
||||||
{
|
{
|
||||||
byte[] hash = hmac.ComputeHash(br.ReadBytes((int)hdr.digest_sector_size));
|
byte[] hash = hmac.ComputeHash(br.ReadBytes((int)hdr.digest_sector_size));
|
||||||
long tmp = br.BaseStream.Position;
|
long tmp = br.BaseStream.Position;
|
||||||
bw.BaseStream.Position = hdr.sector_hashtable_start + i * 0x14;
|
bw.BaseStream.Position = hdr.sector_hashtable_start + i * 0x14;
|
||||||
bw.Write(hash);
|
bw.Write(hash);
|
||||||
br.BaseStream.Position = tmp;
|
br.BaseStream.Position = tmp;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute TWL Hashtable
|
// Compute TWL Hashtable
|
||||||
br.BaseStream.Position = hdr.digest_twl_start;
|
br.BaseStream.Position = hdr.digest_twl_start;
|
||||||
while (br.BaseStream.Position < hdr.digest_twl_start + hdr.digest_twl_size)
|
while (br.BaseStream.Position < hdr.digest_twl_start + hdr.digest_twl_size)
|
||||||
{
|
{
|
||||||
byte[] hash = hmac.ComputeHash(br.ReadBytes((int)hdr.digest_sector_size));
|
byte[] hash = hmac.ComputeHash(br.ReadBytes((int)hdr.digest_sector_size));
|
||||||
long tmp = br.BaseStream.Position;
|
long tmp = br.BaseStream.Position;
|
||||||
bw.BaseStream.Position = hdr.sector_hashtable_start + i * 0x14;
|
bw.BaseStream.Position = hdr.sector_hashtable_start + i * 0x14;
|
||||||
bw.Write(hash);
|
bw.Write(hash);
|
||||||
br.BaseStream.Position = tmp;
|
br.BaseStream.Position = tmp;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute Secondary Hashtable
|
// Compute Secondary Hashtable
|
||||||
i = 0;
|
i = 0;
|
||||||
br.BaseStream.Position = hdr.sector_hashtable_start;
|
br.BaseStream.Position = hdr.sector_hashtable_start;
|
||||||
while (br.BaseStream.Position < hdr.sector_hashtable_start + hdr.sector_hashtable_size)
|
while (br.BaseStream.Position < hdr.sector_hashtable_start + hdr.sector_hashtable_size)
|
||||||
{
|
{
|
||||||
byte[] hash = hmac.ComputeHash(br.ReadBytes((int)hdr.digest_block_sectorcount * 0x14));
|
byte[] hash = hmac.ComputeHash(br.ReadBytes((int)hdr.digest_block_sectorcount * 0x14));
|
||||||
long tmp = br.BaseStream.Position;
|
long tmp = br.BaseStream.Position;
|
||||||
bw.BaseStream.Position = hdr.block_hashtable_start + i * 0x14;
|
bw.BaseStream.Position = hdr.block_hashtable_start + i * 0x14;
|
||||||
bw.Write(hash);
|
bw.Write(hash);
|
||||||
br.BaseStream.Position = tmp;
|
br.BaseStream.Position = tmp;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute Master Hashtable
|
// Compute Master Hashtable
|
||||||
br.BaseStream.Position = hdr.block_hashtable_start;
|
br.BaseStream.Position = hdr.block_hashtable_start;
|
||||||
digest_master_hash = hmac.ComputeHash(br.ReadBytes((int)hdr.block_hashtable_size));
|
digest_master_hash = hmac.ComputeHash(br.ReadBytes((int)hdr.block_hashtable_size));
|
||||||
|
|
||||||
// Encrypt DSi sections
|
// Encrypt DSi sections
|
||||||
if (this.twlEncrypted)
|
if (this.twlEncrypted)
|
||||||
{
|
{
|
||||||
byte[] key = AES128KeyGenerate(hdr);
|
byte[] key = AES128KeyGenerate(hdr);
|
||||||
byte[] counter9 = new byte[16];
|
byte[] counter9 = new byte[16];
|
||||||
byte[] counter7 = new byte[16];
|
byte[] counter7 = new byte[16];
|
||||||
Array.Copy(hdr.hmac_arm9, 0, counter9, 0, 16);
|
Array.Copy(hdr.hmac_arm9, 0, counter9, 0, 16);
|
||||||
Array.Copy(hdr.hmac_arm7, 0, counter7, 0, 16);
|
Array.Copy(hdr.hmac_arm7, 0, counter7, 0, 16);
|
||||||
bw.BaseStream.Position = hdr.dsi9_rom_offset;
|
bw.BaseStream.Position = hdr.dsi9_rom_offset;
|
||||||
if (hdr.modcrypt1_size > 0) bw.Write(AES128CTRCrypt(key, counter9, this.DSi9Data, 0, hdr.modcrypt1_size));
|
if (hdr.modcrypt1_size > 0) bw.Write(AES128CTRCrypt(key, counter9, this.DSi9Data, 0, hdr.modcrypt1_size));
|
||||||
bw.BaseStream.Position = hdr.dsi7_rom_offset;
|
bw.BaseStream.Position = hdr.dsi7_rom_offset;
|
||||||
if (hdr.modcrypt2_size > 0) bw.Write(AES128CTRCrypt(key, counter7, this.DSi7Data, 0, hdr.modcrypt2_size));
|
if (hdr.modcrypt2_size > 0) bw.Write(AES128CTRCrypt(key, counter7, this.DSi7Data, 0, hdr.modcrypt2_size));
|
||||||
}
|
}
|
||||||
|
|
||||||
bw.BaseStream.Position = pos;
|
bw.BaseStream.Position = pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void UpdateHeaderSignatures(
|
public static void UpdateHeaderSignatures(
|
||||||
ref BinaryWriter bw,
|
ref BinaryWriter bw,
|
||||||
ref Estructuras.ROMHeader header,
|
ref Estructuras.ROMHeader header,
|
||||||
string header_file,
|
string header_file,
|
||||||
bool keep_original)
|
bool keep_original)
|
||||||
{
|
{
|
||||||
long pos = bw.BaseStream.Position;
|
long pos = bw.BaseStream.Position;
|
||||||
|
|
||||||
// Update digest master hash
|
// Update digest master hash
|
||||||
bw.BaseStream.Position = 0x328;
|
bw.BaseStream.Position = 0x328;
|
||||||
bw.Write(header.hmac_digest_master);
|
bw.Write(header.hmac_digest_master);
|
||||||
|
|
||||||
// Read signed header data
|
// Read signed header data
|
||||||
BinaryReader br = new BinaryReader(File.OpenRead(header_file));
|
BinaryReader br = new BinaryReader(File.OpenRead(header_file));
|
||||||
byte[] hdrSignedData = br.ReadBytes(0xE00);
|
byte[] hdrSignedData = br.ReadBytes(0xE00);
|
||||||
Array.Copy(header.hmac_digest_master, 0, hdrSignedData, 0x328, 0x14);
|
Array.Copy(header.hmac_digest_master, 0, hdrSignedData, 0x328, 0x14);
|
||||||
br.Close();
|
br.Close();
|
||||||
|
|
||||||
// Verify RSA Signature
|
// Verify RSA Signature
|
||||||
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(1024);
|
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(1024);
|
||||||
RSAParameters rsaKey = new RSAParameters();
|
RSAParameters rsaKey = new RSAParameters();
|
||||||
rsaKey.Exponent = new byte[] { 1, 0, 1 };
|
rsaKey.Exponent = new byte[] { 1, 0, 1 };
|
||||||
rsaKey.Modulus = (byte[])TWL.rsaPublicKey.Clone();
|
rsaKey.Modulus = (byte[])TWL.rsaPublicKey.Clone();
|
||||||
rsaKey.D = null; // In future: here set Private key
|
rsaKey.D = null; // In future: here set Private key
|
||||||
rsa.ImportParameters(rsaKey);
|
rsa.ImportParameters(rsaKey);
|
||||||
bool verify = rsa.VerifyData(hdrSignedData, new SHA1CryptoServiceProvider(), header.rsa_signature);
|
bool verify = rsa.VerifyData(hdrSignedData, new SHA1CryptoServiceProvider(), header.rsa_signature);
|
||||||
if (!verify)
|
if (!verify)
|
||||||
{
|
{
|
||||||
// RSA encrypt signature
|
// RSA encrypt signature
|
||||||
if (rsaKey.D != null)
|
if (rsaKey.D != null)
|
||||||
{
|
{
|
||||||
header.rsa_signature = rsa.SignData(hdrSignedData, new SHA1CryptoServiceProvider());
|
header.rsa_signature = rsa.SignData(hdrSignedData, new SHA1CryptoServiceProvider());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Calc SHA1 hash
|
// Calc SHA1 hash
|
||||||
SHA1 sha1 = new SHA1CryptoServiceProvider();
|
SHA1 sha1 = new SHA1CryptoServiceProvider();
|
||||||
byte[] hash = sha1.ComputeHash(hdrSignedData);
|
byte[] hash = sha1.ComputeHash(hdrSignedData);
|
||||||
//Array.Reverse(hash);
|
//Array.Reverse(hash);
|
||||||
sha1.Clear();
|
sha1.Clear();
|
||||||
sha1.Dispose();
|
sha1.Dispose();
|
||||||
|
|
||||||
if (!keep_original)
|
if (!keep_original)
|
||||||
{
|
{
|
||||||
// Set unencrypted signature for no$gba compatible
|
// Set unencrypted signature for no$gba compatible
|
||||||
header.rsa_signature = (byte[])TWL.rsaSignatureMask.Clone();
|
header.rsa_signature = (byte[])TWL.rsaSignatureMask.Clone();
|
||||||
Array.Copy(hash, 0, header.rsa_signature, 0x80 - 0x14, 0x14);
|
Array.Copy(hash, 0, header.rsa_signature, 0x80 - 0x14, 0x14);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write signature
|
// Write signature
|
||||||
bw.BaseStream.Position = 0xF80;
|
bw.BaseStream.Position = 0xF80;
|
||||||
bw.Write(header.rsa_signature, 0, 0x80);
|
bw.Write(header.rsa_signature, 0, 0x80);
|
||||||
}
|
}
|
||||||
|
|
||||||
bw.BaseStream.Position = pos;
|
bw.BaseStream.Position = pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] AES128CTRCrypt(byte[] key, byte[] counter, byte[] data, uint offset, uint size)
|
private static byte[] AES128CTRCrypt(byte[] key, byte[] counter, byte[] data, uint offset, uint size)
|
||||||
{
|
{
|
||||||
AES128CounterMode aes128 = new AES128CounterMode(counter);
|
AES128CounterMode aes128 = new AES128CounterMode(counter);
|
||||||
ICryptoTransform ict = aes128.CreateEncryptor(key, null);
|
ICryptoTransform ict = aes128.CreateEncryptor(key, null);
|
||||||
return ict.TransformFinalBlock(data, (int)offset, (int)size);
|
return ict.TransformFinalBlock(data, (int)offset, (int)size);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] AES128KeyGenerate(Estructuras.ROMHeader hdr)
|
private static byte[] AES128KeyGenerate(Estructuras.ROMHeader hdr)
|
||||||
{
|
{
|
||||||
bool debug = ((hdr.twlInternalFlags & 4) > 0) || ((hdr.appflags[3] & 0x80) > 0);
|
bool debug = ((hdr.twlInternalFlags & 4) > 0) || ((hdr.appflags[3] & 0x80) > 0);
|
||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
byte[] key = new byte[16];
|
byte[] key = new byte[16];
|
||||||
Array.Copy(Encoding.ASCII.GetBytes(hdr.gameTitle), 0, key, 0, 12);
|
Array.Copy(Encoding.ASCII.GetBytes(hdr.gameTitle), 0, key, 0, 12);
|
||||||
Array.Copy(Encoding.ASCII.GetBytes(hdr.gameCode), 0, key, 12, 4);
|
Array.Copy(Encoding.ASCII.GetBytes(hdr.gameCode), 0, key, 12, 4);
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
byte[] keyX = new byte[16];
|
byte[] keyX = new byte[16];
|
||||||
byte[] keyY = new byte[16];
|
byte[] keyY = new byte[16];
|
||||||
Array.Copy(Encoding.ASCII.GetBytes("Nintendo"), 0, keyX, 0, 8);
|
Array.Copy(Encoding.ASCII.GetBytes("Nintendo"), 0, keyX, 0, 8);
|
||||||
Array.Copy(Encoding.ASCII.GetBytes(hdr.gameCode), 0, keyX, 8, 4);
|
Array.Copy(Encoding.ASCII.GetBytes(hdr.gameCode), 0, keyX, 8, 4);
|
||||||
for (int j = 0; j < 4; j++) keyX[12 + j] = (byte)hdr.gameCode[3 - j];
|
for (int j = 0; j < 4; j++) keyX[12 + j] = (byte)hdr.gameCode[3 - j];
|
||||||
//Array.Copy(BitConverter.GetBytes(hdr.tid_low), 0, keyX, 12, 4);
|
//Array.Copy(BitConverter.GetBytes(hdr.tid_low), 0, keyX, 12, 4);
|
||||||
Array.Copy(hdr.hmac_arm9i, 0, keyY, 0, 16);
|
Array.Copy(hdr.hmac_arm9i, 0, keyY, 0, 16);
|
||||||
return AES128KeyGenerate(keyX, keyY);
|
return AES128KeyGenerate(keyX, keyY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] AES128KeyGenerate(byte[] keyX, byte[] keyY)
|
private static byte[] AES128KeyGenerate(byte[] keyX, byte[] keyY)
|
||||||
{
|
{
|
||||||
// Key = ((Key_X XOR Key_Y) + FFFEFB4E295902582A680F5F1A4F3E79h) ROL 42
|
// Key = ((Key_X XOR Key_Y) + FFFEFB4E295902582A680F5F1A4F3E79h) ROL 42
|
||||||
byte[] key = new byte[16];
|
byte[] key = new byte[16];
|
||||||
for (int i = 0; i < 16; i++) key[i] = (byte)(keyX[i] ^ keyY[i]);
|
for (int i = 0; i < 16; i++) key[i] = (byte)(keyX[i] ^ keyY[i]);
|
||||||
|
|
||||||
UInt64[] tmp = new ulong[2];
|
UInt64[] tmp = new ulong[2];
|
||||||
UInt64[] xyKey = new[] { BitConverter.ToUInt64(key, 0), BitConverter.ToUInt64(key, 8) };
|
UInt64[] xyKey = new[] { BitConverter.ToUInt64(key, 0), BitConverter.ToUInt64(key, 8) };
|
||||||
UInt64[] cKey = new[] { BitConverter.ToUInt64(modcryptCmnKey, 0), BitConverter.ToUInt64(modcryptCmnKey, 8) };
|
UInt64[] cKey = new[] { BitConverter.ToUInt64(modcryptCmnKey, 0), BitConverter.ToUInt64(modcryptCmnKey, 8) };
|
||||||
tmp[0] = (cKey[0] >> 1) + (xyKey[0] >> 1) + (cKey[0] & xyKey[0] & 1);
|
tmp[0] = (cKey[0] >> 1) + (xyKey[0] >> 1) + (cKey[0] & xyKey[0] & 1);
|
||||||
tmp[0] = tmp[0] >> 63;
|
tmp[0] = tmp[0] >> 63;
|
||||||
cKey[0] = cKey[0] + xyKey[0];
|
cKey[0] = cKey[0] + xyKey[0];
|
||||||
cKey[1] = cKey[1] + xyKey[1] + tmp[0];
|
cKey[1] = cKey[1] + xyKey[1] + tmp[0];
|
||||||
|
|
||||||
int shift = 42;
|
int shift = 42;
|
||||||
tmp[0] = cKey[0] << shift;
|
tmp[0] = cKey[0] << shift;
|
||||||
tmp[1] = cKey[1] << shift;
|
tmp[1] = cKey[1] << shift;
|
||||||
tmp[0] |= (cKey[1] >> (64 - shift));
|
tmp[0] |= (cKey[1] >> (64 - shift));
|
||||||
tmp[1] |= (cKey[0] >> (64 - shift));
|
tmp[1] |= (cKey[0] >> (64 - shift));
|
||||||
cKey[0] = tmp[0];
|
cKey[0] = tmp[0];
|
||||||
cKey[1] = tmp[1];
|
cKey[1] = tmp[1];
|
||||||
|
|
||||||
Array.Copy(BitConverter.GetBytes(cKey[0]), 0, key, 0, 8);
|
Array.Copy(BitConverter.GetBytes(cKey[0]), 0, key, 0, 8);
|
||||||
Array.Copy(BitConverter.GetBytes(cKey[1]), 0, key, 8, 8);
|
Array.Copy(BitConverter.GetBytes(cKey[1]), 0, key, 8, 8);
|
||||||
|
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,16 +18,20 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
using System;
|
using System;
|
||||||
//using System.Collections.Generic;
|
|
||||||
//using System.Linq;
|
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
//using System.Reflection;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Tinke
|
namespace Tinke
|
||||||
{
|
{
|
||||||
static class Program
|
static class Program
|
||||||
{
|
{
|
||||||
|
[DllImport("kernel32.dll", SetLastError = true)]
|
||||||
|
public static extern bool AttachConsole(int dwProcessId);
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll", SetLastError = true)]
|
||||||
|
public static extern bool FreeConsole();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Punto de entrada principal para la aplicación.
|
/// Punto de entrada principal para la aplicación.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -35,7 +39,7 @@ namespace Tinke
|
|||||||
static void Main(string[] args)
|
static void Main(string[] args)
|
||||||
{
|
{
|
||||||
#region Comprobación de archivos necesarios
|
#region Comprobación de archivos necesarios
|
||||||
string[] archivos = new string[] { "Ekona.dll", "DSDecmp.dll" };
|
string[] archivos = new string[] { "Ekona.dll", "DSDecmp.dll" , "Be.Windows.Forms.HexBox.dll" };
|
||||||
string faltan = "";
|
string faltan = "";
|
||||||
for (int i = 0; i < archivos.Length; i++)
|
for (int i = 0; i < archivos.Length; i++)
|
||||||
{
|
{
|
||||||
@ -55,5 +59,4 @@ namespace Tinke
|
|||||||
Application.Run(new Sistema());
|
Application.Run(new Sistema());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
151
Tinke/Sistema.cs
151
Tinke/Sistema.cs
@ -62,12 +62,31 @@ namespace Tinke
|
|||||||
// The IE control of the Debug windows doesn't work in Mono
|
// The IE control of the Debug windows doesn't work in Mono
|
||||||
isMono = (Type.GetType("Mono.Runtime") != null);
|
isMono = (Type.GetType("Mono.Runtime") != null);
|
||||||
|
|
||||||
|
if (Environment.GetCommandLineArgs().Length == 2 && (Environment.GetCommandLineArgs()[1] == "-h" || Environment.GetCommandLineArgs()[1] == "--help"))
|
||||||
|
{
|
||||||
|
Program.AttachConsole(-1);
|
||||||
|
Console.WriteLine("\n" + this.Text);
|
||||||
|
Console.WriteLine("Usage: Tinke.exe rom_name [option]");
|
||||||
|
Console.WriteLine("options:");
|
||||||
|
Console.WriteLine("-x: Extract all files from nds rom");
|
||||||
|
Console.WriteLine("-r: Replace all nitrofs files by dir, need -o to set an output rom path(-o Only allowed after -r)");
|
||||||
|
Console.WriteLine("-h or --help: Show this message, must be the first param...");
|
||||||
|
Program.FreeConsole();
|
||||||
|
SendKeys.SendWait("{ENTER}");
|
||||||
|
}
|
||||||
|
|
||||||
sb = new StringBuilder();
|
sb = new StringBuilder();
|
||||||
TextWriter tw = new StringWriter(sb);
|
TextWriter tw = new StringWriter(sb);
|
||||||
tw.NewLine = "<br>";
|
tw.NewLine = "<br>";
|
||||||
if (!isMono)
|
if (!isMono && !(Environment.GetCommandLineArgs().Length >= 3 && (Environment.GetCommandLineArgs()[2] == "-x" || Environment.GetCommandLineArgs()[2] == "-r")))
|
||||||
Console.SetOut(tw);
|
Console.SetOut(tw);
|
||||||
|
|
||||||
|
if (Environment.GetCommandLineArgs().Length >= 3 && (Environment.GetCommandLineArgs()[2] == "-x" || Environment.GetCommandLineArgs()[2] == "-r"))
|
||||||
|
{
|
||||||
|
Program.AttachConsole(-1);
|
||||||
|
Console.WriteLine("\n" + this.Text);
|
||||||
|
}
|
||||||
|
|
||||||
#region Language
|
#region Language
|
||||||
if (!File.Exists(Application.StartupPath + Path.DirectorySeparatorChar + "Tinke.xml"))
|
if (!File.Exists(Application.StartupPath + Path.DirectorySeparatorChar + "Tinke.xml"))
|
||||||
{
|
{
|
||||||
@ -144,11 +163,47 @@ namespace Tinke
|
|||||||
filesToRead[0] = o.SelectedPath;
|
filesToRead[0] = o.SelectedPath;
|
||||||
o.Dispose();
|
o.Dispose();
|
||||||
}
|
}
|
||||||
|
else if (Environment.GetCommandLineArgs()[1] == "-h" || Environment.GetCommandLineArgs()[1] == "--help")
|
||||||
|
{
|
||||||
|
Application.Exit();
|
||||||
|
return;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
filesToRead[0] = Environment.GetCommandLineArgs()[1];
|
filesToRead[0] = Environment.GetCommandLineArgs()[1];
|
||||||
}
|
}
|
||||||
else if (Environment.GetCommandLineArgs().Length >= 3)
|
else if (Environment.GetCommandLineArgs().Length >= 3)
|
||||||
{
|
{
|
||||||
|
if (Environment.GetCommandLineArgs()[2] == "-x")
|
||||||
|
{
|
||||||
|
filesToRead[0] = Environment.GetCommandLineArgs()[1];
|
||||||
|
ReadGame(filesToRead[0]);
|
||||||
|
sFolder folderSelect = accion.Root;
|
||||||
|
|
||||||
|
if (Environment.GetCommandLineArgs().Length > 3 && Environment.GetCommandLineArgs()[3] is string)
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(Environment.GetCommandLineArgs()[3] + Path.DirectorySeparatorChar + folderSelect.name);
|
||||||
|
RecursivoExtractFolder(folderSelect, Environment.GetCommandLineArgs()[3] + Path.DirectorySeparatorChar + folderSelect.name);
|
||||||
|
Console.WriteLine("Extract all files to " + Environment.GetCommandLineArgs()[3] + Path.DirectorySeparatorChar + folderSelect.name);
|
||||||
|
} else
|
||||||
|
Console.WriteLine("Param error...");
|
||||||
|
Program.FreeConsole();
|
||||||
|
SendKeys.SendWait("{ENTER}");
|
||||||
|
Application.Exit();
|
||||||
|
} else if (Environment.GetCommandLineArgs()[2] == "-r" && Environment.GetCommandLineArgs().Length > 5 && Environment.GetCommandLineArgs()[4] == "-o")
|
||||||
|
{
|
||||||
|
filesToRead[0] = Environment.GetCommandLineArgs()[1];
|
||||||
|
ReadGame(filesToRead[0]);
|
||||||
|
if (Environment.GetCommandLineArgs()[3] is string)
|
||||||
|
{
|
||||||
|
ChangeByDir(Environment.GetCommandLineArgs()[3]);
|
||||||
|
}
|
||||||
|
// parse saving args
|
||||||
|
for(int i = 5; i < Environment.GetCommandLineArgs().Length; i++)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
filesToRead = new String[Environment.GetCommandLineArgs().Length - 1];
|
filesToRead = new String[Environment.GetCommandLineArgs().Length - 1];
|
||||||
Array.Copy(Environment.GetCommandLineArgs(), 1, filesToRead, 0, filesToRead.Length);
|
Array.Copy(Environment.GetCommandLineArgs(), 1, filesToRead, 0, filesToRead.Length);
|
||||||
}
|
}
|
||||||
@ -1444,6 +1499,8 @@ namespace Tinke
|
|||||||
* Files...
|
* Files...
|
||||||
*/
|
*/
|
||||||
bool keep_original = false;
|
bool keep_original = false;
|
||||||
|
bool a9_recomp = false;
|
||||||
|
bool a9_bestcomp = false;
|
||||||
Nitro.Estructuras.ROMHeader header = romInfo.Cabecera;
|
Nitro.Estructuras.ROMHeader header = romInfo.Cabecera;
|
||||||
|
|
||||||
Dialog.SaveOptions dialog = new Dialog.SaveOptions();
|
Dialog.SaveOptions dialog = new Dialog.SaveOptions();
|
||||||
@ -1453,6 +1510,10 @@ namespace Tinke
|
|||||||
keep_original = true;
|
keep_original = true;
|
||||||
if (dialog.IsSafeTrim)
|
if (dialog.IsSafeTrim)
|
||||||
header.trimmedRom = true;
|
header.trimmedRom = true;
|
||||||
|
if (dialog.IsReCompress)
|
||||||
|
a9_recomp = true;
|
||||||
|
if (dialog.IsBetterCompress)
|
||||||
|
a9_bestcomp = true;
|
||||||
|
|
||||||
Thread create = new Thread(ThreadEspera)
|
Thread create = new Thread(ThreadEspera)
|
||||||
{
|
{
|
||||||
@ -1533,16 +1594,19 @@ namespace Tinke
|
|||||||
header.secureCRC16 = SecureArea.CalcCRC(this.secureArea.EncryptedData, gameCode);
|
header.secureCRC16 = SecureArea.CalcCRC(this.secureArea.EncryptedData, gameCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cmparm9 = true;
|
uint cmparm9 = 0;
|
||||||
if (!ov9Sha1Hmac_updated)
|
if (!ov9Sha1Hmac_updated)
|
||||||
{
|
{
|
||||||
uint initptr = BitConverter.ToUInt32(header.reserved2, 0) & 0x3FFF;
|
uint initptr = BitConverter.ToUInt32(header.reserved2, 0) & 0x3FFF;
|
||||||
uint hdrptr = BitConverter.ToUInt32(arm9Data, (int)initptr + 0x14) - header.ARM9ramAddress;
|
uint hdrptr = BitConverter.ToUInt32(arm9Data, (int)initptr + 0x14) - header.ARM9ramAddress;
|
||||||
byte[] arm9Data_dec;
|
byte[] arm9Data_dec;
|
||||||
cmparm9 = ARM9BLZ.Decompress(arm9Data, header, out arm9Data_dec);
|
cmparm9 = ARM9BLZ.Decompress(arm9Data, header, out arm9Data_dec);
|
||||||
if (!cmparm9)
|
if (cmparm9 == 0 && a9_recomp)
|
||||||
{
|
{
|
||||||
arm9Data = ARM9BLZ.Compress(arm9Data_dec, header, 0);
|
arm9Data = ARM9BLZ.Compress(arm9Data, header, 0, a9_bestcomp);
|
||||||
|
} else if (cmparm9 == 1 && a9_recomp)
|
||||||
|
{
|
||||||
|
arm9Data = ARM9BLZ.Compress(arm9Data_dec, header, 0, a9_bestcomp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1551,7 +1615,7 @@ namespace Tinke
|
|||||||
bw.Flush();
|
bw.Flush();
|
||||||
br.Close();
|
br.Close();
|
||||||
|
|
||||||
if (!ov9Sha1Hmac_updated && !cmparm9)
|
if (!ov9Sha1Hmac_updated && a9_recomp)
|
||||||
{
|
{
|
||||||
arm9.path = arm9Binary;
|
arm9.path = arm9Binary;
|
||||||
arm9.offset = 0;
|
arm9.offset = 0;
|
||||||
@ -1627,7 +1691,6 @@ namespace Tinke
|
|||||||
|
|
||||||
Console.WriteLine(Tools.Helper.GetTranslation("Messages", "S09"), new FileInfo(arm9Binary).Length);
|
Console.WriteLine(Tools.Helper.GetTranslation("Messages", "S09"), new FileInfo(arm9Binary).Length);
|
||||||
|
|
||||||
|
|
||||||
// Escribismo el ARM7 Binary
|
// Escribismo el ARM7 Binary
|
||||||
string arm7Binary = Path.GetTempFileName();
|
string arm7Binary = Path.GetTempFileName();
|
||||||
string overlays7 = Path.GetTempFileName();
|
string overlays7 = Path.GetTempFileName();
|
||||||
@ -1690,7 +1753,6 @@ namespace Tinke
|
|||||||
bw.Close();
|
bw.Close();
|
||||||
Console.WriteLine(Tools.Helper.GetTranslation("Messages", "S09"), new FileInfo(arm7Binary).Length);
|
Console.WriteLine(Tools.Helper.GetTranslation("Messages", "S09"), new FileInfo(arm7Binary).Length);
|
||||||
|
|
||||||
|
|
||||||
// Escribimos el FNT (File Name Table)
|
// Escribimos el FNT (File Name Table)
|
||||||
string fileFNT = Path.GetTempFileName();
|
string fileFNT = Path.GetTempFileName();
|
||||||
Console.Write("\tFile Name Table (FNT)...");
|
Console.Write("\tFile Name Table (FNT)...");
|
||||||
@ -1723,7 +1785,7 @@ namespace Tinke
|
|||||||
// Escribimos el banner
|
// Escribimos el banner
|
||||||
string banner = Path.GetTempFileName();
|
string banner = Path.GetTempFileName();
|
||||||
header.banner_size = Nitro.NDS.EscribirBanner(banner, romInfo.Banner);
|
header.banner_size = Nitro.NDS.EscribirBanner(banner, romInfo.Banner);
|
||||||
|
|
||||||
// Escribimos el FAT (File Allocation Table)
|
// Escribimos el FAT (File Allocation Table)
|
||||||
string fileFAT = Path.GetTempFileName();
|
string fileFAT = Path.GetTempFileName();
|
||||||
header.FAToffset = currPos;
|
header.FAToffset = currPos;
|
||||||
@ -1865,15 +1927,8 @@ namespace Tinke
|
|||||||
o.DefaultExt = ".nds";
|
o.DefaultExt = ".nds";
|
||||||
o.Filter = "Nintendo DS ROM (*.nds)|*.nds";
|
o.Filter = "Nintendo DS ROM (*.nds)|*.nds";
|
||||||
o.OverwritePrompt = true;
|
o.OverwritePrompt = true;
|
||||||
Open_Dialog:
|
|
||||||
if (o.ShowDialog() == System.Windows.Forms.DialogResult.OK)
|
if (o.ShowDialog() == System.Windows.Forms.DialogResult.OK)
|
||||||
{
|
{
|
||||||
if (o.FileName == accion.ROMFile)
|
|
||||||
{
|
|
||||||
MessageBox.Show(Tools.Helper.GetTranslation("Sistema", "S44"));
|
|
||||||
goto Open_Dialog;
|
|
||||||
}
|
|
||||||
|
|
||||||
Thread saverom = new Thread(ThreadEspera)
|
Thread saverom = new Thread(ThreadEspera)
|
||||||
{
|
{
|
||||||
IsBackground = true
|
IsBackground = true
|
||||||
@ -1921,7 +1976,7 @@ namespace Tinke
|
|||||||
}
|
}
|
||||||
sb.Length = 0;
|
sb.Length = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Borramos archivos ya innecesarios
|
// Borramos archivos ya innecesarios
|
||||||
File.Delete(header_file);
|
File.Delete(header_file);
|
||||||
File.Delete(arm9Binary);
|
File.Delete(arm9Binary);
|
||||||
@ -1932,10 +1987,6 @@ namespace Tinke
|
|||||||
File.Delete(fileFAT);
|
File.Delete(fileFAT);
|
||||||
File.Delete(banner);
|
File.Delete(banner);
|
||||||
File.Delete(files);
|
File.Delete(files);
|
||||||
|
|
||||||
//if (!isMono)
|
|
||||||
//debug.Add_Text(sb.ToString());
|
|
||||||
//sb.Length = 0;
|
|
||||||
}
|
}
|
||||||
private void btnImport_Click(object sender, EventArgs e)
|
private void btnImport_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
@ -2249,11 +2300,7 @@ namespace Tinke
|
|||||||
|
|
||||||
if (!isMono)
|
if (!isMono)
|
||||||
{
|
{
|
||||||
try
|
CloseEspera(wait);
|
||||||
{
|
|
||||||
espera.Close();
|
|
||||||
}
|
|
||||||
catch { };
|
|
||||||
debug.Add_Text(sb.ToString());
|
debug.Add_Text(sb.ToString());
|
||||||
}
|
}
|
||||||
sb.Length = 0;
|
sb.Length = 0;
|
||||||
@ -2502,30 +2549,10 @@ namespace Tinke
|
|||||||
btnDesplazar.Text = ">>>>>";
|
btnDesplazar.Text = ">>>>>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private void btnImport1_Click(object sender, EventArgs e)
|
private void ChangeByDir(string files_path)
|
||||||
{
|
{
|
||||||
Thread matching = new Thread(ThreadEspera)
|
|
||||||
{
|
|
||||||
IsBackground = true
|
|
||||||
};
|
|
||||||
if (!isMono)
|
|
||||||
matching.Start("S08");
|
|
||||||
|
|
||||||
FolderBrowserDialog FBD = new FolderBrowserDialog
|
|
||||||
{
|
|
||||||
Description = Tools.Helper.GetTranslation("Sistema", "S47"),
|
|
||||||
ShowNewFolderButton = false
|
|
||||||
};
|
|
||||||
if (FBD.ShowDialog() != DialogResult.OK)
|
|
||||||
{
|
|
||||||
if (!isMono)
|
|
||||||
CloseEspera(matching);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Console.WriteLine(FBD.SelectedPath);
|
|
||||||
List<string> files = new List<string>();
|
List<string> files = new List<string>();
|
||||||
files = GetAllSubFiles(FBD.SelectedPath, files);
|
files = GetAllSubFiles(files_path, files);
|
||||||
foreach (string currFile in files)
|
foreach (string currFile in files)
|
||||||
{
|
{
|
||||||
string nstr;
|
string nstr;
|
||||||
@ -2569,12 +2596,32 @@ namespace Tinke
|
|||||||
accion.Change_File(fileToBeChanged.id, currFile);
|
accion.Change_File(fileToBeChanged.id, currFile);
|
||||||
Console.WriteLine(currFile);
|
Console.WriteLine(currFile);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
private void btnImport1_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
Thread matching = new Thread(ThreadEspera)
|
||||||
|
{
|
||||||
|
IsBackground = true
|
||||||
|
};
|
||||||
if (!isMono)
|
if (!isMono)
|
||||||
try
|
matching.Start("S08");
|
||||||
{
|
|
||||||
espera.Close();
|
FolderBrowserDialog FBD = new FolderBrowserDialog
|
||||||
}
|
{
|
||||||
catch { };
|
Description = Tools.Helper.GetTranslation("Sistema", "S47"),
|
||||||
|
ShowNewFolderButton = false
|
||||||
|
};
|
||||||
|
if (FBD.ShowDialog() != DialogResult.OK)
|
||||||
|
{
|
||||||
|
if (!isMono)
|
||||||
|
CloseEspera(matching);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine(FBD.SelectedPath);
|
||||||
|
ChangeByDir(FBD.SelectedPath);
|
||||||
|
if (!isMono)
|
||||||
|
CloseEspera(matching);
|
||||||
}
|
}
|
||||||
public static List<string> GetAllSubFiles(string directoryPath, List<string> files)
|
public static List<string> GetAllSubFiles(string directoryPath, List<string> files)
|
||||||
{
|
{
|
||||||
|
@ -1,89 +1,91 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace Tinke.Tools
|
namespace Tinke.Tools
|
||||||
{
|
{
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
using DSDecmp.Formats;
|
using DSDecmp.Formats;
|
||||||
|
|
||||||
using Nitro;
|
using Nitro;
|
||||||
|
|
||||||
class ARM9BLZ
|
class ARM9BLZ
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Decompress ARM9.bin
|
/// Decompress ARM9.bin
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="arm9Data">Compressed ARM9.bin data</param>
|
/// <param name="arm9Data">Compressed ARM9.bin data</param>
|
||||||
/// <param name="hdr">ROM header</param>
|
/// <param name="hdr">ROM header</param>
|
||||||
/// <param name="decompressed">Decompressed data</param>
|
/// <param name="decompressed">Decompressed data</param>
|
||||||
/// <returns>True if the decompression was successful.</returns>
|
/// <returns>0 = uncompressed; 1 = compressed</returns>
|
||||||
public static bool Decompress(byte[] arm9Data, Estructuras.ROMHeader hdr, out byte[] decompressed)
|
public static uint Decompress(byte[] arm9Data, Estructuras.ROMHeader hdr, out byte[] decompressed)
|
||||||
{
|
{
|
||||||
decompressed = arm9Data;
|
decompressed = arm9Data;
|
||||||
uint nitrocode_length = 0;
|
uint nitrocode_length = 0;
|
||||||
if (arm9Data[arm9Data.Length - 0xC] == 0x21 && arm9Data[arm9Data.Length - 0xB] == 0x06
|
if (arm9Data[arm9Data.Length - 0xC] == 0x21 && arm9Data[arm9Data.Length - 0xB] == 0x06
|
||||||
&& arm9Data[arm9Data.Length - 0xA] == 0xC0 && arm9Data[arm9Data.Length - 0x9] == 0xDE)
|
&& arm9Data[arm9Data.Length - 0xA] == 0xC0 && arm9Data[arm9Data.Length - 0x9] == 0xDE)
|
||||||
{
|
{
|
||||||
nitrocode_length = 0x0C; //Nitrocode found.
|
nitrocode_length = 0x0C; //Nitrocode found.
|
||||||
}
|
}
|
||||||
uint initptr = BitConverter.ToUInt32(hdr.reserved2, 0) & 0x3FFF;
|
uint initptr = BitConverter.ToUInt32(hdr.reserved2, 0) & 0x3FFF;
|
||||||
uint hdrptr = BitConverter.ToUInt32(arm9Data, (int)initptr + 0x14);
|
uint hdrptr = BitConverter.ToUInt32(arm9Data, (int)initptr + 0x14);
|
||||||
if (initptr == 0)
|
if (initptr == 0)
|
||||||
{
|
{
|
||||||
hdrptr = hdr.ARM9ramAddress + hdr.ARM9size;
|
hdrptr = hdr.ARM9ramAddress + hdr.ARM9size;
|
||||||
}
|
}
|
||||||
uint postSize = (uint)arm9Data.Length - (hdrptr - hdr.ARM9ramAddress);
|
uint postSize = (uint)arm9Data.Length - (hdrptr - hdr.ARM9ramAddress);
|
||||||
bool cmparm9 = hdrptr > hdr.ARM9ramAddress && hdrptr + nitrocode_length >= hdr.ARM9ramAddress + arm9Data.Length;
|
bool cmparm9 = hdrptr > hdr.ARM9ramAddress && hdrptr + nitrocode_length >= hdr.ARM9ramAddress + arm9Data.Length;
|
||||||
if (cmparm9)
|
if (cmparm9)
|
||||||
{
|
{
|
||||||
Stream input = new MemoryStream(arm9Data);
|
Stream input = new MemoryStream(arm9Data);
|
||||||
MemoryStream output = new MemoryStream();
|
MemoryStream output = new MemoryStream();
|
||||||
|
|
||||||
LZOvl blz = new LZOvl();
|
LZOvl blz = new LZOvl();
|
||||||
blz.Decompress(input, hdrptr - hdr.ARM9ramAddress, output);
|
blz.Decompress(input, hdrptr - hdr.ARM9ramAddress, output);
|
||||||
output.Write(arm9Data, arm9Data.Length - (int)postSize, (int)postSize);
|
output.Write(arm9Data, arm9Data.Length - (int)postSize, (int)postSize);
|
||||||
input.Close();
|
input.Close();
|
||||||
decompressed = output.ToArray();
|
decompressed = output.ToArray();
|
||||||
cmparm9 = false;
|
|
||||||
|
input.Close();
|
||||||
input.Close();
|
output.Close();
|
||||||
output.Close();
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return cmparm9;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Compress ARM9.bin
|
/// Compress ARM9.bin
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="arm9Data">Uncompressed ARM9.bin data</param>
|
/// <param name="arm9Data">Uncompressed ARM9.bin data</param>
|
||||||
/// <param name="hdr">ROM header</param>
|
/// <param name="hdr">ROM header</param>
|
||||||
/// <param name="postSize">Data size from the end what will be ignored.</param>
|
/// <param name="postSize">Data size from the end what will be ignored.</param>
|
||||||
/// <returns>Compressed data with uncompressed Secure Area (first 0x4000 bytes).</returns>
|
/// <param name="method">0 = BLZ; 1 = BLZ-Cue</param>
|
||||||
public static byte[] Compress(byte[] arm9Data, Estructuras.ROMHeader hdr, uint postSize = 0)
|
/// <returns>Compressed data with uncompressed Secure Area (first 0x4000 bytes).</returns>
|
||||||
{
|
public static byte[] Compress(byte[] arm9Data, Estructuras.ROMHeader hdr, uint postSize = 0, bool method = false)
|
||||||
Stream input = new MemoryStream(arm9Data);
|
{
|
||||||
input.Position = 0x4000;
|
Stream input = new MemoryStream(arm9Data);
|
||||||
MemoryStream output = new MemoryStream();
|
input.Position = 0x4000;
|
||||||
output.Write(arm9Data, 0, 0x4000);
|
MemoryStream output = new MemoryStream();
|
||||||
LZOvl blz = new LZOvl();
|
output.Write(arm9Data, 0, 0x4000);
|
||||||
blz.Compress(input, input.Length - 0x4000, output);
|
LZOvl blz = new LZOvl();
|
||||||
input.Close();
|
LZOvl.LookAhead = method;
|
||||||
output.Write(arm9Data, arm9Data.Length - (int)postSize, (int)postSize);
|
blz.Compress(input, input.Length - 0x4000, output);
|
||||||
byte[] result = output.ToArray();
|
input.Close();
|
||||||
output.Close();
|
output.Write(arm9Data, arm9Data.Length - (int)postSize, (int)postSize);
|
||||||
|
byte[] result = output.ToArray();
|
||||||
// Update size
|
output.Close();
|
||||||
uint initptr = BitConverter.ToUInt32(hdr.reserved2, 0) & 0x3FFF;
|
|
||||||
if (initptr > 0)
|
// Update size
|
||||||
{
|
uint initptr = BitConverter.ToUInt32(hdr.reserved2, 0) & 0x3FFF;
|
||||||
uint hdrptr = (uint)result.Length - postSize + hdr.ARM9ramAddress;
|
if (initptr > 0)
|
||||||
Array.Copy(BitConverter.GetBytes(hdrptr), 0, result, initptr + 0x14, 4);
|
{
|
||||||
}
|
uint hdrptr = (uint)result.Length - postSize + hdr.ARM9ramAddress;
|
||||||
|
Array.Copy(BitConverter.GetBytes(hdrptr), 0, result, initptr + 0x14, 4);
|
||||||
return result;
|
}
|
||||||
}
|
|
||||||
}
|
return result;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -425,6 +425,8 @@
|
|||||||
<S1C>Cancel</S1C>
|
<S1C>Cancel</S1C>
|
||||||
<S1E>Safe Trim</S1E>
|
<S1E>Safe Trim</S1E>
|
||||||
<S1F>Keep Original RSA SHA1 Signature</S1F>
|
<S1F>Keep Original RSA SHA1 Signature</S1F>
|
||||||
|
<S20>Recompress ARM9 binary (BLZ)</S20>
|
||||||
|
<S21>Better compress method (BLZ-Cue)</S21>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
<VisorHex>
|
<VisorHex>
|
||||||
<S00>File</S00>
|
<S00>File</S00>
|
||||||
|
@ -429,6 +429,8 @@
|
|||||||
<S1C>Cancelar</S1C>
|
<S1C>Cancelar</S1C>
|
||||||
<S1E>Safe Trim</S1E>
|
<S1E>Safe Trim</S1E>
|
||||||
<S1F>Keep Original RSA SHA1 Signature</S1F>
|
<S1F>Keep Original RSA SHA1 Signature</S1F>
|
||||||
|
<S20>Recompress ARM9 binary (BLZ)</S20>
|
||||||
|
<S21>Better compress method (BLZ-Cue)</S21>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
<VisorHex>
|
<VisorHex>
|
||||||
<S00>Archivo</S00>
|
<S00>Archivo</S00>
|
||||||
|
@ -425,6 +425,8 @@
|
|||||||
<S1C>Annuler</S1C>
|
<S1C>Annuler</S1C>
|
||||||
<S1E>Safe Trim</S1E>
|
<S1E>Safe Trim</S1E>
|
||||||
<S1F>Keep Original RSA SHA1 Signature</S1F>
|
<S1F>Keep Original RSA SHA1 Signature</S1F>
|
||||||
|
<S20>Recompress ARM9 binary (BLZ)</S20>
|
||||||
|
<S21>Better compress method (BLZ-Cue)</S21>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
<VisorHex>
|
<VisorHex>
|
||||||
<S00>Archive</S00>
|
<S00>Archive</S00>
|
||||||
|
@ -424,6 +424,8 @@
|
|||||||
<S1C>Cancella</S1C>
|
<S1C>Cancella</S1C>
|
||||||
<S1E>Safe Trim</S1E>
|
<S1E>Safe Trim</S1E>
|
||||||
<S1F>Keep Original RSA SHA1 Signature</S1F>
|
<S1F>Keep Original RSA SHA1 Signature</S1F>
|
||||||
|
<S20>Recompress ARM9 binary (BLZ)</S20>
|
||||||
|
<S21>Better compress method (BLZ-Cue)</S21>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
<VisorHex>
|
<VisorHex>
|
||||||
<S00>File</S00>
|
<S00>File</S00>
|
||||||
|
@ -422,6 +422,8 @@
|
|||||||
<S1C>取消</S1C>
|
<S1C>取消</S1C>
|
||||||
<S1E>安全裁剪</S1E>
|
<S1E>安全裁剪</S1E>
|
||||||
<S1F>保持原始的 RSA SHA1 签名</S1F>
|
<S1F>保持原始的 RSA SHA1 签名</S1F>
|
||||||
|
<S20>重压缩 ARM9 文件 (BLZ 算法)</S20>
|
||||||
|
<S21>更好的压缩率算法 (BLZ-Cue)</S21>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
<VisorHex>
|
<VisorHex>
|
||||||
<S00>文件</S00>
|
<S00>文件</S00>
|
||||||
|
@ -13,10 +13,12 @@ TinkeDSi 0.9.5 (Made by R-YaTian)
|
|||||||
* DSDecmp: Add and use CUE's BLZ_Encoder, clean old method
|
* DSDecmp: Add and use CUE's BLZ_Encoder, clean old method
|
||||||
* Add saveoptions window before saving rom (Allow keep original RSA signature, safe trim the rom)
|
* Add saveoptions window before saving rom (Allow keep original RSA signature, safe trim the rom)
|
||||||
* Allow opening .SRL .IDS .DSI .APP files
|
* Allow opening .SRL .IDS .DSI .APP files
|
||||||
* WIP: Improve ARM9BLZ compression logic
|
* Improve ARM9BLZ compression logic
|
||||||
* Add McDonalds Maker Code to Estructuras.makerCode
|
* Add McDonalds Maker Code to Estructuras.makerCode
|
||||||
* Image: Set gimp_error to default false, hope this will fix palette exporting for anything that's not GIMP
|
* Image: Set gimp_error to default false, hope this will fix palette exporting for anything that's not GIMP
|
||||||
* 3DModels: Update to OpenTK 3.3.3, fix bug on fullscreen btn
|
* 3DModels: Update to OpenTK 3.3.3, fix bug on fullscreen btn
|
||||||
|
* Improved SF Feather Plugin (By @mn1712trungson)
|
||||||
|
* Core: Improve Nitrocode check when saving rom
|
||||||
TODO: full i18n support (include plugins)
|
TODO: full i18n support (include plugins)
|
||||||
|
|
||||||
TinkeDSi 0.9.4
|
TinkeDSi 0.9.4
|
||||||
|
@ -41,7 +41,7 @@ REM Get compiler
|
|||||||
SET netver=v4.5
|
SET netver=v4.5
|
||||||
SET msbuild_path=%windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe
|
SET msbuild_path=%windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe
|
||||||
SET msbuild=%msbuild_path% /p:Configuration=%conf% /p:TargetFrameworkVersion=%netver%
|
SET msbuild=%msbuild_path% /p:Configuration=%conf% /p:TargetFrameworkVersion=%netver%
|
||||||
SET msbuild_plugin=%msbuild% /p:OutputPath="%build_dir%\Plugins\\"
|
SET msbuild_plugin=%msbuild% /p:OutputPath="%build_dir%\Plugins\\" /m
|
||||||
|
|
||||||
REM Compile program in standard directory, to allow plugins find Ekona
|
REM Compile program in standard directory, to allow plugins find Ekona
|
||||||
ECHO Compiling base library
|
ECHO Compiling base library
|
||||||
@ -49,7 +49,7 @@ ECHO Compiling base library
|
|||||||
|
|
||||||
REM Compiling program
|
REM Compiling program
|
||||||
echo Compiling Tinke
|
echo Compiling Tinke
|
||||||
%msbuild% /p:Platform=%plat% /p:OutputPath="%build_dir%\\" Tinke.sln > error.log || (TYPE error.log & EXIT /B 1)
|
%msbuild% /p:Platform=%plat% /p:OutputPath="%build_dir%\\" /m Tinke.sln > error.log || (TYPE error.log & EXIT /B 1)
|
||||||
|
|
||||||
REM Compiling format plugins
|
REM Compiling format plugins
|
||||||
call :compile_plugin "Plugins\Pack\Pack.sln"
|
call :compile_plugin "Plugins\Pack\Pack.sln"
|
||||||
|
Loading…
Reference in New Issue
Block a user