Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.IO;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- namespace nfs2iso
- {
- class Program
- {
- public const int SECTOR_SIZE = 0x8000;
- public const int HEADER_SIZE = 0x200;
- public static readonly byte[] VWII_COMMON_KEY = !!!!ADD THIS YOURSELF!!!
- public static readonly byte[] WII_COMMON_KEY = !!!!ADD THIS YOURSELF!!!
- static void Main(string[] args)
- {
- Console.WriteLine();
- string dir = Directory.GetCurrentDirectory();
- string folder = new DirectoryInfo(dir).Name;
- if (folder.Length != 7 || String.Compare("content", 0, folder, 0, 7, false) != 0)
- {
- Console.WriteLine("Wrong directory! Place this program in the 'content' folder.");
- return;
- }
- Console.WriteLine("Searching for key file...");
- string keyDir = Directory.GetParent(dir)+"\\code"+"\\htk.bin";
- if (!File.Exists(keyDir))
- {
- Console.WriteLine("Could not find the file ..\\code\\htk.bin.");
- return;
- }
- byte[] key = getKey(keyDir);
- if (key == null)
- {
- Console.WriteLine("..\\code\\htk.bin has wrong file size.");
- return;
- }
- Console.WriteLine("Key file found!");
- Console.WriteLine("Looking for .nfs files...");
- int nfsNo = -1;
- while (File.Exists(dir + "\\hif_" + String.Format("{0:D6}", nfsNo + 1) + ".nfs"))
- {
- nfsNo++;
- }
- Console.WriteLine((nfsNo + 1) + " .nfs files found!");
- Console.WriteLine("Joining .nfs files...");
- Console.WriteLine();
- combineNFSFiles(nfsNo);
- string InFile = "hif.nfs";
- string OutFile = "hif_dec.nfs";
- byte[] iv = buildZero(key.Length);
- DecryptNFS(InFile, OutFile, key, iv);
- InFile = "hif_dec.nfs";
- OutFile = "hif_dec.iso";
- manipulateISO(InFile, OutFile);
- }
- public static byte[] getKey(string keyDir)
- {
- using (var keyFile = new BinaryReader(File.OpenRead(keyDir)))
- {
- long keySize = keyFile.BaseStream.Length;
- if (keySize != 16)
- return null;
- return keyFile.ReadBytes(0x10);
- }
- }
- public static byte[] buildZero(int size)
- {
- byte[] iv = new byte[size];
- for (int i = 0; i < size; i++)
- iv[i] = 0;
- return iv;
- }
- public static void combineNFSFiles(int size)
- {
- using (var nfs = new BinaryWriter(File.OpenWrite("hif.nfs")))
- {
- for (int i = 0; i <= size; i++)
- {
- Console.WriteLine("Processing hif_" + String.Format("{0:D6}", i) + ".nfs...");
- var nfsTemp = new BinaryReader(File.OpenRead(Directory.GetCurrentDirectory() + "\\hif_" + String.Format("{0:D6}", i) + ".nfs"));
- byte[] file = new byte[nfsTemp.BaseStream.Length];
- long NFSsize = nfsTemp.BaseStream.Length;
- if (i == 0)
- {
- nfsTemp.ReadBytes(HEADER_SIZE);
- NFSsize -= HEADER_SIZE;
- }
- nfs.Write(nfsTemp.ReadBytes((int)NFSsize));
- }
- }
- }
- public static void DecryptNFS(string InFile, string OutFile, byte[] key, byte[] iv)
- {
- using (var er = new BinaryReader(File.OpenRead(InFile)))
- using (var ew = new BinaryWriter(File.OpenWrite(OutFile)))
- {
- Console.WriteLine();
- Console.WriteLine("Decrypting hif.nfs...");
- Console.WriteLine();
- byte[] Sector = new byte[SECTOR_SIZE];
- int timer = 0;
- int i = 0;
- //init size
- long leftSize = er.BaseStream.Length;
- do
- {
- if (timer == 8000)
- {
- timer = 0;
- i++;
- Console.WriteLine((i * 256)+ " MB processed...");
- }
- timer++;
- //read encrypted sector
- Sector = er.ReadBytes(leftSize > SECTOR_SIZE ? SECTOR_SIZE : (int)leftSize);
- //decrypt it, note: this is needed to reset iv
- Sector = aes_128_cbc_dec(key, iv, Sector);
- //write it to outfile
- ew.Write(Sector);
- //decrease remaining size
- leftSize -= SECTOR_SIZE;
- //loop till end of file
- } while (leftSize > 0);
- }
- }
- public static void manipulateISO(string InFile, string OutFile)
- {
- using (var er = new BinaryReader(File.OpenRead(InFile)))
- using (var ew = new BinaryWriter(File.OpenWrite(OutFile)))
- {
- Console.WriteLine("Write file...");
- ew.Write(er.ReadBytes(0x8000));
- byte[] partitionTable = er.ReadBytes(0x400);
- ew.Write(buildZero(0x400));
- ew.Write(er.ReadBytes(0xDC00));
- byte[] regionSettings = er.ReadBytes(0x20);
- ew.Write(buildZero(0x20));
- ew.Write(er.ReadBytes(0x1FDC));
- byte[] magicBytes = er.ReadBytes(0x4);
- ew.Write(buildZero(0x4));
- ew.Write(buildZero(0x28000));
- Console.WriteLine("Write partition table...");
- ew.Write(partitionTable);
- ew.Write(buildZero(0xDC00));
- Console.WriteLine("Write region settings...");
- ew.Write(regionSettings);
- ew.Write(buildZero(0x1FDC));
- Console.WriteLine("Write magic bytes...");
- ew.Write(magicBytes);
- Console.WriteLine("Write zeros...");
- ew.Write(buildZero(0xF7B0000));
- ew.Write(er.ReadBytes(0x1BE)); //Write start of partiton
- byte[] enc_titlekey = er.ReadBytes(0x10); //read encrypted titlekey
- ew.Write(enc_titlekey); //Write encrypted titlekey
- ew.Write(er.ReadBytes(0xD)); //Write bytes till titleID
- byte[] titleID = er.ReadBytes(0x8); //read titleID
- ew.Write(titleID); //WritetitleID
- byte[] IV = new byte[0x10]; //build IV
- for (int i = 0; i <= 15; i++)
- if (i < 8)
- IV[i] = titleID[i];
- else IV[i] = 0x0;
- ew.Write(er.ReadBytes(0xC1)); //Write bytes till end of ticket
- ew.Write(er.ReadBytes(0x1FD5C)); //Write bytes till start of partition data
- byte[] titlekey = aes_128_cbc_dec(WII_COMMON_KEY, IV, enc_titlekey);
- Console.WriteLine("Write game partition...");
- IV = buildZero(0x10);
- long size = er.BaseStream.Length - 0x50000;
- byte[] Sector = new byte[SECTOR_SIZE];
- while (size >= SECTOR_SIZE)
- {
- Sector = er.ReadBytes(SECTOR_SIZE);
- Sector = aes_128_cbc_enc(titlekey, IV, Sector);
- ew.Write(Sector);
- size -= SECTOR_SIZE;
- }
- Sector = er.ReadBytes((int)size);
- Sector = aes_128_cbc_enc(titlekey, IV, Sector);
- ew.Write(Sector);
- }
- }
- public static byte[] aes_128_cbc_dec(byte[] key, byte[] iv, byte[] data)
- {
- byte[] result = new byte[data.Length];
- try
- {
- System.Security.Cryptography.RijndaelManaged rm = new System.Security.Cryptography.RijndaelManaged();
- rm.Mode = System.Security.Cryptography.CipherMode.CBC;
- rm.Padding = System.Security.Cryptography.PaddingMode.None;
- rm.KeySize = 128;
- rm.BlockSize = 128;
- rm.Key = key;
- rm.IV = iv;
- using (System.Security.Cryptography.ICryptoTransform itc = rm.CreateDecryptor())
- {
- result = itc.TransformFinalBlock(data, 0, data.Length);
- }
- rm.Clear();
- return result;
- }
- catch (System.Security.Cryptography.CryptographicException e)
- {
- Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);
- return null;
- }
- }
- public static byte[] aes_128_cbc_enc(byte[] key, byte[] iv, byte[] data)
- {
- byte[] result = new byte[data.Length];
- try
- {
- System.Security.Cryptography.RijndaelManaged rm = new System.Security.Cryptography.RijndaelManaged();
- rm.Mode = System.Security.Cryptography.CipherMode.CBC;
- rm.Padding = System.Security.Cryptography.PaddingMode.None;
- rm.KeySize = 128;
- rm.BlockSize = 128;
- rm.Key = key;
- rm.IV = iv;
- using (System.Security.Cryptography.ICryptoTransform itc = rm.CreateEncryptor())
- {
- result = itc.TransformFinalBlock(data, 0, data.Length);
- }
- rm.Clear();
- return result;
- }
- catch (System.Security.Cryptography.CryptographicException e)
- {
- Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);
- return null;
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement