static void Main(string[] args) { // Check if enough args were passed if (args.Length != 2) { Console.WriteLine("NisasystSharp <game path> <file path>"); Console.WriteLine("Example: NisasystSharp Mush/ActorDb.release.byml C:\\Blitz\\ActorDb.Release.byml"); return; } using (FileStream fileStream = new FileStream(args[1], FileMode.Open)) using (StreamReader streamReader = new StreamReader(fileStream)) { // Test the file length if (fileStream.Length <= 8) { // This can't be a valid file Console.WriteLine("The file is too small to be a nisasyst container"); return; } // Seek to the magic numbers fileStream.Seek(-8, SeekOrigin.End); // Verify the magic numbers if (streamReader.ReadToEnd() != MagicNumbers) { // This isn't a valid file Console.WriteLine("This file isn't a nisasyst container"); return; } // Generate a CRC32 over the game path Crc32 crc32 = new Crc32(); uint seed = crc32.Get(Encoding.ASCII.GetBytes(args[0])); // Create a new SeadRandom instance using the seed SeadRandom seadRandom = new SeadRandom(seed); // Create the encryption key and IV byte[] encryptionKey = CreateSequence(seadRandom); byte[] iv = CreateSequence(seadRandom); using (MemoryStream memoryStream = new MemoryStream()) using (AesManaged cryptor = new AesManaged()) { cryptor.Mode = CipherMode.CBC; cryptor.Padding = PaddingMode.PKCS7; cryptor.KeySize = 128; cryptor.BlockSize = 128; using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptor.CreateDecryptor(encryptionKey, iv), CryptoStreamMode.Write)) { // Seek to the beginning of the file fileStream.Seek(0, SeekOrigin.Begin); // Copy the encrypted data CopyStream(fileStream, cryptoStream, (int)fileStream.Length - 8); } // Write out the new file File.WriteAllBytes(args[1] + ".decrypted", memoryStream.ToArray()); Console.WriteLine("Wrote decrypted file"); } } }