mirror of
https://github.com/Gericom/dspatch.git
synced 2025-06-19 01:15:42 -04:00
Multiple Rom Support
This commit is contained in:
parent
4b3548b6ab
commit
32856c4b68
@ -14,7 +14,7 @@ namespace dspatch.DS
|
||||
{
|
||||
MemoryStream m = new MemoryStream();
|
||||
EndianBinaryWriter er = new EndianBinaryWriter(m);
|
||||
er.Write((byte)entries.Length);
|
||||
er.Write((byte)entries.Count);
|
||||
er.Write((byte)0);
|
||||
er.Write((byte)0);
|
||||
er.Write((byte)0);
|
||||
@ -25,7 +25,7 @@ namespace dspatch.DS
|
||||
er.Close();
|
||||
return result;
|
||||
}
|
||||
public DemoMenuEntry[] entries;
|
||||
public List<DemoMenuEntry> entries = new List<DemoMenuEntry>();
|
||||
public class DemoMenuEntry
|
||||
{
|
||||
private string createString(string text, int length, bool nullTerminated = true)
|
||||
|
278
dspatch/DownloadStationPatcher.cs
Normal file
278
dspatch/DownloadStationPatcher.cs
Normal file
@ -0,0 +1,278 @@
|
||||
using dspatch.DS;
|
||||
using dspatch.IO;
|
||||
using dspatch.Nitro;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace dspatch
|
||||
{
|
||||
public class DownloadStationPatcher
|
||||
{
|
||||
private static byte[] haxxStationIconImage =
|
||||
{
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x90, 0x61, 0x66, 0x66, 0x69, 0x66, 0x66, 0x66, 0x61, 0xC8, 0xCC, 0xCC,
|
||||
0x66, 0xCC, 0xCC, 0x6C, 0x66, 0xCC, 0xCC, 0x6C, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66,
|
||||
0x66, 0x66, 0x66, 0x66, 0xCC, 0xCC, 0xCC, 0xCC, 0x66, 0x66, 0x66, 0x66,
|
||||
0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x16, 0x09, 0x66, 0x66, 0x66, 0x96,
|
||||
0xCC, 0xCC, 0x8C, 0x16, 0xC6, 0xCC, 0xCC, 0x66, 0xC6, 0xCC, 0xCC, 0x66,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0xCC, 0xCC, 0x6C,
|
||||
0x66, 0xCC, 0xCC, 0x6C, 0x66, 0xCC, 0xCC, 0x6C, 0x66, 0xCC, 0xCC, 0x6C,
|
||||
0x66, 0xCC, 0xCC, 0x6C, 0x66, 0x8C, 0xCC, 0x6C, 0x45, 0x65, 0x41, 0x85,
|
||||
0x89, 0xE2, 0xC0, 0x27, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
0x66, 0x66, 0x66, 0x66, 0x27, 0x16, 0x54, 0xB7, 0xD5, 0xE0, 0x9D, 0x14,
|
||||
0xC6, 0xCC, 0xCC, 0x66, 0xC6, 0xCC, 0xCC, 0x66, 0xC6, 0xCC, 0xCC, 0x66,
|
||||
0xC6, 0xCC, 0xCC, 0x66, 0xC6, 0xCC, 0xCC, 0x66, 0xC6, 0x99, 0xCC, 0x66,
|
||||
0x5C, 0x11, 0xC5, 0x66, 0x42, 0xEE, 0x24, 0x44, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x20, 0x0E, 0x00,
|
||||
0x00, 0x79, 0x00, 0x0B, 0x00, 0x01, 0x70, 0x08, 0xD0, 0x04, 0x2E, 0x00,
|
||||
0xB0, 0x07, 0x5D, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD9, 0x00, 0x77, 0x0C,
|
||||
0x24, 0x87, 0x52, 0x14, 0x66, 0x14, 0xC9, 0x6C, 0x66, 0xAC, 0xCC, 0x6C,
|
||||
0x66, 0xCC, 0xC1, 0x6C, 0x66, 0x1C, 0x16, 0x6C, 0x66, 0xCC, 0xC1, 0x6C,
|
||||
0x00, 0x00, 0x00, 0x00, 0x80, 0x21, 0xA7, 0x00, 0x41, 0x88, 0x47, 0x41,
|
||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xF3, 0x63, 0x66, 0x66,
|
||||
0x36, 0x3F, 0x66, 0x66, 0x36, 0x3F, 0x66, 0x66, 0x0D, 0x00, 0xD0, 0x99,
|
||||
0x00, 0x88, 0x00, 0x00, 0x18, 0x44, 0x81, 0x99, 0x76, 0xCC, 0x57, 0x44,
|
||||
0xC6, 0xCC, 0xCC, 0x66, 0xC6, 0x6C, 0xCC, 0x66, 0xC6, 0xC6, 0xC6, 0x66,
|
||||
0xC6, 0x6C, 0xCC, 0x66, 0x90, 0x09, 0x89, 0x00, 0xB0, 0x07, 0x4D, 0x00,
|
||||
0xD0, 0x04, 0x10, 0x00, 0x00, 0x01, 0x80, 0x05, 0x00, 0x78, 0x00, 0x0E,
|
||||
0x00, 0x10, 0x0D, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x66, 0xCC, 0xCC, 0x6C, 0x66, 0xCC, 0xCC, 0x6C, 0x66, 0xCC, 0xCC, 0x6C,
|
||||
0x61, 0xC8, 0xCC, 0xCC, 0x68, 0x66, 0x66, 0x66, 0x80, 0x61, 0x66, 0x66,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF3, 0x63, 0xFF, 0x6F,
|
||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xCC, 0xCC, 0xCC, 0xCC,
|
||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xC6, 0xCC, 0xCC, 0x66, 0xC6, 0xCC, 0xCC, 0x66,
|
||||
0xC6, 0xCC, 0xCC, 0x66, 0xCC, 0xCC, 0x8C, 0x16, 0x66, 0x66, 0x66, 0x86,
|
||||
0x66, 0x66, 0x16, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
private static byte[] haxxStationIconPltt =
|
||||
{
|
||||
0x1F, 0x7C, 0x42, 0x04, 0x83, 0x0C, 0xC5, 0x08, 0xC6, 0x18, 0xE7, 0x1C,
|
||||
0x00, 0x00, 0x29, 0x25, 0x8C, 0x2D, 0xAD, 0x35, 0xCE, 0x39, 0x0F, 0x3E,
|
||||
0x10, 0x42, 0x51, 0x46, 0x94, 0x52, 0x35, 0x23
|
||||
};
|
||||
|
||||
private static byte[] haxxStationServer =
|
||||
{
|
||||
0x52, 0x43, 0x31, 0x20, 0x32, 0x30, 0x30, 0x36, 0x20, 0x30, 0x31, 0x20,
|
||||
0x32, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x65, 0x72, 0x69,
|
||||
0x63, 0x6F, 0x6D, 0x00, 0x00, 0x00, 0x48, 0x61, 0x78, 0x78, 0x53, 0x74,
|
||||
0x61, 0x74, 0x69, 0x6F, 0x6E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x79, 0x20, 0x47, 0x65, 0x72,
|
||||
0x69, 0x63, 0x6F, 0x6D, 0x2C, 0x20, 0x73, 0x68, 0x75, 0x74, 0x74, 0x65,
|
||||
0x72, 0x62, 0x75, 0x67, 0x32, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x6E, 0x64, 0x20, 0x41, 0x70,
|
||||
0x61, 0x63, 0x68, 0x65, 0x20, 0x54, 0x68, 0x75, 0x6E, 0x64, 0x65, 0x72,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2E, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
private static byte[] exploitData =
|
||||
{
|
||||
0x44, 0x30, 0x9F, 0xE5, 0x2C, 0x00, 0x93, 0xE5, 0x2C, 0x10, 0x9F, 0xE5,
|
||||
0x01, 0x00, 0x40, 0xE0, 0x28, 0x10, 0x9F, 0xE5, 0x01, 0x00, 0x80, 0xE0,
|
||||
0x24, 0x10, 0x9F, 0xE5, 0x24, 0x20, 0x9F, 0xE5, 0x28, 0xE0, 0x9F, 0xE5,
|
||||
0x3E, 0xFF, 0x2F, 0xE1, 0x24, 0xE0, 0x9F, 0xE5, 0x3E, 0xFF, 0x2F, 0xE1,
|
||||
0x01, 0x00, 0xA0, 0xE3, 0x1C, 0xE0, 0x9F, 0xE5, 0x1E, 0xFF, 0x2F, 0xE1,
|
||||
0x00, 0xAE, 0x11, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
|
||||
0x20, 0x6D, 0x11, 0x00, 0x40, 0xE8, 0x3F, 0x02, 0x08, 0xBB, 0x32, 0x02,
|
||||
0x24, 0xAF, 0x32, 0x02, 0x78, 0x3A, 0x32, 0x02
|
||||
};
|
||||
|
||||
private static byte[] arm7Fix =
|
||||
{
|
||||
0x2C, 0x00, 0x9F, 0xE5, 0x8E, 0x07, 0x80, 0xE2, 0x1C, 0x10, 0x9F, 0xE5,
|
||||
0x1C, 0x20, 0x9F, 0xE5, 0x01, 0x30, 0xD0, 0xE4, 0x01, 0x30, 0xC1, 0xE4,
|
||||
0x01, 0x20, 0x52, 0xE2, 0xFB, 0xFF, 0xFF, 0xCA, 0x00, 0x00, 0x9F, 0xE5,
|
||||
0x10, 0xFF, 0x2F, 0xE1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
private NDS mDownloadStation;
|
||||
private SFSDirectory mFileSystem;
|
||||
private DemoMenu mDemoMenu;
|
||||
|
||||
public DownloadStationPatcher(NDS downloadStation)
|
||||
{
|
||||
mDownloadStation = downloadStation;
|
||||
mFileSystem = mDownloadStation.ToFileSystem();
|
||||
|
||||
SFSDirectory d = mFileSystem.GetDirectoryByPath("//ds_demo");
|
||||
//this is shitty...
|
||||
d.Files.Remove(d.GetFileByPath("ds_demo/ANDEdemo"));
|
||||
d.Files.Remove(d.GetFileByPath("ds_demo/AGFEdemo"));
|
||||
d.Files.Remove(d.GetFileByPath("ds_demo/AMFEclip"));
|
||||
d.Files.Remove(d.GetFileByPath("ds_demo/AMTEdemo"));
|
||||
d.Files.Remove(d.GetFileByPath("ds_demo/APTEdemo"));
|
||||
d.Files.Remove(d.GetFileByPath("ds_demo/ATTEdemo"));
|
||||
d.Files.Remove(d.GetFileByPath("ds_demo/ATTEpush"));
|
||||
d.Files.Remove(d.GetFileByPath("ds_demo/testcode"));
|
||||
d.Files.Remove(d.GetFileByPath("ds_demo/AMCEdemo"));
|
||||
|
||||
mFileSystem.GetFileByPath("//mb/server").Data = haxxStationServer;
|
||||
mFileSystem.GetFileByPath("//mb/icon.nbfc").Data = haxxStationIconImage;
|
||||
mFileSystem.GetFileByPath("//mb/icon.nbfp").Data = haxxStationIconPltt;
|
||||
|
||||
//change banner
|
||||
mDownloadStation.Banner.Banner.Image = haxxStationIconImage;
|
||||
mDownloadStation.Banner.Banner.Pltt = haxxStationIconPltt;
|
||||
for (int i = 0; i < 6; i++)
|
||||
mDownloadStation.Banner.Banner.GameName[i] = "HaxxStation\nBy Gericom, shutterbug2000\nand Apache Thunder";
|
||||
|
||||
mDemoMenu = new DemoMenu();
|
||||
}
|
||||
|
||||
public void AddRom(NDS rom)
|
||||
{
|
||||
if (rom.Header.SubRamAddress >= 0x03000000)
|
||||
{
|
||||
byte[] newArm7 = new byte[rom.SubRom.Length + arm7Fix.Length];
|
||||
Array.Copy(arm7Fix, newArm7, arm7Fix.Length);
|
||||
Array.Copy(rom.SubRom, 0, newArm7, arm7Fix.Length, rom.SubRom.Length);
|
||||
IOUtil.WriteU32LE(newArm7, 0x28, rom.Header.SubEntryAddress);
|
||||
IOUtil.WriteU32LE(newArm7, 0x2C, rom.Header.SubRamAddress);
|
||||
IOUtil.WriteU32LE(newArm7, 0x30, rom.Header.SubSize);
|
||||
rom.SubRom = newArm7;
|
||||
rom.Header.SubSize = (uint)newArm7.Length;
|
||||
rom.Header.SubRamAddress = 0x02380000;
|
||||
rom.Header.SubEntryAddress = 0x02380000;
|
||||
}
|
||||
byte[] newRomFixed = rom.Write(true);
|
||||
|
||||
uint arm9offset = (uint)(newRomFixed[0x20] | (newRomFixed[0x21] << 8) | (newRomFixed[0x22] << 16) | (newRomFixed[0x23] << 24));
|
||||
uint arm9loadaddr = (uint)(newRomFixed[0x28] | (newRomFixed[0x29] << 8) | (newRomFixed[0x2A] << 16) | (newRomFixed[0x2B] << 24));
|
||||
uint arm9size = (uint)(newRomFixed[0x2C] | (newRomFixed[0x2D] << 8) | (newRomFixed[0x2E] << 16) | (newRomFixed[0x2F] << 24));
|
||||
uint arm7offset = (uint)(newRomFixed[0x30] | (newRomFixed[0x31] << 8) | (newRomFixed[0x32] << 16) | (newRomFixed[0x33] << 24));
|
||||
|
||||
//arm9 offset becomes 0x180
|
||||
newRomFixed[0x20] = 0x80;
|
||||
newRomFixed[0x21] = 0x01;
|
||||
newRomFixed[0x22] = 0x00;
|
||||
newRomFixed[0x23] = 0x00;
|
||||
//arm9 load becomes 0x02332C40 (rsa_GetDecodedHash)
|
||||
newRomFixed[0x28] = 0x40;
|
||||
newRomFixed[0x29] = 0x2C;
|
||||
newRomFixed[0x2A] = 0x33;
|
||||
newRomFixed[0x2B] = 0x02;
|
||||
//arm9 size becomes 0x100
|
||||
newRomFixed[0x2C] = 0x00;
|
||||
newRomFixed[0x2D] = 0x01;
|
||||
newRomFixed[0x2E] = 0x00;
|
||||
newRomFixed[0x2F] = 0x00;
|
||||
ushort newcrc = CRC16.GetCRC16(newRomFixed, 0, 0x15E);
|
||||
newRomFixed[0x15E] = (byte)(newcrc & 0xFF);
|
||||
newRomFixed[0x15F] = (byte)(newcrc >> 8);
|
||||
|
||||
Array.Copy(exploitData, 0, newRomFixed, 0x180, exploitData.Length);
|
||||
|
||||
newRomFixed[0x180 + 0x3C] = (byte)(arm7offset & 0xFF);
|
||||
newRomFixed[0x180 + 0x3D] = (byte)((arm7offset >> 8) & 0xFF);
|
||||
newRomFixed[0x180 + 0x3E] = (byte)((arm7offset >> 16) & 0xFF);
|
||||
newRomFixed[0x180 + 0x3F] = (byte)((arm7offset >> 24) & 0xFF);
|
||||
|
||||
newRomFixed[0x180 + 0x40] = (byte)(arm9offset & 0xFF);
|
||||
newRomFixed[0x180 + 0x41] = (byte)((arm9offset >> 8) & 0xFF);
|
||||
newRomFixed[0x180 + 0x42] = (byte)((arm9offset >> 16) & 0xFF);
|
||||
newRomFixed[0x180 + 0x43] = (byte)((arm9offset >> 24) & 0xFF);
|
||||
|
||||
newRomFixed[0x180 + 0x44] = (byte)(arm9loadaddr & 0xFF);
|
||||
newRomFixed[0x180 + 0x45] = (byte)((arm9loadaddr >> 8) & 0xFF);
|
||||
newRomFixed[0x180 + 0x46] = (byte)((arm9loadaddr >> 16) & 0xFF);
|
||||
newRomFixed[0x180 + 0x47] = (byte)((arm9loadaddr >> 24) & 0xFF);
|
||||
|
||||
newRomFixed[0x180 + 0x48] = (byte)(arm9size & 0xFF);
|
||||
newRomFixed[0x180 + 0x49] = (byte)((arm9size >> 8) & 0xFF);
|
||||
newRomFixed[0x180 + 0x4A] = (byte)((arm9size >> 16) & 0xFF);
|
||||
newRomFixed[0x180 + 0x4B] = (byte)((arm9size >> 24) & 0xFF);
|
||||
|
||||
string fileName = "rom" + mDemoMenu.entries.Count.ToString("0000") + "d";
|
||||
|
||||
var entry = new DemoMenu.DemoMenuEntry()
|
||||
{
|
||||
rating = 1,
|
||||
guideMode = 0x15,
|
||||
touchText1 = "HaxxStation by Gericom,",
|
||||
touchText2 = "shutterbug2000, Apache Thunder",
|
||||
internalName = fileName
|
||||
};
|
||||
if (rom.Banner != null)
|
||||
{
|
||||
string[] lines = rom.Banner.Banner.GameName[1].Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (lines.Length > 0)
|
||||
entry.bannerText1 = lines[0];
|
||||
else
|
||||
entry.bannerText1 = "Bannerless Homebrew";
|
||||
if (lines.Length > 1)
|
||||
entry.bannerText2 = lines[1];
|
||||
else
|
||||
entry.bannerText2 = "";
|
||||
entry.bannerImage = rom.Banner.Banner.Image;
|
||||
entry.bannerPalette = rom.Banner.Banner.Pltt;
|
||||
}
|
||||
else
|
||||
{
|
||||
entry.bannerText1 = "Bannerless Homebrew";
|
||||
entry.bannerText2 = "";
|
||||
entry.bannerImage = new byte[512];
|
||||
entry.bannerPalette = new byte[32];
|
||||
}
|
||||
mDemoMenu.entries.Add(entry);
|
||||
var d = mFileSystem.GetDirectoryByPath("//ds_demo");
|
||||
d.Files.Add(new SFSFile(-1, fileName, d) { Data = newRomFixed });
|
||||
|
||||
}
|
||||
|
||||
public NDS ProduceRom()
|
||||
{
|
||||
string fileName = "rom" + (mDemoMenu.entries.Count - 1).ToString("0000") + "d";
|
||||
while (mDemoMenu.entries.Count < 3)
|
||||
{
|
||||
mDemoMenu.entries.Add(new DemoMenu.DemoMenuEntry()
|
||||
{
|
||||
bannerImage = new byte[512],
|
||||
bannerPalette = new byte[32],
|
||||
bannerText1 = "",
|
||||
bannerText2 = "",
|
||||
rating = 1,
|
||||
guideMode = 0x15,
|
||||
touchText1 = "HaxxStation by Gericom,",
|
||||
touchText2 = "shutterbug2000, Apache Thunder",
|
||||
internalName = fileName
|
||||
});
|
||||
}
|
||||
mFileSystem.GetFileByPath("//ds_demo/demomenu").Data = mDemoMenu.Write();
|
||||
mDownloadStation.FromFileSystem(mFileSystem);
|
||||
return mDownloadStation;
|
||||
}
|
||||
}
|
||||
}
|
@ -13,348 +13,116 @@ namespace dspatch
|
||||
{
|
||||
class Program
|
||||
{
|
||||
static byte[] lockIconImage =
|
||||
{
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x8A,
|
||||
0x00, 0xA0, 0x88, 0x88, 0x00, 0x88, 0x57, 0x34, 0x80, 0x58, 0x33, 0x33,
|
||||
0x8A, 0x34, 0x04, 0x00, 0xA0, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xA8, 0x0A, 0x00, 0x00, 0x88, 0x88, 0x0A, 0x00,
|
||||
0x43, 0x75, 0x88, 0x00, 0x33, 0x33, 0x85, 0x08, 0x00, 0x40, 0x43, 0x88,
|
||||
0x00, 0x00, 0x37, 0x85, 0x00, 0x00, 0x40, 0x73, 0x00, 0x00, 0x00, 0x53,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,
|
||||
0x08, 0x00, 0x00, 0x00, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x33,
|
||||
0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x33,
|
||||
0x00, 0x00, 0x00, 0x33, 0xDD, 0xDD, 0xDD, 0xDD, 0xA8, 0x00, 0x00, 0x00,
|
||||
0x88, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00,
|
||||
0x88, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00,
|
||||
0xDD, 0xED, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0x29, 0xFF, 0xFF, 0xBF, 0x11, 0xFF, 0xFF, 0x9F, 0x11,
|
||||
0xFF, 0xFF, 0xBF, 0x11, 0xFF, 0xFF, 0xFF, 0x16, 0xDD, 0xDD, 0xDD, 0xDD,
|
||||
0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x92, 0xDD, 0xDD, 0xDD,
|
||||
0x11, 0xDB, 0xDD, 0xDD, 0x11, 0xD9, 0xDD, 0xDD, 0x11, 0xDB, 0xDD, 0xDD,
|
||||
0x61, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x00, 0x00, 0xDD, 0xDD, 0x00, 0x00,
|
||||
0xDD, 0xDD, 0x00, 0x00, 0xDD, 0xDD, 0x00, 0x00, 0xDD, 0xDD, 0x00, 0x00,
|
||||
0xDD, 0xDD, 0x00, 0x00, 0xDD, 0xDD, 0x00, 0x00, 0xDD, 0xDD, 0x00, 0x00,
|
||||
0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x16,
|
||||
0xFF, 0xFF, 0xFF, 0x12, 0xFF, 0xFF, 0xCF, 0x11, 0xFF, 0xFF, 0x9F, 0x11,
|
||||
0xFF, 0xFF, 0x9F, 0x11, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0x61, 0xDD, 0xDD, 0xDD, 0x21, 0xDD, 0xDD, 0xDD,
|
||||
0x11, 0xDB, 0xDD, 0xDD, 0x11, 0xD9, 0xDD, 0xDD, 0x11, 0xD9, 0xDD, 0xDD,
|
||||
0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
|
||||
0xDD, 0xDD, 0x00, 0x00, 0xDD, 0xDD, 0x00, 0x00, 0xDD, 0xDD, 0x00, 0x00,
|
||||
0xDD, 0xDD, 0x00, 0x00, 0xDD, 0xDD, 0x00, 0x00, 0xDD, 0xDD, 0x00, 0x00,
|
||||
0xDD, 0xDD, 0x00, 0x00, 0xDD, 0xED, 0x00, 0x00
|
||||
};
|
||||
|
||||
static byte[] lockIconPltt =
|
||||
{
|
||||
0x1C, 0x3C, 0x07, 0x25, 0x49, 0x25, 0xAA, 0x3D, 0xCB, 0x3D, 0xEC, 0x41,
|
||||
0xEF, 0x25, 0x0E, 0x4A, 0x2F, 0x4E, 0x74, 0x26, 0x71, 0x56, 0xF9, 0x2A,
|
||||
0x5B, 0x2F, 0x5E, 0x1B, 0x7E, 0x37, 0xBF, 0x2F
|
||||
};
|
||||
|
||||
static byte[] haxxStationIconImage =
|
||||
{
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x90, 0x61, 0x66, 0x66, 0x69, 0x66, 0x66, 0x66, 0x61, 0xC8, 0xCC, 0xCC,
|
||||
0x66, 0xCC, 0xCC, 0x6C, 0x66, 0xCC, 0xCC, 0x6C, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66,
|
||||
0x66, 0x66, 0x66, 0x66, 0xCC, 0xCC, 0xCC, 0xCC, 0x66, 0x66, 0x66, 0x66,
|
||||
0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x16, 0x09, 0x66, 0x66, 0x66, 0x96,
|
||||
0xCC, 0xCC, 0x8C, 0x16, 0xC6, 0xCC, 0xCC, 0x66, 0xC6, 0xCC, 0xCC, 0x66,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0xCC, 0xCC, 0x6C,
|
||||
0x66, 0xCC, 0xCC, 0x6C, 0x66, 0xCC, 0xCC, 0x6C, 0x66, 0xCC, 0xCC, 0x6C,
|
||||
0x66, 0xCC, 0xCC, 0x6C, 0x66, 0x8C, 0xCC, 0x6C, 0x45, 0x65, 0x41, 0x85,
|
||||
0x89, 0xE2, 0xC0, 0x27, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
0x66, 0x66, 0x66, 0x66, 0x27, 0x16, 0x54, 0xB7, 0xD5, 0xE0, 0x9D, 0x14,
|
||||
0xC6, 0xCC, 0xCC, 0x66, 0xC6, 0xCC, 0xCC, 0x66, 0xC6, 0xCC, 0xCC, 0x66,
|
||||
0xC6, 0xCC, 0xCC, 0x66, 0xC6, 0xCC, 0xCC, 0x66, 0xC6, 0x99, 0xCC, 0x66,
|
||||
0x5C, 0x11, 0xC5, 0x66, 0x42, 0xEE, 0x24, 0x44, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x20, 0x0E, 0x00,
|
||||
0x00, 0x79, 0x00, 0x0B, 0x00, 0x01, 0x70, 0x08, 0xD0, 0x04, 0x2E, 0x00,
|
||||
0xB0, 0x07, 0x5D, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD9, 0x00, 0x77, 0x0C,
|
||||
0x24, 0x87, 0x52, 0x14, 0x66, 0x14, 0xC9, 0x6C, 0x66, 0xAC, 0xCC, 0x6C,
|
||||
0x66, 0xCC, 0xC1, 0x6C, 0x66, 0x1C, 0x16, 0x6C, 0x66, 0xCC, 0xC1, 0x6C,
|
||||
0x00, 0x00, 0x00, 0x00, 0x80, 0x21, 0xA7, 0x00, 0x41, 0x88, 0x47, 0x41,
|
||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xF3, 0x63, 0x66, 0x66,
|
||||
0x36, 0x3F, 0x66, 0x66, 0x36, 0x3F, 0x66, 0x66, 0x0D, 0x00, 0xD0, 0x99,
|
||||
0x00, 0x88, 0x00, 0x00, 0x18, 0x44, 0x81, 0x99, 0x76, 0xCC, 0x57, 0x44,
|
||||
0xC6, 0xCC, 0xCC, 0x66, 0xC6, 0x6C, 0xCC, 0x66, 0xC6, 0xC6, 0xC6, 0x66,
|
||||
0xC6, 0x6C, 0xCC, 0x66, 0x90, 0x09, 0x89, 0x00, 0xB0, 0x07, 0x4D, 0x00,
|
||||
0xD0, 0x04, 0x10, 0x00, 0x00, 0x01, 0x80, 0x05, 0x00, 0x78, 0x00, 0x0E,
|
||||
0x00, 0x10, 0x0D, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x66, 0xCC, 0xCC, 0x6C, 0x66, 0xCC, 0xCC, 0x6C, 0x66, 0xCC, 0xCC, 0x6C,
|
||||
0x61, 0xC8, 0xCC, 0xCC, 0x68, 0x66, 0x66, 0x66, 0x80, 0x61, 0x66, 0x66,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF3, 0x63, 0xFF, 0x6F,
|
||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xCC, 0xCC, 0xCC, 0xCC,
|
||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xC6, 0xCC, 0xCC, 0x66, 0xC6, 0xCC, 0xCC, 0x66,
|
||||
0xC6, 0xCC, 0xCC, 0x66, 0xCC, 0xCC, 0x8C, 0x16, 0x66, 0x66, 0x66, 0x86,
|
||||
0x66, 0x66, 0x16, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
static byte[] haxxStationIconPltt =
|
||||
{
|
||||
0x1F, 0x7C, 0x42, 0x04, 0x83, 0x0C, 0xC5, 0x08, 0xC6, 0x18, 0xE7, 0x1C,
|
||||
0x00, 0x00, 0x29, 0x25, 0x8C, 0x2D, 0xAD, 0x35, 0xCE, 0x39, 0x0F, 0x3E,
|
||||
0x10, 0x42, 0x51, 0x46, 0x94, 0x52, 0x35, 0x23
|
||||
};
|
||||
|
||||
static byte[] haxxStationServer =
|
||||
{
|
||||
0x52, 0x43, 0x31, 0x20, 0x32, 0x30, 0x30, 0x36, 0x20, 0x30, 0x31, 0x20,
|
||||
0x32, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x65, 0x72, 0x69,
|
||||
0x63, 0x6F, 0x6D, 0x00, 0x00, 0x00, 0x48, 0x61, 0x78, 0x78, 0x53, 0x74,
|
||||
0x61, 0x74, 0x69, 0x6F, 0x6E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x79, 0x20, 0x47, 0x65, 0x72,
|
||||
0x69, 0x63, 0x6F, 0x6D, 0x2C, 0x20, 0x73, 0x68, 0x75, 0x74, 0x74, 0x65,
|
||||
0x72, 0x62, 0x75, 0x67, 0x32, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x6E, 0x64, 0x20, 0x41, 0x70,
|
||||
0x61, 0x63, 0x68, 0x65, 0x20, 0x54, 0x68, 0x75, 0x6E, 0x64, 0x65, 0x72,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2E, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
static byte[] dsHash =
|
||||
{
|
||||
0xF1, 0x8B, 0x55, 0xF3, 0xE1, 0x25, 0x9C, 0x03, 0xE1, 0x0D, 0x0E, 0xCB,
|
||||
0x54, 0x96, 0x93, 0xB4, 0x29, 0x05, 0xCE, 0xB5
|
||||
};
|
||||
|
||||
static byte[] exploitData =
|
||||
{
|
||||
0x44, 0x30, 0x9F, 0xE5, 0x2C, 0x00, 0x93, 0xE5, 0x2C, 0x10, 0x9F, 0xE5,
|
||||
0x01, 0x00, 0x40, 0xE0, 0x28, 0x10, 0x9F, 0xE5, 0x01, 0x00, 0x80, 0xE0,
|
||||
0x24, 0x10, 0x9F, 0xE5, 0x24, 0x20, 0x9F, 0xE5, 0x28, 0xE0, 0x9F, 0xE5,
|
||||
0x3E, 0xFF, 0x2F, 0xE1, 0x24, 0xE0, 0x9F, 0xE5, 0x3E, 0xFF, 0x2F, 0xE1,
|
||||
0x01, 0x00, 0xA0, 0xE3, 0x1C, 0xE0, 0x9F, 0xE5, 0x1E, 0xFF, 0x2F, 0xE1,
|
||||
0x00, 0xAE, 0x11, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
|
||||
0x20, 0x6D, 0x11, 0x00, 0x40, 0xE8, 0x3F, 0x02, 0x08, 0xBB, 0x32, 0x02,
|
||||
0x24, 0xAF, 0x32, 0x02, 0x78, 0x3A, 0x32, 0x02
|
||||
};
|
||||
|
||||
static byte[] arm7Fix =
|
||||
{
|
||||
0x2C, 0x00, 0x9F, 0xE5, 0x8E, 0x07, 0x80, 0xE2, 0x1C, 0x10, 0x9F, 0xE5,
|
||||
0x1C, 0x20, 0x9F, 0xE5, 0x01, 0x30, 0xD0, 0xE4, 0x01, 0x30, 0xC1, 0xE4,
|
||||
0x01, 0x20, 0x52, 0xE2, 0xFB, 0xFF, 0xFF, 0xCA, 0x00, 0x00, 0x9F, 0xE5,
|
||||
0x10, 0xFF, 0x2F, 0xE1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
static void PrintUsage()
|
||||
{
|
||||
Console.WriteLine("Usage: dspatch download_station.nds rom_to_boot.nds result.nds");
|
||||
Console.WriteLine("Usage: dspatch -s download_station.nds -o result.nds [-i rom1.nds] [-I romfolder1]");
|
||||
Console.WriteLine("You can add multiple roms by using -I or -i multiple times");
|
||||
}
|
||||
|
||||
static void Main(string[] args)
|
||||
{
|
||||
Console.WriteLine("== DS Download Station Patcher v1.0 ==");
|
||||
Console.WriteLine("Exploit by Gericom, shutterbug2000 and Apache Thunder\n");
|
||||
if (args.Length != 3)
|
||||
PrintUsage();
|
||||
else
|
||||
|
||||
if (args.Length <= 1)
|
||||
{
|
||||
byte[] dsdata = File.ReadAllBytes(args[0]);
|
||||
byte[] sha1 = SHA1.Create().ComputeHash(dsdata);
|
||||
for (int i = 0; i < 20; i++)
|
||||
{
|
||||
if (sha1[i] != dsHash[i])
|
||||
{
|
||||
Console.WriteLine("Error: Invalid download station rom!");
|
||||
Console.WriteLine("The patcher is only compatible with:");
|
||||
Console.WriteLine("xxxx - DS Download Station - Volume 1 (Kiosk WiFi Demo Cart) (U)(Independent).nds");
|
||||
Console.WriteLine("SHA1: F18B55F3E1259C03E10D0ECB549693B42905CEB5");
|
||||
return;
|
||||
}
|
||||
}
|
||||
NDS downloadStation = new NDS(dsdata);
|
||||
var fs = downloadStation.ToFileSystem();
|
||||
byte[] newRom = File.ReadAllBytes(args[1]);
|
||||
NDS newRom2 = new NDS(newRom);
|
||||
if (newRom2.Header.SubRamAddress >= 0x03000000)
|
||||
{
|
||||
byte[] newArm7 = new byte[newRom2.SubRom.Length + arm7Fix.Length];
|
||||
Array.Copy(arm7Fix, newArm7, arm7Fix.Length);
|
||||
Array.Copy(newRom2.SubRom, 0, newArm7, arm7Fix.Length, newRom2.SubRom.Length);
|
||||
IOUtil.WriteU32LE(newArm7, 0x28, newRom2.Header.SubEntryAddress);
|
||||
IOUtil.WriteU32LE(newArm7, 0x2C, newRom2.Header.SubRamAddress);
|
||||
IOUtil.WriteU32LE(newArm7, 0x30, newRom2.Header.SubSize);
|
||||
newRom2.SubRom = newArm7;
|
||||
newRom2.Header.SubSize = (uint)newArm7.Length;
|
||||
newRom2.Header.SubRamAddress = 0x02380000;
|
||||
newRom2.Header.SubEntryAddress = 0x02380000;
|
||||
}
|
||||
byte[] newRomFixed = newRom2.Write(true);
|
||||
{
|
||||
uint arm9offset = (uint)(newRomFixed[0x20] | (newRomFixed[0x21] << 8) | (newRomFixed[0x22] << 16) | (newRomFixed[0x23] << 24));
|
||||
uint arm9loadaddr = (uint)(newRomFixed[0x28] | (newRomFixed[0x29] << 8) | (newRomFixed[0x2A] << 16) | (newRomFixed[0x2B] << 24));
|
||||
uint arm9size = (uint)(newRomFixed[0x2C] | (newRomFixed[0x2D] << 8) | (newRomFixed[0x2E] << 16) | (newRomFixed[0x2F] << 24));
|
||||
uint arm7offset = (uint)(newRomFixed[0x30] | (newRomFixed[0x31] << 8) | (newRomFixed[0x32] << 16) | (newRomFixed[0x33] << 24));
|
||||
|
||||
//arm9 offset becomes 0x180
|
||||
newRomFixed[0x20] = 0x80;
|
||||
newRomFixed[0x21] = 0x01;
|
||||
newRomFixed[0x22] = 0x00;
|
||||
newRomFixed[0x23] = 0x00;
|
||||
//arm9 load becomes 0x02332C40 (rsa_GetDecodedHash)
|
||||
newRomFixed[0x28] = 0x40;
|
||||
newRomFixed[0x29] = 0x2C;
|
||||
newRomFixed[0x2A] = 0x33;
|
||||
newRomFixed[0x2B] = 0x02;
|
||||
//arm9 size becomes 0x100
|
||||
newRomFixed[0x2C] = 0x00;
|
||||
newRomFixed[0x2D] = 0x01;
|
||||
newRomFixed[0x2E] = 0x00;
|
||||
newRomFixed[0x2F] = 0x00;
|
||||
ushort newcrc = CRC16.GetCRC16(newRomFixed, 0, 0x15E);
|
||||
newRomFixed[0x15E] = (byte)(newcrc & 0xFF);
|
||||
newRomFixed[0x15F] = (byte)(newcrc >> 8);
|
||||
|
||||
exploitData[0x3C] = (byte)(arm7offset & 0xFF);
|
||||
exploitData[0x3D] = (byte)((arm7offset >> 8) & 0xFF);
|
||||
exploitData[0x3E] = (byte)((arm7offset >> 16) & 0xFF);
|
||||
exploitData[0x3F] = (byte)((arm7offset >> 24) & 0xFF);
|
||||
|
||||
exploitData[0x40] = (byte)(arm9offset & 0xFF);
|
||||
exploitData[0x41] = (byte)((arm9offset >> 8) & 0xFF);
|
||||
exploitData[0x42] = (byte)((arm9offset >> 16) & 0xFF);
|
||||
exploitData[0x43] = (byte)((arm9offset >> 24) & 0xFF);
|
||||
|
||||
exploitData[0x44] = (byte)(arm9loadaddr & 0xFF);
|
||||
exploitData[0x45] = (byte)((arm9loadaddr >> 8) & 0xFF);
|
||||
exploitData[0x46] = (byte)((arm9loadaddr >> 16) & 0xFF);
|
||||
exploitData[0x47] = (byte)((arm9loadaddr >> 24) & 0xFF);
|
||||
|
||||
exploitData[0x48] = (byte)(arm9size & 0xFF);
|
||||
exploitData[0x49] = (byte)((arm9size >> 8) & 0xFF);
|
||||
exploitData[0x4A] = (byte)((arm9size >> 16) & 0xFF);
|
||||
exploitData[0x4B] = (byte)((arm9size >> 24) & 0xFF);
|
||||
|
||||
Array.Copy(exploitData, 0, newRomFixed, 0x180, exploitData.Length);
|
||||
}
|
||||
SFSDirectory d = fs.GetDirectoryByPath("//ds_demo");
|
||||
d.Files.Add(new SFSFile(-1, "rom1.nds", d) { Data = newRomFixed });
|
||||
//this is shitty...
|
||||
d.Files.Remove(d.GetFileByPath("ds_demo/ANDEdemo"));
|
||||
d.Files.Remove(d.GetFileByPath("ds_demo/AGFEdemo"));
|
||||
d.Files.Remove(d.GetFileByPath("ds_demo/AMFEclip"));
|
||||
d.Files.Remove(d.GetFileByPath("ds_demo/AMTEdemo"));
|
||||
d.Files.Remove(d.GetFileByPath("ds_demo/APTEdemo"));
|
||||
d.Files.Remove(d.GetFileByPath("ds_demo/ATTEdemo"));
|
||||
d.Files.Remove(d.GetFileByPath("ds_demo/ATTEpush"));
|
||||
d.Files.Remove(d.GetFileByPath("ds_demo/testcode"));
|
||||
d.Files.Remove(d.GetFileByPath("ds_demo/AMCEdemo"));
|
||||
DemoMenu menu = new DemoMenu();
|
||||
menu.entries = new DemoMenu.DemoMenuEntry[]
|
||||
{
|
||||
new DemoMenu.DemoMenuEntry()
|
||||
{
|
||||
rating = 1,
|
||||
guideMode = 0x15,
|
||||
touchText1 = "HaxxStation by Gericom,",
|
||||
touchText2 = "shutterbug2000, Apache Thunder",
|
||||
internalName = "rom1.nds"
|
||||
},
|
||||
new DemoMenu.DemoMenuEntry()
|
||||
{
|
||||
bannerImage = new byte[512],
|
||||
bannerPalette = new byte[32],
|
||||
bannerText1 = "",
|
||||
bannerText2 = "",
|
||||
rating = 1,
|
||||
guideMode = 0x15,
|
||||
touchText1 = "HaxxStation by Gericom,",
|
||||
touchText2 = "shutterbug2000, Apache Thunder",
|
||||
internalName = "rom1.nds"
|
||||
},
|
||||
new DemoMenu.DemoMenuEntry()
|
||||
{
|
||||
bannerImage = new byte[512],
|
||||
bannerPalette = new byte[32],
|
||||
bannerText1 = "",
|
||||
bannerText2 = "",
|
||||
rating = 1,
|
||||
guideMode = 0x15,
|
||||
touchText1 = "HaxxStation by Gericom,",
|
||||
touchText2 = "shutterbug2000, Apache Thunder",
|
||||
internalName = "rom1.nds"
|
||||
}
|
||||
};
|
||||
if (newRom2.Banner != null)
|
||||
{
|
||||
string[] lines = newRom2.Banner.Banner.GameName[1].Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (lines.Length > 0)
|
||||
menu.entries[0].bannerText1 = lines[0];
|
||||
else
|
||||
menu.entries[0].bannerText1 = "Bannerless Homebrew";
|
||||
if (lines.Length > 1)
|
||||
menu.entries[0].bannerText2 = lines[1];
|
||||
else
|
||||
menu.entries[0].bannerText2 = "";
|
||||
menu.entries[0].bannerImage = newRom2.Banner.Banner.Image;
|
||||
menu.entries[0].bannerPalette = newRom2.Banner.Banner.Pltt;
|
||||
}
|
||||
else
|
||||
{
|
||||
menu.entries[0].bannerText1 = "Bannerless Homebrew";
|
||||
menu.entries[0].bannerText2 = "";
|
||||
menu.entries[0].bannerImage = new byte[512];
|
||||
menu.entries[0].bannerPalette = new byte[32];
|
||||
}
|
||||
byte[] demoMenu = menu.Write();
|
||||
fs.GetFileByPath("//ds_demo/demomenu").Data = demoMenu;
|
||||
fs.GetFileByPath("//mb/server").Data = haxxStationServer;
|
||||
fs.GetFileByPath("//mb/icon.nbfc").Data = haxxStationIconImage;
|
||||
fs.GetFileByPath("//mb/icon.nbfp").Data = haxxStationIconPltt;
|
||||
downloadStation.FromFileSystem(fs);
|
||||
//change banner
|
||||
downloadStation.Banner.Banner.Image = haxxStationIconImage;
|
||||
downloadStation.Banner.Banner.Pltt = haxxStationIconPltt;
|
||||
for(int i = 0; i < 6; i++)
|
||||
downloadStation.Banner.Banner.GameName[i] = "HaxxStation\nBy Gericom, shutterbug2000\nand Apache Thunder";
|
||||
byte[] finalResult = downloadStation.Write();
|
||||
File.Create(args[2]).Close();
|
||||
File.WriteAllBytes(args[2], finalResult);
|
||||
PrintUsage();
|
||||
return;
|
||||
}
|
||||
|
||||
string dsPath = null;
|
||||
string outPath = null;
|
||||
List<string> romPaths = new List<string>();
|
||||
string filePath;
|
||||
//parse arguments
|
||||
int q = 0;
|
||||
while (q < args.Length - 1)
|
||||
{
|
||||
string arg = args[q++];
|
||||
switch (arg)
|
||||
{
|
||||
case "-s":
|
||||
filePath = args[q++];
|
||||
if (!File.Exists(filePath))
|
||||
{
|
||||
Console.WriteLine("Error: File (" + filePath + ") does not exist!");
|
||||
return;
|
||||
}
|
||||
dsPath = filePath;
|
||||
break;
|
||||
case "-o":
|
||||
outPath = args[q++];
|
||||
break;
|
||||
case "-i":
|
||||
filePath = args[q++];
|
||||
if (!File.Exists(filePath))
|
||||
{
|
||||
Console.WriteLine("Error: File (" + filePath + ") does not exist!");
|
||||
return;
|
||||
}
|
||||
romPaths.Add(filePath);
|
||||
break;
|
||||
case "-I":
|
||||
string dirPath = args[q++];
|
||||
if (!Directory.Exists(dirPath))
|
||||
{
|
||||
Console.WriteLine("Error: Directory (" + dirPath + ") does not exist!");
|
||||
return;
|
||||
}
|
||||
romPaths.AddRange(Directory.GetFiles(dirPath, "*.nds"));
|
||||
romPaths.AddRange(Directory.GetFiles(dirPath, "*.srl"));
|
||||
break;
|
||||
default:
|
||||
Console.WriteLine("Error: Invalid argument (" + arg + ")\n");
|
||||
PrintUsage();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (dsPath == null)
|
||||
{
|
||||
Console.WriteLine("Error: Specify a download station rom!\n");
|
||||
PrintUsage();
|
||||
return;
|
||||
}
|
||||
if (outPath == null)
|
||||
{
|
||||
Console.WriteLine("Error: Specify a destination path!\n");
|
||||
PrintUsage();
|
||||
return;
|
||||
}
|
||||
if (romPaths.Count == 0)
|
||||
{
|
||||
Console.WriteLine("Error: Specify at least 1 rom!\n");
|
||||
PrintUsage();
|
||||
return;
|
||||
}
|
||||
|
||||
byte[] dsdata = File.ReadAllBytes(dsPath);
|
||||
byte[] sha1 = SHA1.Create().ComputeHash(dsdata);
|
||||
for (int i = 0; i < 20; i++)
|
||||
{
|
||||
if (sha1[i] != dsHash[i])
|
||||
{
|
||||
Console.WriteLine("Error: Invalid download station rom!");
|
||||
Console.WriteLine("The patcher is only compatible with:");
|
||||
Console.WriteLine("xxxx - DS Download Station - Volume 1 (Kiosk WiFi Demo Cart) (U)(Independent).nds");
|
||||
Console.WriteLine("SHA1: F18B55F3E1259C03E10D0ECB549693B42905CEB5");
|
||||
return;
|
||||
}
|
||||
}
|
||||
DownloadStationPatcher p = new DownloadStationPatcher(new NDS(dsdata));
|
||||
foreach(var r in romPaths)
|
||||
p.AddRom(new NDS(File.ReadAllBytes(r)));
|
||||
byte[] finalResult = p.ProduceRom().Write();
|
||||
File.Create(outPath).Close();
|
||||
File.WriteAllBytes(outPath, finalResult);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -44,6 +44,7 @@
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="DownloadStationPatcher.cs" />
|
||||
<Compile Include="DS\DemoMenu.cs" />
|
||||
<Compile Include="IO\IOUtil.cs" />
|
||||
<Compile Include="Nitro\ARM9.cs" />
|
||||
|
Loading…
Reference in New Issue
Block a user