Globalized block encryption/decryption.

Only entralink forest can be decrypted for now until more encrypted data is found and added.
This commit is contained in:
suloku
2016-03-02 19:49:40 +01:00
parent f367b7f976
commit 24790b8056
6 changed files with 157 additions and 25 deletions

View File

@@ -19,6 +19,7 @@ namespace BW_tool
private System.Windows.Forms.Button dump_dec_but;
private System.Windows.Forms.Button inject_crypt_but;
private System.Windows.Forms.ComboBox selectedblock;
private System.Windows.Forms.CheckBox crypt_check;
/// <summary>
/// Disposes resources used by the form.
@@ -46,6 +47,7 @@ namespace BW_tool
this.dump_dec_but = new System.Windows.Forms.Button();
this.inject_crypt_but = new System.Windows.Forms.Button();
this.selectedblock = new System.Windows.Forms.ComboBox();
this.crypt_check = new System.Windows.Forms.CheckBox();
this.SuspendLayout();
//
// dump_but
@@ -70,6 +72,7 @@ namespace BW_tool
//
// dump_dec_but
//
this.dump_dec_but.Enabled = false;
this.dump_dec_but.Location = new System.Drawing.Point(204, 68);
this.dump_dec_but.Name = "dump_dec_but";
this.dump_dec_but.Size = new System.Drawing.Size(125, 23);
@@ -80,6 +83,7 @@ namespace BW_tool
//
// inject_crypt_but
//
this.inject_crypt_but.Enabled = false;
this.inject_crypt_but.Location = new System.Drawing.Point(353, 68);
this.inject_crypt_but.Name = "inject_crypt_but";
this.inject_crypt_but.Size = new System.Drawing.Size(125, 23);
@@ -173,12 +177,25 @@ namespace BW_tool
this.selectedblock.Name = "selectedblock";
this.selectedblock.Size = new System.Drawing.Size(692, 21);
this.selectedblock.TabIndex = 5;
this.selectedblock.SelectedIndexChanged += new System.EventHandler(this.SelectedblockSelectedIndexChanged);
//
// crypt_check
//
this.crypt_check.AutoCheck = false;
this.crypt_check.Location = new System.Drawing.Point(12, 38);
this.crypt_check.Name = "crypt_check";
this.crypt_check.Size = new System.Drawing.Size(104, 24);
this.crypt_check.TabIndex = 6;
this.crypt_check.Text = "Encripted";
this.crypt_check.UseVisualStyleBackColor = true;
this.crypt_check.CheckedChanged += new System.EventHandler(this.Crypt_checkCheckedChanged);
//
// Dumper
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(716, 103);
this.Controls.Add(this.crypt_check);
this.Controls.Add(this.selectedblock);
this.Controls.Add(this.inject_crypt_but);
this.Controls.Add(this.dump_dec_but);

View File

@@ -82,5 +82,25 @@ namespace BW_tool
MainForm.save.setBlockCrypt( injectfile, (int)selectedblock.SelectedIndex);
//MessageBox.Show(injectfile.Length.ToString());
}
void Crypt_checkCheckedChanged(object sender, EventArgs e)
{
if (MainForm.save.blocks[selectedblock.SelectedIndex].encrypted)
{
dump_dec_but.Enabled = true;
inject_crypt_but.Enabled = true;
}
else
{
dump_dec_but.Enabled = false;
inject_crypt_but.Enabled = false;
}
}
void SelectedblockSelectedIndexChanged(object sender, EventArgs e)
{
if (MainForm.save.blocks[selectedblock.SelectedIndex].encrypted)
crypt_check.Checked = true;
else
crypt_check.Checked = false;
}
}
}

View File

