mirror of
https://github.com/mm201/pkmn-classic-framework.git
synced 2026-04-25 16:20:08 -05:00
Initial attempt at decoding Wi-fi Plaza gamestats blobs
This commit is contained in:
parent
1d931ff91b
commit
1eab40f4a1
|
|
@ -89,6 +89,7 @@
|
|||
<Compile Include="BattleVideo.aspx.designer.cs">
|
||||
<DependentUpon>BattleVideo.aspx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="src\GamestatsSessionPlat.cs" />
|
||||
<Compile Include="src\HeaderColour.cs" />
|
||||
<Compile Include="test\BoxUp.aspx.cs">
|
||||
<DependentUpon>BoxUp.aspx</DependentUpon>
|
||||
|
|
|
|||
68
gts/src/GamestatsSessionPlat.cs
Normal file
68
gts/src/GamestatsSessionPlat.cs
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using System.Security.Cryptography;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
|
||||
namespace PkmnFoundations.GTS
|
||||
{
|
||||
public class GamestatsSessionPlat : GtsSessionBase
|
||||
{
|
||||
public GamestatsSessionPlat(int pid, String url)
|
||||
: base(pid, url)
|
||||
{
|
||||
Hash = ComputeHash(Token);
|
||||
}
|
||||
|
||||
public static String ComputeHash(String token)
|
||||
{
|
||||
// todo: add unit tests with some wiresharked examples.
|
||||
|
||||
if (m_sha1 == null) m_sha1 = SHA1.Create();
|
||||
|
||||
String longToken = "uLMOGEiiJogofchScpXb" + token;
|
||||
|
||||
byte[] data = new byte[longToken.Length];
|
||||
MemoryStream stream = new MemoryStream(data);
|
||||
StreamWriter writer = new StreamWriter(stream);
|
||||
writer.Write(longToken); // fixme: this throws an OutOfBoundsException if the passed token contains non-ascii.
|
||||
writer.Flush();
|
||||
|
||||
return m_sha1.ComputeHash(data).ToHexStringLower();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Decrypts the NDS &data= querystring into readable binary data.
|
||||
/// The PID (little endian) is left at the start of the output
|
||||
/// but the (unencrypted) checksum is removed.
|
||||
/// </summary>
|
||||
public static byte[] DecryptData(String data)
|
||||
{
|
||||
byte[] data2 = FromUrlSafeBase64String(data);
|
||||
if (data2.Length < 4) throw new FormatException("Data must contain at least 4 bytes.");
|
||||
|
||||
byte[] data3 = new byte[data2.Length - 4];
|
||||
int checksum = BitConverter.ToInt32(data2, 0);
|
||||
checksum = IPAddress.NetworkToHostOrder(checksum); // endian flip
|
||||
checksum ^= 0x5b440000;
|
||||
int rand = checksum | (checksum << 16);
|
||||
|
||||
// todo: prune first 8 bytes, pass pid to this function to validate
|
||||
for (int pos = 0; pos < data3.Length; pos++)
|
||||
{
|
||||
rand = DecryptRNG(rand);
|
||||
data3[pos] = (byte)(data2[pos + 4] ^ (byte)(rand >> 16));
|
||||
}
|
||||
|
||||
int checkedsum = 0;
|
||||
foreach (byte b in data3)
|
||||
checkedsum += b;
|
||||
|
||||
if (checkedsum != checksum) throw new FormatException("Data checksum is incorrect.");
|
||||
|
||||
return data3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -17,6 +17,11 @@
|
|||
<div class="code">
|
||||
<asp:Literal ID="litDecoded" runat="server" />
|
||||
</div>
|
||||
<asp:PlaceHolder ID="phChecksum" Visible="false" runat="server">
|
||||
<p>
|
||||
Checksum: <asp:Literal ID="litChecksum" runat="server" />
|
||||
</p>
|
||||
</asp:PlaceHolder>
|
||||
</div>
|
||||
</asp:PlaceHolder>
|
||||
</form>
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ using System.Web;
|
|||
using System.Web.UI;
|
||||
using System.Web.UI.WebControls;
|
||||
using System.Text;
|
||||
using System.Net;
|
||||
|
||||
namespace PkmnFoundations.GTS.debug
|
||||
{
|
||||
|
|
@ -13,12 +14,14 @@ namespace PkmnFoundations.GTS.debug
|
|||
protected void Page_Load(object sender, EventArgs e)
|
||||
{
|
||||
litMessage.Text = "";
|
||||
litChecksum.Text = "";
|
||||
}
|
||||
|
||||
protected void btnDecode_Click(object sender, EventArgs e)
|
||||
{
|
||||
byte[] data = null;
|
||||
phDecoded.Visible = false;
|
||||
phChecksum.Visible = false;
|
||||
|
||||
try
|
||||
{
|
||||
|
|
@ -38,16 +41,49 @@ namespace PkmnFoundations.GTS.debug
|
|||
{
|
||||
}
|
||||
|
||||
if (data == null) try
|
||||
{
|
||||
data = GamestatsSessionPlat.DecryptData(txtData.Text);
|
||||
litGeneration.Text = "Platinum";
|
||||
}
|
||||
catch (FormatException)
|
||||
{
|
||||
}
|
||||
|
||||
if (data == null)
|
||||
{
|
||||
data = DecryptData(txtData.Text);
|
||||
|
||||
int checkedsum = 0;
|
||||
foreach (byte b in data)
|
||||
checkedsum += b;
|
||||
|
||||
litGeneration.Text = "";
|
||||
litChecksum.Text = checkedsum.ToString();
|
||||
phChecksum.Visible = true;
|
||||
}
|
||||
|
||||
if (data == null)
|
||||
{
|
||||
litMessage.Text = "<p class=\"errorMessage\">Data is not formatted correctly.</p>";
|
||||
return;
|
||||
}
|
||||
|
||||
litDecoded.Text = RenderHex(data.ToHexStringLower());
|
||||
phDecoded.Visible = true;
|
||||
}
|
||||
|
||||
public static byte[] DecryptData(String data)
|
||||
{
|
||||
byte[] data2 = GtsSessionBase.FromUrlSafeBase64String(data);
|
||||
if (data2.Length < 12) throw new FormatException("Data must contain at least 12 bytes.");
|
||||
|
||||
int checksum = BitConverter.ToInt32(data2, 0);
|
||||
checksum = IPAddress.NetworkToHostOrder(checksum); // endian flip
|
||||
//checksum ^= 0x2db842b2;
|
||||
|
||||
return data2;
|
||||
}
|
||||
|
||||
private String RenderHex(String hex)
|
||||
{
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
|
|
|||
18
gts/test/Decode.aspx.designer.cs
generated
18
gts/test/Decode.aspx.designer.cs
generated
|
|
@ -74,5 +74,23 @@ namespace PkmnFoundations.GTS.debug {
|
|||
/// To modify move field declaration from designer file to code-behind file.
|
||||
/// </remarks>
|
||||
protected global::System.Web.UI.WebControls.Literal litDecoded;
|
||||
|
||||
/// <summary>
|
||||
/// phChecksum control.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Auto-generated field.
|
||||
/// To modify move field declaration from designer file to code-behind file.
|
||||
/// </remarks>
|
||||
protected global::System.Web.UI.WebControls.PlaceHolder phChecksum;
|
||||
|
||||
/// <summary>
|
||||
/// litChecksum control.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Auto-generated field.
|
||||
/// To modify move field declaration from designer file to code-behind file.
|
||||
/// </remarks>
|
||||
protected global::System.Web.UI.WebControls.Literal litChecksum;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user