From 6c48af34346dd494d26feabeb011c04a121359d2 Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Sat, 7 Jun 2014 23:43:20 +0200 Subject: [PATCH] Fix checksums for devices that care about that. --- Crc16.cs | 51 +++++++++++++++++++++++++++++++++++++++++++++++ Program.cs | 10 ++++++++++ WfcPatcher.csproj | 1 + 3 files changed, 62 insertions(+) create mode 100644 Crc16.cs diff --git a/Crc16.cs b/Crc16.cs new file mode 100644 index 0000000..8c35edd --- /dev/null +++ b/Crc16.cs @@ -0,0 +1,51 @@ +// modified from http://www.sanity-free.org/134/standard_crc_16_in_csharp.html + +using System; +using System.IO; + +namespace WfcPatcher { + public class Crc16 { + private ushort[] table = new ushort[256]; + + public ushort ComputeChecksum( byte[] bytes ) { + ushort crc = 0; + for ( int i = 0; i < bytes.Length; ++i ) { + byte index = (byte)( crc ^ bytes[i] ); + crc = (ushort)( ( crc >> 8 ) ^ table[index] ); + } + return crc; + } + + public ushort ComputeChecksum( Stream stream, int length, ushort init = 0 ) { + ushort crc = init; + for ( int i = 0; i < length; ++i ) { + byte index = (byte)( ( crc ^ stream.ReadByte() ) & 0xFF ); + crc = (ushort)( ( crc >> 8 ) ^ table[index] ); + } + return crc; + } + + public byte[] ComputeChecksumBytes( byte[] bytes ) { + ushort crc = ComputeChecksum( bytes ); + return BitConverter.GetBytes( crc ); + } + + public Crc16( ushort polynomial = 0xA001 ) { + ushort value; + ushort temp; + for ( ushort i = 0; i < table.Length; ++i ) { + value = 0; + temp = i; + for ( byte j = 0; j < 8; ++j ) { + if ( ( ( value ^ temp ) & 0x0001 ) != 0 ) { + value = (ushort)( ( value >> 1 ) ^ polynomial ); + } else { + value >>= 1; + } + temp >>= 1; + } + table[i] = value; + } + } + } +} diff --git a/Program.cs b/Program.cs index fc24a5e..13c4dcf 100644 --- a/Program.cs +++ b/Program.cs @@ -177,6 +177,16 @@ static void PatchArm9( System.IO.FileStream nds, uint pos, uint len ) { byte[] newSizeBytes = BitConverter.GetBytes( newSize ); nds.Position = 0x2C; nds.Write( newSizeBytes, 0, 4 ); + + // recalculate checksums + nds.Position = pos; + ushort secureChecksum = new Crc16().ComputeChecksum( nds, 0x4000, 0xFFFF ); + nds.Position = 0x6C; + nds.Write( BitConverter.GetBytes( secureChecksum ), 0, 2 ); + + nds.Position = 0; + ushort headerChecksum = new Crc16().ComputeChecksum( nds, 0x15E, 0xFFFF ); + nds.Write( BitConverter.GetBytes( headerChecksum ), 0, 2 ); } } diff --git a/WfcPatcher.csproj b/WfcPatcher.csproj index f2217aa..ab4cfa2 100644 --- a/WfcPatcher.csproj +++ b/WfcPatcher.csproj @@ -43,6 +43,7 @@ +