diff --git a/AssetStudio/FileReader.cs b/AssetStudio/FileReader.cs index d566aed..aababd7 100644 --- a/AssetStudio/FileReader.cs +++ b/AssetStudio/FileReader.cs @@ -206,6 +206,9 @@ namespace AssetStudio case GameType.CodenameJump: reader = DecryptCodenameJump(reader); break; + case GameType.GirlsFrontline: + reader = DecryptGirlsFrontline(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 8eebba1..ea3ccd0 100644 --- a/AssetStudio/GameManager.cs +++ b/AssetStudio/GameManager.cs @@ -39,6 +39,7 @@ namespace AssetStudio Games.Add(index++, new Game(GameType.AliceGearAegis)); Games.Add(index++, new Game(GameType.ProjectSekai)); Games.Add(index++, new Game(GameType.CodenameJump)); + Games.Add(index++, new Game(GameType.GirlsFrontline)); } public static Game GetGame(GameType gameType) => GetGame((int)gameType); public static Game GetGame(int index) @@ -148,7 +149,8 @@ namespace AssetStudio ImaginaryFest, AliceGearAegis, ProjectSekai, - CodenameJump + CodenameJump, + GirlsFrontline } public static class GameTypes diff --git a/AssetStudio/ImportHelper.cs b/AssetStudio/ImportHelper.cs index 6b8f2cc..9cd6e71 100644 --- a/AssetStudio/ImportHelper.cs +++ b/AssetStudio/ImportHelper.cs @@ -869,5 +869,34 @@ namespace AssetStudio ms.Position = 0; return new FileReader(reader.FullPath, ms); } + + public static FileReader DecryptGirlsFrontline(FileReader reader) + { + Logger.Verbose($"Attempting to decrypt file {reader.FileName} with Girls Frontline encryption"); + + var originalHeader = new byte[] { 0x55, 0x6E, 0x69, 0x74, 0x79, 0x46, 0x53, 0x00, 0x00, 0x00, 0x00, 0x07, 0x35, 0x2E, 0x78, 0x2E }; + + MemoryStream ms = new(); + var key = reader.ReadBytes(0x10); + for (int i = 0; i < key.Length; i++) + { + var b = (byte)(key[i] ^ originalHeader[i]); + key[i] = b != originalHeader[i] ? b : originalHeader[i]; + } + + var data = reader.ReadBytes((int)reader.Remaining); + var size = Math.Min(data.Length, 0x8000); + for (int i = 0; i < size; i++) + { + data[i] ^= key[i % key.Length]; + } + + Logger.Verbose("Decrypted Girls Frontline file successfully !!"); + + ms.Write(originalHeader); + ms.Write(data); + ms.Position = 0; + return new FileReader(reader.FullPath, ms); + } } }