diff --git a/AssetStudio/FileReader.cs b/AssetStudio/FileReader.cs index 23bba92..1c71473 100644 --- a/AssetStudio/FileReader.cs +++ b/AssetStudio/FileReader.cs @@ -200,6 +200,9 @@ namespace AssetStudio case GameType.AliceGearAegis: reader = DecryptAliceGearAegis(reader); break; + case GameType.ProjectSekai: + reader = DecryptProjectSekai(reader); + break; } } if (reader.FileType == FileType.BundleFile && game.Type.IsBlockFile() || reader.FileType == FileType.ENCRFile || reader.FileType == FileType.BlbFile) diff --git a/AssetStudio/GameManager.cs b/AssetStudio/GameManager.cs index b2fe92c..a5866e2 100644 --- a/AssetStudio/GameManager.cs +++ b/AssetStudio/GameManager.cs @@ -37,6 +37,7 @@ namespace AssetStudio Games.Add(index++, new Game(GameType.DreamscapeAlbireo)); Games.Add(index++, new Game(GameType.ImaginaryFest)); Games.Add(index++, new Game(GameType.AliceGearAegis)); + Games.Add(index++, new Game(GameType.ProjectSekai)); } public static Game GetGame(GameType gameType) => GetGame((int)gameType); public static Game GetGame(int index) @@ -145,6 +146,7 @@ namespace AssetStudio DreamscapeAlbireo, ImaginaryFest, AliceGearAegis, + ProjectSekai } public static class GameTypes diff --git a/AssetStudio/ImportHelper.cs b/AssetStudio/ImportHelper.cs index fea6367..740d7ad 100644 --- a/AssetStudio/ImportHelper.cs +++ b/AssetStudio/ImportHelper.cs @@ -798,5 +798,43 @@ namespace AssetStudio return new FileReader(reader.FullPath, ms); } + + public static FileReader DecryptProjectSekai(FileReader reader) + { + Logger.Verbose($"Attempting to decrypt file {reader.FileName} with Project Sekai encryption"); + + var key = new byte[] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00 }; + + reader.Endian = EndianType.LittleEndian; + var version = reader.ReadUInt32(); + + if (version != 0x10 && version != 0x20) + { + reader.Endian = EndianType.BigEndian; + reader.Position = 0; + return reader; + } + + MemoryStream ms = new MemoryStream(); + if (version == 0x10) + { + var buffer = (stackalloc byte[8]); + for (int i = 0; i < 0x10; i++) + { + var read = reader.Read(buffer); + for (int j = 0; j < key.Length; j++) + { + buffer[j] ^= key[j]; + } + ms.Write(buffer[..read]); + } + } + + ms.Write(reader.ReadBytes((int)reader.Remaining)); + + Logger.Verbose("Decrypted Project Sekai file successfully !!"); + ms.Position = 0; + return new FileReader(reader.FullPath, ms); + } } }