mirror of
https://github.com/FIX94/nfs2iso2nfs.git
synced 2024-11-22 09:39:20 +01:00
faster patching + homebrew patches
This commit is contained in:
parent
edfe7b9174
commit
c01b9f57d2
456
Program.cs
456
Program.cs
@ -12,17 +12,22 @@ namespace nfs2iso2nfs
|
|||||||
{
|
{
|
||||||
public const int SECTOR_SIZE = 0x8000;
|
public const int SECTOR_SIZE = 0x8000;
|
||||||
public const int HEADER_SIZE = 0x200;
|
public const int HEADER_SIZE = 0x200;
|
||||||
public static byte[] WII_COMMON_KEY = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
public static byte[] WII_COMMON_KEY = { 0xEB, 0xE4, 0x2A, 0x22, 0x5E, 0x85, 0x93, 0xE4, 0x48, 0xD9, 0xC5, 0x45, 0x73, 0x81, 0xAA, 0xF7 };
|
||||||
public const int NFS_SIZE = 0xFA00000;
|
public const int NFS_SIZE = 0xFA00000;
|
||||||
public static bool dec = false;
|
public static bool dec = false;
|
||||||
public static bool enc = false;
|
public static bool enc = false;
|
||||||
public static bool keepFiles = false;
|
public static bool keepFiles = false;
|
||||||
public static bool keepLegit = false;
|
public static bool keepLegit = false;
|
||||||
|
public static bool horiz_wiimote = false;
|
||||||
|
public static bool vert_wiimote = false;
|
||||||
|
public static bool map_shoulder_to_trigger = false;
|
||||||
|
public static bool homebrew = false;
|
||||||
public static string keyFile = "..\\code\\htk.bin";
|
public static string keyFile = "..\\code\\htk.bin";
|
||||||
public static string isoFile = "game.iso";
|
public static string isoFile = "game.iso";
|
||||||
public static string wiiKeyFile = "wii_common_key.bin";
|
public static string wiiKeyFile = "wii_common_key.bin";
|
||||||
public static string nfsDir = "";
|
public static string nfsDir = "";
|
||||||
public static string fwFile = "..\\code\\fw.img";
|
public static string fw_file = "..\\code\\fw.img";
|
||||||
|
|
||||||
|
|
||||||
static void Main(string[] args)
|
static void Main(string[] args)
|
||||||
{
|
{
|
||||||
@ -48,8 +53,8 @@ namespace nfs2iso2nfs
|
|||||||
}
|
}
|
||||||
else if (enc)
|
else if (enc)
|
||||||
{
|
{
|
||||||
if (!keepLegit)
|
if (!keepLegit || horiz_wiimote || vert_wiimote || map_shoulder_to_trigger)
|
||||||
patchFakeSigning(fwFile);
|
DoThePatching(fw_file);
|
||||||
long[] size = manipulateISO(isoFile, "hif_unpack.nfs", false);
|
long[] size = manipulateISO(isoFile, "hif_unpack.nfs", false);
|
||||||
byte[] header = packNFS("hif_unpack.nfs", "hif_dec.nfs", size);
|
byte[] header = packNFS("hif_unpack.nfs", "hif_dec.nfs", size);
|
||||||
if (!keepFiles)
|
if (!keepFiles)
|
||||||
@ -108,14 +113,27 @@ namespace nfs2iso2nfs
|
|||||||
case "-fwimg":
|
case "-fwimg":
|
||||||
if (i == args.Length)
|
if (i == args.Length)
|
||||||
return -1;
|
return -1;
|
||||||
fwFile = args[i + 1];
|
fw_file = args[i + 1];
|
||||||
i++;
|
i++;
|
||||||
break;
|
break;
|
||||||
|
case "-lrpatch":
|
||||||
|
map_shoulder_to_trigger = true;
|
||||||
|
break;
|
||||||
|
case "-wiimote":
|
||||||
|
horiz_wiimote = true;
|
||||||
|
break;
|
||||||
|
case "-vertical":
|
||||||
|
vert_wiimote = true;
|
||||||
|
break;
|
||||||
|
case "-homebrew":
|
||||||
|
homebrew = true;
|
||||||
|
break;
|
||||||
|
|
||||||
case "-help":
|
case "-help":
|
||||||
Console.WriteLine("+++++ NFS2ISO2NFS v0.4+++++");
|
Console.WriteLine("+++++ NFS2ISO2NFS v0.5.2 +++++");
|
||||||
Console.WriteLine();
|
Console.WriteLine();
|
||||||
Console.WriteLine("-dec Decrypt .nfs files to an .iso file.");
|
Console.WriteLine("-dec Decrypt .nfs files to an .iso file.");
|
||||||
Console.WriteLine("-enc Encrypt an .iso file to -nfs file(s)");
|
Console.WriteLine("-enc Encrypt an .iso file to .nfs file(s)");
|
||||||
Console.WriteLine("-key <file> Location of AES key file. DEFAULT: code\\htk.bin.");
|
Console.WriteLine("-key <file> Location of AES key file. DEFAULT: code\\htk.bin.");
|
||||||
Console.WriteLine("-wiikey <file> Location of Wii Common key file. DEFAULT: wii_common_key.bin.");
|
Console.WriteLine("-wiikey <file> Location of Wii Common key file. DEFAULT: wii_common_key.bin.");
|
||||||
Console.WriteLine("-iso <file> Location of .iso file. DEFAULT: game.iso.");
|
Console.WriteLine("-iso <file> Location of .iso file. DEFAULT: game.iso.");
|
||||||
@ -123,6 +141,10 @@ namespace nfs2iso2nfs
|
|||||||
Console.WriteLine("-fwimg <file> Location of fw.img. DEFAULT: code\\fw.img.");
|
Console.WriteLine("-fwimg <file> Location of fw.img. DEFAULT: code\\fw.img.");
|
||||||
Console.WriteLine("-keep Don't delete the files produced in intermediate steps.");
|
Console.WriteLine("-keep Don't delete the files produced in intermediate steps.");
|
||||||
Console.WriteLine("-legit Don't patch fw.img to allow fakesigned content");
|
Console.WriteLine("-legit Don't patch fw.img to allow fakesigned content");
|
||||||
|
Console.WriteLine("-lrpatch Map emulated Classic Controller's L & R to Gamepad's ZL & ZR");
|
||||||
|
Console.WriteLine("-wiimote Emulate a Wii Remote instead of the Classic Controller");
|
||||||
|
Console.WriteLine("-vertical Remap Wii Remote d-pad for vertical usage (implies -wiimote)");
|
||||||
|
Console.WriteLine("-homebrew Various patches to enable proper homebrew functionality");
|
||||||
Console.WriteLine("-help Print this text.");
|
Console.WriteLine("-help Print this text.");
|
||||||
return -1;
|
return -1;
|
||||||
default:
|
default:
|
||||||
@ -138,8 +160,16 @@ namespace nfs2iso2nfs
|
|||||||
wiiKeyFile = dir + "\\" + wiiKeyFile;
|
wiiKeyFile = dir + "\\" + wiiKeyFile;
|
||||||
if (!Path.IsPathRooted(nfsDir))
|
if (!Path.IsPathRooted(nfsDir))
|
||||||
nfsDir = dir + "\\" + nfsDir;
|
nfsDir = dir + "\\" + nfsDir;
|
||||||
if (!Path.IsPathRooted(fwFile))
|
if (!Path.IsPathRooted(fw_file))
|
||||||
fwFile = dir + "\\" + fwFile;
|
fw_file = dir + "\\" + fw_file;
|
||||||
|
|
||||||
|
|
||||||
|
if (map_shoulder_to_trigger && horiz_wiimote || map_shoulder_to_trigger && vert_wiimote)
|
||||||
|
{
|
||||||
|
Console.WriteLine("ERROR: Please don't mix patches for Classic Controller and Wii Remote.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (dec || ((!dec && !enc) && File.Exists(nfsDir + "\\hif_000000.nfs")))
|
if (dec || ((!dec && !enc) && File.Exists(nfsDir + "\\hif_000000.nfs")))
|
||||||
{
|
{
|
||||||
@ -147,7 +177,7 @@ namespace nfs2iso2nfs
|
|||||||
Console.WriteLine();
|
Console.WriteLine();
|
||||||
if (dec && !enc && !File.Exists(nfsDir + "\\hif_000000.nfs"))
|
if (dec && !enc && !File.Exists(nfsDir + "\\hif_000000.nfs"))
|
||||||
{
|
{
|
||||||
Console.WriteLine(".nfs files not found! Exiting...");
|
Console.WriteLine("ERROR: .nfs files not found! Exiting...");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
else if ((!dec && !enc) && File.Exists(nfsDir + "\\hif_000000.nfs"))
|
else if ((!dec && !enc) && File.Exists(nfsDir + "\\hif_000000.nfs"))
|
||||||
@ -158,18 +188,19 @@ namespace nfs2iso2nfs
|
|||||||
enc = false;
|
enc = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (enc || (((!dec && !enc) || (!dec && !enc)) && File.Exists(isoFile)))
|
else if (enc || (((!dec && !enc) || (!dec && !enc)) && File.Exists(isoFile)))
|
||||||
{
|
{
|
||||||
Console.WriteLine("+++++ ISO2NFS +++++");
|
Console.WriteLine("+++++ ISO2NFS +++++");
|
||||||
Console.WriteLine();
|
Console.WriteLine();
|
||||||
if (!dec && enc && !File.Exists(isoFile))
|
if (!dec && enc && !File.Exists(isoFile))
|
||||||
{
|
{
|
||||||
Console.WriteLine(".iso file not found! Exiting...");
|
Console.WriteLine("ERROR: .iso file not found! Exiting...");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (!dec && enc && !File.Exists(fwFile))
|
if (!dec && enc && !File.Exists(fw_file))
|
||||||
{
|
{
|
||||||
Console.WriteLine("fw.img not found! Exiting...");
|
Console.WriteLine("ERROR: fw.img not found! Exiting...");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
else if (((dec && enc) || (!dec && !enc)) && File.Exists(isoFile))
|
else if (((dec && enc) || (!dec && !enc)) && File.Exists(isoFile))
|
||||||
@ -180,6 +211,7 @@ namespace nfs2iso2nfs
|
|||||||
enc = true;
|
enc = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Console.WriteLine("You haven't specified if you want to use nfs2iso or iso2nfs");
|
Console.WriteLine("You haven't specified if you want to use nfs2iso or iso2nfs");
|
||||||
@ -195,13 +227,13 @@ namespace nfs2iso2nfs
|
|||||||
Console.WriteLine("Searching for AES key file...");
|
Console.WriteLine("Searching for AES key file...");
|
||||||
if (!File.Exists(keyFile))
|
if (!File.Exists(keyFile))
|
||||||
{
|
{
|
||||||
Console.WriteLine("Could not find AES key file! Exiting...");
|
Console.WriteLine("ERROR: Could not find AES key file! Exiting...");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
byte[] key = getKey(keyFile);
|
byte[] key = getKey(keyFile);
|
||||||
if (key == null)
|
if (key == null)
|
||||||
{
|
{
|
||||||
Console.WriteLine("AES key file has wrong file size! Exiting...");
|
Console.WriteLine("ERROR: AES key file has wrong file size! Exiting...");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Console.WriteLine("AES key file found!");
|
Console.WriteLine("AES key file found!");
|
||||||
@ -211,18 +243,20 @@ namespace nfs2iso2nfs
|
|||||||
Console.WriteLine("Wii common key not found in source code. Looking for file...");
|
Console.WriteLine("Wii common key not found in source code. Looking for file...");
|
||||||
if (!File.Exists(wiiKeyFile))
|
if (!File.Exists(wiiKeyFile))
|
||||||
{
|
{
|
||||||
Console.WriteLine("Could not find Wii common key file! Exiting...");
|
Console.WriteLine("ERROR: Could not find Wii common key file! Exiting...");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
WII_COMMON_KEY = getKey(wiiKeyFile);
|
WII_COMMON_KEY = getKey(wiiKeyFile);
|
||||||
if (key == null)
|
if (key == null)
|
||||||
{
|
{
|
||||||
Console.WriteLine("Wii common key file has wrong file size! Exiting...");
|
Console.WriteLine("ERROR: Wii common key file has wrong file size! Exiting...");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Console.WriteLine("Wii Common Key file found!");
|
Console.WriteLine("Wii Common Key file found!");
|
||||||
}
|
}
|
||||||
else Console.WriteLine("Wii common key found in source code!");
|
else Console.WriteLine("Wii common key found in source code!");
|
||||||
|
|
||||||
|
Console.WriteLine();
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -801,47 +835,395 @@ namespace nfs2iso2nfs
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void patchFakeSigning(string fwFile)
|
public static void DoThePatching(string fw_file)
|
||||||
{
|
{
|
||||||
if (File.Exists("fw.img.tmp")) // delete any existent temp file
|
var input_ios = new MemoryStream(File.ReadAllBytes(fw_file)); //copy fw.img into a memory stream
|
||||||
|
|
||||||
|
Console.WriteLine("Checking fw.img's revision number...");
|
||||||
|
|
||||||
|
byte[] buffer_rev = new byte[4];
|
||||||
|
byte[] rev_pattern = { 0x73, 0x76, 0x6E, 0x2D }; // search for "svn-"
|
||||||
|
string revision = "";
|
||||||
|
|
||||||
|
for (int offset = 0; offset < input_ios.Length - 4; offset++)
|
||||||
{
|
{
|
||||||
File.Delete("fw.img.tmp");
|
input_ios.Position = offset; // set position to advance byte by byte
|
||||||
|
input_ios.Read(buffer_rev, 0, 4); // because we read 4 bytes at once
|
||||||
|
|
||||||
|
if (ByteArrayCompare(buffer_rev, rev_pattern)) // see if it matches
|
||||||
|
{
|
||||||
|
input_ios.Read(buffer_rev, 0, 4);
|
||||||
|
revision = System.Text.Encoding.UTF8.GetString(buffer_rev, 0, buffer_rev.Length);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
File.Copy(fwFile, "fw.img.tmp"); // create new temp file
|
|
||||||
|
|
||||||
using (var in_ios = new BinaryReader(File.OpenRead(fwFile)))
|
if (revision == "r590")
|
||||||
using (var out_ios = new BinaryWriter(File.OpenWrite(Directory.GetCurrentDirectory() + "\\fw.img.tmp")))
|
|
||||||
{
|
{
|
||||||
|
Console.WriteLine("OK, revision 590 detected.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Console.WriteLine("Warning: {0} detected. These patches are designed for revision 590 only.", revision);
|
||||||
|
}
|
||||||
Console.WriteLine();
|
Console.WriteLine();
|
||||||
Console.WriteLine("Patching fw.img to enable fakesigning...");
|
|
||||||
int patchCount = 0;
|
|
||||||
|
|
||||||
byte[] buff = new byte[4];
|
|
||||||
|
byte[] buffer_4 = new byte[4]; // buffer for 4-byte arrays
|
||||||
|
byte[] buffer_8 = new byte[8]; // buffer for 8-byte arrays
|
||||||
|
|
||||||
|
Console.WriteLine("Patching fw.img.");
|
||||||
|
if (!keepLegit)
|
||||||
|
{
|
||||||
|
Array.Clear(buffer_4, 0, 4);
|
||||||
|
int patchCount = 0;
|
||||||
byte[] oldHashCheck = { 0x20, 0x07, 0x23, 0xA2 };
|
byte[] oldHashCheck = { 0x20, 0x07, 0x23, 0xA2 };
|
||||||
byte[] newHashCheck = { 0x20, 0x07, 0x4B, 0x0B };
|
byte[] newHashCheck = { 0x20, 0x07, 0x4B, 0x0B };
|
||||||
|
|
||||||
for (int offset = 0; offset < in_ios.BaseStream.Length - 4; offset++)
|
for (int offset = 0; offset < input_ios.Length - 4; offset++)
|
||||||
{
|
{
|
||||||
in_ios.BaseStream.Position = offset; // set position to advance byte by byte
|
input_ios.Position = offset; // set position to advance byte by byte
|
||||||
buff = in_ios.ReadBytes(4); // because we read 4 bytes at once
|
input_ios.Read(buffer_4, 0, 4); // because we read 4 bytes at once
|
||||||
if (ByteArrayCompare(buff, oldHashCheck) || ByteArrayCompare(buff, newHashCheck)) // see if it matches one of the patterns
|
|
||||||
|
if (ByteArrayCompare(buffer_4, oldHashCheck) || ByteArrayCompare(buffer_4, newHashCheck)) // see if it matches one of the patterns
|
||||||
{
|
{
|
||||||
out_ios.Seek(offset + 1, SeekOrigin.Begin); // if it does, advance on byte further in
|
input_ios.Seek(offset + 1, SeekOrigin.Begin); // if it does, advance on byte further in
|
||||||
out_ios.Write((byte)0x00); // the output and write a zero
|
input_ios.WriteByte(0x00); // the output and write a zero
|
||||||
|
|
||||||
|
patchCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (patchCount == 0)
|
||||||
|
Console.WriteLine("Fakesign patching: Nothing to patch.");
|
||||||
|
else
|
||||||
|
Console.WriteLine("Fakesigning patching finished... (Patches applied: {0})", patchCount);
|
||||||
|
|
||||||
|
Console.WriteLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
//map classic controller's L & R to the gamepad's ZL & ZR
|
||||||
|
if (map_shoulder_to_trigger)
|
||||||
|
{
|
||||||
|
Array.Clear(buffer_4, 0, 4);
|
||||||
|
int patchCount = 0;
|
||||||
|
|
||||||
|
byte[] pattern1 = { 0x40, 0x05, 0x46, 0xA9 };
|
||||||
|
byte[] patch1 = { 0x26, 0x80, 0x40, 0x06 };
|
||||||
|
|
||||||
|
byte[] pattern2 = { 0x1C, 0x05, 0x40, 0x35 };
|
||||||
|
byte[] patch2 = { 0x25, 0x40, 0x40, 0x05 };
|
||||||
|
|
||||||
|
byte[] pattern3 = { 0x46, 0x53, 0x42, 0x18 };
|
||||||
|
byte[] patch3 = { 0x23, 0x10, 0x40, 0x03 };
|
||||||
|
|
||||||
|
byte[] pattern4 = { 0x1C, 0x05, 0x80, 0x22 };
|
||||||
|
byte[] patch4 = { 0x25, 0x40, 0x80, 0x22, 0x40, 0x05 };
|
||||||
|
|
||||||
|
for (int offset = 0; offset < input_ios.Length - 4; offset++)
|
||||||
|
{
|
||||||
|
input_ios.Position = offset; // set position to advance byte by byte
|
||||||
|
input_ios.Read(buffer_4, 0, 4); // because we read 4 bytes at once
|
||||||
|
|
||||||
|
if (ByteArrayCompare(buffer_4, pattern1)) // see if it matches
|
||||||
|
{
|
||||||
|
input_ios.Seek(offset, SeekOrigin.Begin); // seek
|
||||||
|
input_ios.Write(patch1, 0, 4); // and then patch
|
||||||
|
|
||||||
|
patchCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ByteArrayCompare(buffer_4, pattern2)) // see if it matches
|
||||||
|
{
|
||||||
|
input_ios.Seek(offset, SeekOrigin.Begin); // seek
|
||||||
|
input_ios.Write(patch2, 0, 4); // and then patch
|
||||||
|
|
||||||
|
patchCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ByteArrayCompare(buffer_4, pattern3)) // see if it matches
|
||||||
|
{
|
||||||
|
input_ios.Seek(offset, SeekOrigin.Begin); // seek
|
||||||
|
input_ios.Write(patch3, 0, 4); // and then patch
|
||||||
|
|
||||||
|
patchCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ByteArrayCompare(buffer_4, pattern4)) // see if it matches
|
||||||
|
{
|
||||||
|
input_ios.Seek(offset, SeekOrigin.Begin); // seek
|
||||||
|
input_ios.Write(patch4, 0, 6); // and then patch
|
||||||
|
|
||||||
patchCount++;
|
patchCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (patchCount == 0)
|
if (patchCount == 0)
|
||||||
Console.WriteLine("Nothing to patch");
|
Console.WriteLine("LR to ZLZR patching: Nothing to patch.");
|
||||||
else
|
else
|
||||||
Console.WriteLine("Patching fakesigning finished... (Patches applied: {0})", patchCount);
|
Console.WriteLine("LR to ZLZR patching finished. (Patches applied: {0})", patchCount);
|
||||||
|
|
||||||
|
Console.WriteLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//enable wii remote emulation
|
||||||
|
if (horiz_wiimote || vert_wiimote)
|
||||||
|
{
|
||||||
|
Array.Clear(buffer_8, 0, 8);
|
||||||
|
int patchCount = 0;
|
||||||
|
byte[] pattern = { 0x16, 0x13, 0x1C, 0x02, 0x40, 0x9A, 0x1C, 0x13 };
|
||||||
|
byte[] patch = { 0x23, 0x00 };
|
||||||
|
|
||||||
|
for (int offset = 0; offset < input_ios.Length - 6; offset++)
|
||||||
|
{
|
||||||
|
input_ios.Position = offset; // set position to advance byte by byte
|
||||||
|
input_ios.Read(buffer_8, 0, 8); // because we read 8 bytes at once
|
||||||
|
|
||||||
|
if (ByteArrayCompare(buffer_8, pattern)) // see if it matches
|
||||||
|
{
|
||||||
|
input_ios.Seek(offset, SeekOrigin.Begin); // seek
|
||||||
|
input_ios.Write(patch, 0, 2); // and then patch
|
||||||
|
|
||||||
|
patchCount++;
|
||||||
}
|
}
|
||||||
File.Delete(fwFile); // delete original fw.img
|
|
||||||
File.Copy("fw.img.tmp", fwFile); // replace with patched temp file
|
|
||||||
File.Delete("fw.img.tmp"); // delete temp file
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (patchCount == 0)
|
||||||
|
Console.WriteLine("Wii Remote emulation patching: Nothing to patch.");
|
||||||
|
else
|
||||||
|
Console.WriteLine("Wii Remote emulation enabled... (Patches applied: {0})", patchCount);
|
||||||
|
|
||||||
|
Console.WriteLine();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//enable horizontal wii remote emulation (remap dpad)
|
||||||
|
if (vert_wiimote)
|
||||||
|
{
|
||||||
|
Array.Clear(buffer_8, 0, 8);
|
||||||
|
int patchCount = 0;
|
||||||
|
byte[] pattern = { 0x00, 0x2B, 0x00, 0xD0, 0x00, 0x80, 0x08, 0x9A };
|
||||||
|
|
||||||
|
for (int offset = 0; offset < input_ios.Length - 8; offset++)
|
||||||
|
{
|
||||||
|
input_ios.Position = offset; // set position to advance byte by byte
|
||||||
|
input_ios.Read(buffer_8, 0, 8); // because we read 8 bytes at once
|
||||||
|
|
||||||
|
if (ByteArrayCompare(buffer_8, pattern)) // see if it matches
|
||||||
|
{
|
||||||
|
input_ios.Seek(offset, SeekOrigin.Begin);
|
||||||
|
input_ios.WriteByte(0x02); // dpad left -> down
|
||||||
|
patchCount++;
|
||||||
|
|
||||||
|
input_ios.Seek(offset + 8, SeekOrigin.Begin);
|
||||||
|
input_ios.WriteByte(0x03); // dpad right -> up
|
||||||
|
patchCount++;
|
||||||
|
|
||||||
|
input_ios.Seek(offset + 0x16, SeekOrigin.Begin);
|
||||||
|
input_ios.WriteByte(0x01); // dpad down -> right
|
||||||
|
patchCount++;
|
||||||
|
|
||||||
|
input_ios.Seek(offset + 0x24, SeekOrigin.Begin);
|
||||||
|
input_ios.WriteByte(0x00); // dpad up -> left
|
||||||
|
|
||||||
|
patchCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (patchCount == 0)
|
||||||
|
Console.WriteLine("Vertical Wii Remote patching: Nothing to patch.");
|
||||||
|
else
|
||||||
|
Console.WriteLine("Vertical Wii Remote emulation enabled... (Patches applied: {0})", patchCount);
|
||||||
|
|
||||||
|
Console.WriteLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// enable proper input support in homebrew
|
||||||
|
if (homebrew)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Homebrew-related patches:");
|
||||||
|
Array.Clear(buffer_4, 0, 4);
|
||||||
|
Array.Clear(buffer_8, 0, 8);
|
||||||
|
int patchCount = 0;
|
||||||
|
|
||||||
|
|
||||||
|
//wiimote passthrough
|
||||||
|
byte[] pattern_passthrough = { 0x20, 0x4B, 0x01, 0x68, 0x18, 0x47, 0x70, 0x00 };
|
||||||
|
byte[] patch_passthrough = { 0x20, 0x00 };
|
||||||
|
|
||||||
|
for (int offset = 0; offset < input_ios.Length - 8; offset++)
|
||||||
|
{
|
||||||
|
input_ios.Position = offset; // set position to advance byte by byte
|
||||||
|
input_ios.Read(buffer_8, 0, 8); // because we read 8 bytes at once
|
||||||
|
|
||||||
|
if (ByteArrayCompare(buffer_8, pattern_passthrough)) // if it matches
|
||||||
|
{
|
||||||
|
Console.WriteLine("* Enabling Wii Remote passthrough...");
|
||||||
|
input_ios.Seek(offset + 3, SeekOrigin.Begin); // seek to offset
|
||||||
|
input_ios.Write(patch_passthrough, 0, 2); // and then patch
|
||||||
|
|
||||||
|
patchCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// the custom function
|
||||||
|
byte[] pattern_custom_func = { 0x28, 0x00, 0xD0, 0x03, 0x49, 0x02, 0x22, 0x09 };
|
||||||
|
byte[] patch_custom_func = { 0xF0, 0x04, 0xFF, 0x21, 0x48, 0x02, 0x21, 0x09, 0xF0, 0x04, 0xFE, 0xF9 };
|
||||||
|
|
||||||
|
for (int offset = 0; offset < input_ios.Length - 8; offset++)
|
||||||
|
{
|
||||||
|
input_ios.Position = offset; // set position to advance byte by byte
|
||||||
|
input_ios.Read(buffer_8, 0, 8); // because we read 8 bytes at once
|
||||||
|
|
||||||
|
if (ByteArrayCompare(buffer_8, pattern_custom_func)) // if it matches
|
||||||
|
{
|
||||||
|
Console.WriteLine("* Writing custom function...");
|
||||||
|
input_ios.Seek(offset, SeekOrigin.Begin); // seek to offset
|
||||||
|
input_ios.Write(patch_custom_func, 0, 12); // and then patch
|
||||||
|
|
||||||
|
patchCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// call custom function
|
||||||
|
byte[] pattern_custom_call = { 0xF0, 0x01, 0xFA, 0xB9 };
|
||||||
|
byte[] patch_custom_call = { 0xF7, 0xFC, 0xFB, 0x95 };
|
||||||
|
|
||||||
|
for (int offset = 0; offset < input_ios.Length - 4; offset++)
|
||||||
|
{
|
||||||
|
input_ios.Position = offset; // set position to advance byte by byte
|
||||||
|
input_ios.Read(buffer_4, 0, 4); // because we read 4 bytes at once
|
||||||
|
|
||||||
|
if (ByteArrayCompare(buffer_4, pattern_custom_call)) // if it matches
|
||||||
|
{
|
||||||
|
Console.WriteLine("* Writing call to the custom function...");
|
||||||
|
input_ios.Seek(offset, SeekOrigin.Begin); // seek to offset
|
||||||
|
input_ios.Write(patch_custom_call, 0, 4); // and then patch
|
||||||
|
|
||||||
|
patchCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// disable AHBPROT
|
||||||
|
byte[] pattern_ahbprot = { 0x20, 0x00, 0xF0, 0x04, 0xFB, 0x2B, 0x48, 0x29 };
|
||||||
|
byte[] patch_ahbprot = { 0x20, 0x01 };
|
||||||
|
|
||||||
|
for (int offset = 0; offset < input_ios.Length - 8; offset++)
|
||||||
|
{
|
||||||
|
input_ios.Position = offset; // set position to advance byte by byte
|
||||||
|
input_ios.Read(buffer_8, 0, 8); // because we read 8 bytes at once
|
||||||
|
|
||||||
|
if (ByteArrayCompare(buffer_8, pattern_ahbprot)) // see if it matches
|
||||||
|
{
|
||||||
|
Console.WriteLine("* Disabling AHBPROT...");
|
||||||
|
input_ios.Seek(offset, SeekOrigin.Begin); // seek to offset
|
||||||
|
input_ios.Write(patch_ahbprot, 0, 2); // and then patch
|
||||||
|
|
||||||
|
patchCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//disable MEMPROT
|
||||||
|
byte[] pattern_memprot = { 0x0D, 0x80, 0x01, 0x94, 0xB5, 0x00, 0x4B, 0x08 };
|
||||||
|
byte[] patch_memprot = { 0x22, 0x00 };
|
||||||
|
|
||||||
|
for (int offset = 0; offset < input_ios.Length - 8; offset++)
|
||||||
|
{
|
||||||
|
input_ios.Position = offset; // set position to advance byte by byte
|
||||||
|
input_ios.Read(buffer_8, 0, 8); // because we read 8 bytes at once
|
||||||
|
|
||||||
|
if (ByteArrayCompare(buffer_8, pattern_memprot)) // see if it matches
|
||||||
|
{
|
||||||
|
Console.WriteLine("* Disabling MEMPROT...");
|
||||||
|
input_ios.Seek(offset + 8, SeekOrigin.Begin); // seek to offset
|
||||||
|
input_ios.Write(patch_memprot, 0, 2); // and then patch
|
||||||
|
|
||||||
|
patchCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// nintendont 1
|
||||||
|
byte[] pattern_nintendont_1 = { 0xB0, 0xBA, 0x1C, 0x0F };
|
||||||
|
byte[] patch_nintendont_1 = { 0xE5, 0x9F, 0x10, 0x04, 0xE5, 0x91, 0x00, 0x00, 0xE1, 0x2F, 0xFF, 0x10, 0x12, 0xFF, 0xFF, 0xE0 };
|
||||||
|
for (int offset = 0; offset < input_ios.Length - 4; offset++)
|
||||||
|
{
|
||||||
|
input_ios.Position = offset; // set position to advance byte by byte
|
||||||
|
input_ios.Read(buffer_4, 0, 4); // because we read 4 bytes at once
|
||||||
|
|
||||||
|
if (ByteArrayCompare(buffer_4, pattern_nintendont_1)) // if it matches
|
||||||
|
{
|
||||||
|
Console.WriteLine("* Nintendont patch 1...");
|
||||||
|
input_ios.Seek(offset - 12, SeekOrigin.Begin); // seek to offset
|
||||||
|
input_ios.Write(patch_nintendont_1, 0, 16); // and then patch
|
||||||
|
|
||||||
|
patchCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//nintendont 2
|
||||||
|
byte[] pattern_nintendont_2 = { 0x68, 0x4B, 0x2B, 0x06 };
|
||||||
|
byte[] patch_nintendont_2 = { 0x49, 0x01, 0x47, 0x88, 0x46, 0xC0, 0xE0, 0x01, 0x12, 0xFF, 0xFE, 0x00, 0x22, 0x00, 0x23, 0x01, 0x46, 0xC0, 0x46, 0xC0 };
|
||||||
|
for (int offset = 0; offset < input_ios.Length - 4; offset++)
|
||||||
|
{
|
||||||
|
input_ios.Position = offset; // set position to advance byte by byte
|
||||||
|
input_ios.Read(buffer_4, 0, 4); // because we read 4 bytes at once
|
||||||
|
|
||||||
|
if (ByteArrayCompare(buffer_4, pattern_nintendont_2)) // if it matches
|
||||||
|
{
|
||||||
|
Console.WriteLine("* Nintendont patch 2...");
|
||||||
|
input_ios.Seek(offset, SeekOrigin.Begin); // seek to offset
|
||||||
|
input_ios.Write(patch_nintendont_2, 0, 20); // and then patch
|
||||||
|
|
||||||
|
patchCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//nintendont 3
|
||||||
|
byte[] pattern_nintendont_3 = { 0x0D, 0x80, 0x00, 0x00, 0x0D, 0x80, 0x00, 0x00 };
|
||||||
|
byte[] patch_nintendont_3 = { 0x0D, 0x80, 0x00, 0x00, 0x0D, 0x80, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00 };
|
||||||
|
for (int offset = 0; offset < input_ios.Length - 8; offset++)
|
||||||
|
{
|
||||||
|
input_ios.Position = offset; // set position to advance byte by byte
|
||||||
|
input_ios.Read(buffer_8, 0, 8); // because we read 8 bytes at once
|
||||||
|
|
||||||
|
if (ByteArrayCompare(buffer_8, pattern_nintendont_3)) // if it matches
|
||||||
|
{
|
||||||
|
Console.WriteLine("* Nintendont patch 3...");
|
||||||
|
input_ios.Seek(offset, SeekOrigin.Begin); // seek to offset
|
||||||
|
input_ios.Write(patch_nintendont_3, 0, 24); // and then patch
|
||||||
|
|
||||||
|
patchCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (patchCount == 0)
|
||||||
|
Console.WriteLine("Homebrew patching: Nothing to patch.");
|
||||||
|
else
|
||||||
|
Console.WriteLine("Homebrew patching finished... (Patches applied: {0})", patchCount);
|
||||||
|
|
||||||
|
Console.WriteLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
// write to disk
|
||||||
|
//FileStream patched_file = File.OpenWrite("newfw.img"); // for testing
|
||||||
|
FileStream patched_file = File.OpenWrite(fw_file); // open file
|
||||||
|
input_ios.WriteTo(patched_file); // write
|
||||||
|
patched_file.Close();
|
||||||
|
input_ios.Close();
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user