mirror of
https://github.com/suloku/BW_efd_tool.git
synced 2026-09-08 18:35:18 -05:00
Can dump decrypted forest block.
This commit is contained in:
16
BW Entralink Forest tool/MainForm.Designer.cs
generated
16
BW Entralink Forest tool/MainForm.Designer.cs
generated
@@ -18,6 +18,7 @@ partial class MainForm
|
||||
private System.Windows.Forms.TextBox savegamename;
|
||||
private System.Windows.Forms.Button dump_but;
|
||||
private System.Windows.Forms.Button inject_but;
|
||||
private System.Windows.Forms.Button dump_dec_but;
|
||||
|
||||
/// <summary>
|
||||
/// Disposes resources used by the form.
|
||||
@@ -44,6 +45,7 @@ private void InitializeComponent()
|
||||
this.savegamename = new System.Windows.Forms.TextBox();
|
||||
this.dump_but = new System.Windows.Forms.Button();
|
||||
this.inject_but = new System.Windows.Forms.Button();
|
||||
this.dump_dec_but = new System.Windows.Forms.Button();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// loadsave
|
||||
@@ -86,11 +88,23 @@ private void InitializeComponent()
|
||||
this.inject_but.UseVisualStyleBackColor = true;
|
||||
this.inject_but.Click += new System.EventHandler(this.Inject_butClick);
|
||||
//
|
||||
// dump_dec_but
|
||||
//
|
||||
this.dump_dec_but.Enabled = false;
|
||||
this.dump_dec_but.Location = new System.Drawing.Point(13, 97);
|
||||
this.dump_dec_but.Name = "dump_dec_but";
|
||||
this.dump_dec_but.Size = new System.Drawing.Size(161, 36);
|
||||
this.dump_dec_but.TabIndex = 5;
|
||||
this.dump_dec_but.Text = "Dump Entralink Forest Data (decrypted)";
|
||||
this.dump_dec_but.UseVisualStyleBackColor = true;
|
||||
this.dump_dec_but.Click += new System.EventHandler(this.Dump_dec_butClick);
|
||||
//
|
||||
// MainForm
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(354, 95);
|
||||
this.ClientSize = new System.Drawing.Size(354, 136);
|
||||
this.Controls.Add(this.dump_dec_but);
|
||||
this.Controls.Add(this.savegamename);
|
||||
this.Controls.Add(this.dump_but);
|
||||
this.Controls.Add(this.loadsave);
|
||||
|
||||
@@ -16,6 +16,23 @@
|
||||
using System.Windows.Forms;
|
||||
using System.IO;
|
||||
|
||||
/*
|
||||
Kaphotics info about forest data:
|
||||
|
||||
0x850 bytes of data
|
||||
u16 update counter
|
||||
u16 checksum
|
||||
|
||||
checksum: crc-ccitt (16 bit) over the 0x850 range
|
||||
encryption seed: last 4 bytes of the 0x850 bytes (the only thing that isn't encrypted!)
|
||||
encryption method: 32bit lcrng, same used for Pokemon encryption, xor (result >> 16).
|
||||
|
||||
The internal structure should be pretty easy to figure out if you just compare it to PokeStock's display. Something like u16 Species, u16 Move.
|
||||
A species' level is static, determined by a table stored in the ROM (NARC file) afaik.
|
||||
|
||||
The one save file I checked had it at 0x22A00, must have been B2W2 (not BW).
|
||||
|
||||
*/
|
||||
|
||||
namespace BW_Entralink_Forest_tool
|
||||
{
|
||||
@@ -38,6 +55,7 @@ public MainForm()
|
||||
string forestfile;
|
||||
byte[] savebuffer = new byte[524288];
|
||||
byte[] forestbuffer = new byte[2304];
|
||||
byte[] forestbuffer_dec = new byte[2304];
|
||||
|
||||
//adapted from Gocario's PHBank (www.github.com/gocario/phbank)
|
||||
byte[] ccitt16(byte[] data)
|
||||
@@ -61,6 +79,33 @@ byte[] ccitt16(byte[] data)
|
||||
|
||||
return BitConverter.GetBytes(crc);
|
||||
}
|
||||
UInt32 LCRNG(UInt32 seed)
|
||||
// --------------------------------------------------
|
||||
{
|
||||
UInt32 a = 0x41c64e6d;
|
||||
UInt32 c = 0x00006073;
|
||||
return (UInt32)(((UInt64)seed * (UInt64)a + (UInt64)c)&0x00000000FFFFFFFF);
|
||||
}
|
||||
void decryptForest()
|
||||
// --------------------------------------------------
|
||||
{
|
||||
Array.Copy(forestbuffer, forestbuffer_dec, 2304);
|
||||
|
||||
UInt32 pv = BitConverter.ToUInt32(forestbuffer_dec, 0x84C);
|
||||
byte sv = (byte)((((pv & 0x3e000) >> 0xd) % 24)&0x000000FF);
|
||||
|
||||
UInt32 seed = pv;
|
||||
UInt16 tmp;
|
||||
|
||||
for (Int32 i = 0x0; i < 0x850; i += 0x2)
|
||||
{
|
||||
tmp = BitConverter.ToUInt16(forestbuffer_dec, i);
|
||||
|
||||
seed = LCRNG(seed);
|
||||
tmp ^= (UInt16)((seed >> 16)&0x0000FFFF);
|
||||
Array.Copy(BitConverter.GetBytes(tmp), 0, forestbuffer_dec, i, 2);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads data into a complete array, throwing an EndOfStreamException
|
||||
@@ -124,6 +169,20 @@ private void PDR_save_data()
|
||||
saveFile.Write(savebuffer, 0, savebuffer.Length);
|
||||
saveFile.Close();
|
||||
MessageBox.Show("File Saved.", "Save file");
|
||||
}
|
||||
}
|
||||
private void PDR_save_decforest_data()
|
||||
{ SaveFileDialog saveFD = new SaveFileDialog();
|
||||
//saveFD.InitialDirectory = "c:\\";
|
||||
saveFD.Filter = "Entralink Forest Decrypted Data|*.efdd|All Files (*.*)|*.*";
|
||||
if (saveFD.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
System.IO.FileStream saveFile;
|
||||
saveFile = new FileStream(saveFD.FileName, FileMode.Create);
|
||||
//Write file
|
||||
saveFile.Write(forestbuffer_dec, 0, forestbuffer_dec.Length);
|
||||
saveFile.Close();
|
||||
MessageBox.Show("File Saved.", "Save file");
|
||||
}
|
||||
}
|
||||
private void PDR_dump_forest_data()
|
||||
@@ -141,19 +200,6 @@ private void PDR_dump_forest_data()
|
||||
MessageBox.Show("Entralink forest data dumped to:\r"+saveFD.FileName+".", "Dump Entralink Forest Data");
|
||||
}
|
||||
}
|
||||
private void PDR_read_forest_data()
|
||||
{
|
||||
System.IO.FileStream saveFile;
|
||||
saveFile = new FileStream(forestfile, FileMode.Open);
|
||||
if (saveFile.Length != 0x900){
|
||||
//forestfile = "";
|
||||
MessageBox.Show("Invalid file length", "Error");
|
||||
return;
|
||||
}
|
||||
ReadWholeArray(saveFile, forestbuffer);
|
||||
saveFile.Close();
|
||||
PDR_injectNsave();
|
||||
}
|
||||
private void PDR_get_forest_data()
|
||||
{
|
||||
OpenFileDialog openFD = new OpenFileDialog();
|
||||
@@ -168,6 +214,18 @@ private void PDR_get_forest_data()
|
||||
}
|
||||
|
||||
}
|
||||
private void PDR_read_forest_data()
|
||||
{
|
||||
System.IO.FileStream forestFile;
|
||||
forestFile = new FileStream(forestfile, FileMode.Open);
|
||||
if (forestFile.Length != 0x900){
|
||||
//forestfile = "";
|
||||
MessageBox.Show("Invalid file length", "Error");
|
||||
return;
|
||||
}
|
||||
ReadWholeArray(forestFile, forestbuffer);
|
||||
forestFile.Close();
|
||||
}
|
||||
private void PDR_injectNsave()
|
||||
{
|
||||
//Put new forest in both save file slots
|
||||
@@ -213,9 +271,11 @@ void SavegamenameTextChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (savegamename.Text.Length > 0){
|
||||
dump_but.Enabled = true;
|
||||
dump_dec_but.Enabled = true;
|
||||
inject_but.Enabled = true;
|
||||
}else{
|
||||
dump_but.Enabled = false;
|
||||
dump_dec_but.Enabled = false;
|
||||
inject_but.Enabled = false;
|
||||
}
|
||||
|
||||
@@ -223,6 +283,14 @@ void SavegamenameTextChanged(object sender, EventArgs e)
|
||||
void Inject_butClick(object sender, EventArgs e)
|
||||
{
|
||||
PDR_get_forest_data();
|
||||
PDR_injectNsave();
|
||||
}
|
||||
void Dump_dec_butClick(object sender, EventArgs e)
|
||||
{
|
||||
//Copy forest to buffer
|
||||
Array.Copy(savebuffer, 0x22C00, forestbuffer, 0, 0x900);
|
||||
decryptForest();
|
||||
PDR_save_decforest_data();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user