@@ -20,6 +20,7 @@ namespace BW_tool
private System.Windows.Forms.Label versiontext;
private System.Windows.Forms.Button dumper_but;
private System.Windows.Forms.Button chk_but;
private System.Windows.Forms.Button chk_updt_but;
/// <summary>
/// Disposes resources used by the form.
@@ -48,6 +49,7 @@ namespace BW_tool
this.versiontext = new System.Windows.Forms.Label();
this.dumper_but = new System.Windows.Forms.Button();
this.chk_but = new System.Windows.Forms.Button();
this.chk_updt_but = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// loadsave_but
@@ -66,10 +68,12 @@ namespace BW_tool
this.savegamename.Name = "savegamename";
this.savegamename.Size = new System.Drawing.Size(484, 20);
this.savegamename.TabIndex = 1;
this.savegamename.TextChanged += new System.EventHandler(this.SavegamenameTextChanged);
//
// save_but
//
this.save_but.Location = new System.Drawing.Point(421, 12);
this.save_but.Enabled = false;
this.save_but.Location = new System.Drawing.Point(421, 67);
this.save_but.Name = "save_but";
this.save_but.Size = new System.Drawing.Size(75, 23);
this.save_but.TabIndex = 2;
@@ -86,6 +90,7 @@ namespace BW_tool
//
// dumper_but
//
this.dumper_but.Enabled = false;
this.dumper_but.Location = new System.Drawing.Point(12, 80);
this.dumper_but.Name = "dumper_but";
this.dumper_but.Size = new System.Drawing.Size(92, 23);
@@ -96,7 +101,8 @@ namespace BW_tool
//
// chk_but
//
this.chk_but.Location = new System.Drawing.Point(316, 12);
this.chk_but.Enabled = false;
this.chk_but.Location = new System.Drawing.Point(274, 12);
this.chk_but.Name = "chk_but";
this.chk_but.Size = new System.Drawing.Size(99, 23);
this.chk_but.TabIndex = 5;
@@ -104,11 +110,23 @@ namespace BW_tool
this.chk_but.UseVisualStyleBackColor = true;
this.chk_but.Click += new System.EventHandler(this.Chk_butClick);
//
// chk_updt_but
//
this.chk_updt_but.Enabled = false;
this.chk_updt_but.Location = new System.Drawing.Point(379, 12);
this.chk_updt_but.Name = "chk_updt_but";
this.chk_updt_but.Size = new System.Drawing.Size(117, 23);
this.chk_updt_but.TabIndex = 6;
this.chk_updt_but.Text = "Update Checksums";
this.chk_updt_but.UseVisualStyleBackColor = true;
this.chk_updt_but.Click += new System.EventHandler(this.Chk_updt_butClick);
//
// MainForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(503, 119);
this.Controls.Add(this.chk_updt_but);
this.Controls.Add(this.chk_but);
this.Controls.Add(this.dumper_but);
this.Controls.Add(this.versiontext);

View File

@@ -64,11 +64,32 @@ namespace BW_tool
void Dumper_butClick(object sender, EventArgs e)
{
Form dumper = new Dumper();
dumper.Show();
dumper.ShowDialog();
}
void Chk_butClick(object sender, EventArgs e)
{
save.chkCheck();
save.chkCheck(false); //Only verify
}
void Chk_updt_butClick(object sender, EventArgs e)
{
save.chkCheck(true); //Recalculate checksums and set them to savefile
}
void SavegamenameTextChanged(object sender, EventArgs e)
{
if (savegamename.Text != "")
{
dumper_but.Enabled = true;
chk_but.Enabled = true;
chk_updt_but.Enabled = true;
save_but.Enabled = true;
}
else
{
dumper_but.Enabled = false;
chk_but.Enabled = false;
chk_updt_but.Enabled = false;
save_but.Enabled = false;
}
}
}
}

View File

@@ -62,7 +62,7 @@ namespace BW_tool
UInt32 seed = pv;
UInt16 tmp;
for (Int32 i = start_offset; i < length-4; i += 0x2)
for (Int32 i = start_offset; i < length; i += 0x2)
{
tmp = BitConverter.ToUInt16(buffer_dec, i);

View File

@@ -16,6 +16,12 @@ using System.IO;
namespace BW_tool
{
public class Crypto
{
public int start;
public int length;
public int seed;
}
public class BlockInfo
{
public int Offset;
@@ -24,7 +30,7 @@ namespace BW_tool
public int updtcnt;
public int Checksum;
public bool encrypted;
public int seed;
public Crypto crypto;
}
public class SAV5 : PKX5
{
@@ -93,6 +99,7 @@ namespace BW_tool
for (i=0;i<74;i++)
{
blocks[i] = new BlockInfo();
blocks[i].crypto = new Crypto();
blocks[i].Offset=BlockTableBW2[i];
blocks[i].Length=BlockTableLengthBW2[i];
blocks[i].ID= i;
@@ -105,10 +112,18 @@ namespace BW_tool
{
blocks[i].Checksum=0x25FA2;
}
blocks[i].encrypted=false;
blocks[i].seed=blocks[i].Offset+blocks[i].Length-4;
switch (i)
{
case 60: //Entralink forest
blocks[i].encrypted=true;
blocks[i].crypto.start = 0x00;
blocks[i].crypto.length = 0x84C;
blocks[i].crypto.seed = 0x84C;
break;
default:
blocks[i].encrypted=false;
break;
}
}
// Different Offsets for different games.
@@ -153,7 +168,7 @@ namespace BW_tool
{
//MessageBox.Show(decrypt.Length.ToString());
//MessageBox.Show((blocks[index].Length-4).ToString());
decrypt = PKX5.cryptoArray(Data.Skip(blocks[index].Offset).Take(blocks[index+1].Offset-blocks[index].Offset).ToArray(), 0, blocks[index].Length, blocks[index].Length-4);
decrypt = PKX5.cryptoArray(Data.Skip(blocks[index].Offset).Take(blocks[index+1].Offset-blocks[index].Offset).ToArray(), blocks[index].crypto.start, blocks[index].crypto.length, blocks[index].crypto.seed);
//MessageBox.Show((blocks[index].Length-4).ToString());
return decrypt;
}
@@ -221,21 +236,23 @@ namespace BW_tool
{
if (index <74)
{
//Encrypt
byte[] encrypt = new byte[getBlockLength(index)];
encrypt = PKX5.cryptoArray(input, blocks[index].crypto.start, blocks[index].crypto.length, blocks[index].crypto.seed);
//Recalculate checksum before applying to savedata
ushort crc = ccitt16(input.Take(blocks[index].Length).ToArray());
if (crc != BitConverter.ToUInt16(input, blocks[index].Checksum-blocks[index].Offset) )
ushort crc = ccitt16(encrypt.Take(blocks[index].Length).ToArray());
if (crc != BitConverter.ToUInt16(encrypt, blocks[index].Checksum-blocks[index].Offset) )
{
Array.Copy(BitConverter.GetBytes(crc), 0, input, blocks[index].Checksum-blocks[index].Offset, 2);
Array.Copy(BitConverter.GetBytes(crc), 0, encrypt, blocks[index].Checksum-blocks[index].Offset, 2);
MessageBox.Show("Block's checksum updated");
}else
{
MessageBox.Show("Checksum doesn't need update");
}
input.CopyTo(Data, blocks[index].Offset);
input.CopyTo(Data, blocks[index].Offset+SIZE2);
encrypt.CopyTo(Data, blocks[index].Offset);
encrypt.CopyTo(Data, blocks[index].Offset+SIZE2);
Edited = true;
}
else return;
@@ -247,12 +264,15 @@ namespace BW_tool
input.CopyTo(Data, Offset);
Edited = true;
}
public void chkCheck()
public void chkCheck(bool correct)
{
int i = 0;
string badblocks;
badblocks = "Found bad checksums in MAIN save at blocks: ";
string correctedblocks;
correctedblocks = "Corrected checksums in MAIN save at blocks: ";
bool badcheck = false;
bool firstcorrect = false;
if (B2W2)
{
//Main save checksums
@@ -261,8 +281,20 @@ namespace BW_tool
ushort crc = ccitt16(Data.Skip(blocks[i].Offset).Take(blocks[i].Length).ToArray());
if ( crc != BitConverter.ToUInt16(Data, blocks[i].Checksum) )
{
//Array.Copy(BitConverter.GetBytes(crc), 0, input, blocks[index].Checksum-blocks[index].Offset, 2);
//MessageBox.Show("Block's checksum is wrong " + i.ToString());
if (correct)
{
Array.Copy(BitConverter.GetBytes(crc), 0, Data, blocks[i].Checksum, 2);
if (!firstcorrect)
{
firstcorrect = true;
correctedblocks = correctedblocks + i.ToString();
}else
{
correctedblocks = correctedblocks + ", " + i.ToString();
}
Edited = true;
}
//Build bad checksum message
if (!badcheck)
{
badcheck = true;
@@ -279,20 +311,39 @@ namespace BW_tool
}
if(badcheck)
MessageBox.Show(badblocks);
{
if (correct)
MessageBox.Show(correctedblocks);
else
MessageBox.Show(badblocks);
}
else
MessageBox.Show("All 74 checksums OK in MAIN save");
//Backup save checksums
badcheck = false;
badblocks = "Found bad checksums in BACKUP save at blocks: ";
firstcorrect = false;
correctedblocks = "Corrected checksums in BACKUP save at blocks: ";
for(i=0; i<74; i++)
{
ushort crc = ccitt16(Data.Skip(blocks[i].Offset+SIZE2).Take(blocks[i].Length).ToArray());
if ( crc != BitConverter.ToUInt16(Data, blocks[i].Checksum+SIZE2) )
{
//Array.Copy(BitConverter.GetBytes(crc), 0, input, blocks[index].Checksum-blocks[index].Offset, 2);
//MessageBox.Show("Block's checksum is wrong " + i.ToString());
if (correct)
{
Array.Copy(BitConverter.GetBytes(crc), 0, Data, blocks[i].Checksum+SIZE2, 2);
if (!firstcorrect)
{
firstcorrect = true;
correctedblocks = correctedblocks + i.ToString();
}else
{
correctedblocks = correctedblocks + ", " + i.ToString();
}
Edited = true;
}
//Build bad checksum message
if (!badcheck)
{
badcheck = true;
@@ -309,7 +360,12 @@ namespace BW_tool
}
if(badcheck)
MessageBox.Show(badblocks);
{
if (correct)
MessageBox.Show(correctedblocks);
else
MessageBox.Show(badblocks);
}
else
MessageBox.Show("All 74 checksums OK in BACKUP save");