diff --git a/ChovySign-CLI/Program.cs b/ChovySign-CLI/Program.cs index 23e5bf6..c6b40bd 100644 --- a/ChovySign-CLI/Program.cs +++ b/ChovySign-CLI/Program.cs @@ -6,6 +6,10 @@ using LibChovy.VersionKey; using System.Text; using Vita.ContentManager; using PspCrypto; +using Li.Utilities; +using System.Security.Cryptography; +using static PspCrypto.SceNpDrm; +using System.Runtime.InteropServices; namespace ChovySign_CLI { @@ -105,6 +109,7 @@ namespace ChovySign_CLI if(rif.AccountId != accountId) { Error(rif.ContentId + " account id does not match: " + accountId.ToString("X") + " (was " + rif.AccountId.ToString("X") + ")", 10); continue; } string[] keys = new string[4]; + for (int i = 0; i < keys.Length; i++) keys[i] = BitConverter.ToString(ActRifMethod.GetVersionKey(actDat, rif.Rif, idps, i).VersionKey).Replace("-", ""); @@ -112,7 +117,7 @@ namespace ChovySign_CLI string keysTxt = String.Join(' ', keysTxtLine); addKeys.AppendLine(keysTxt); - Console.WriteLine(keysTxt); + //Console.WriteLine(keysTxt); } File.AppendAllText("KEYS.TXT", addKeys.ToString()); } @@ -143,8 +148,8 @@ namespace ChovySign_CLI drmInfo = new NpDrmInfo(StringToByteArray(parameters[0]), parameters[1], int.Parse(parameters[2])); break; case ArgumentParsingMode.VERSIONKEY_EXTRACT: - if (parameters.Count != 1) return Error("--vkey-extract: expect 1 arguments. ("+parameters.Count+" given)", 4); - drmInfo = EbootPbpMethod.GetVersionKey(File.OpenRead(parameters[0])); + if (parameters.Count != 2) return Error("--vkey-extract: expect 2 arguments. ("+parameters.Count+" given)", 4); + drmInfo = EbootPbpMethod.GetVersionKey(File.OpenRead(parameters[0]), int.Parse(parameters[1])); break; case ArgumentParsingMode.VERSIONKEY_GENERATOR: if(parameters.Count != 4) return Error("--vkey-gen: expect 4 arguments. ("+parameters.Count+" given)", 4); @@ -192,9 +197,58 @@ namespace ChovySign_CLI parameters.Clear(); return 0; } + + public static void generateRif(byte[] idps, byte[] actBuf, byte[] versionKey, int versionKeyType, ulong accountId, string contentId) + { + byte[] vkey2 = new byte[versionKey.Length]; + Array.Copy(versionKey, vkey2, versionKey.Length); + + byte[] rkey = Rng.RandomBytes(0x10); + int keyId = 0x10; // (Int32)(Rng.RandomUInt() % 0x80); + Array.ConstrainedCopy(BitConverter.GetBytes(keyId).Reverse().ToArray(), 0, rkey, 0xC, 0x4); + + byte[] encKey1 = new byte[0x10]; + AesHelper.AesEncrypt(rkey, encKey1, KeyVault.drmRifKey); + + // get the act key + byte[] actKey = new byte[0x10]; + + SceNpDrm.SetPSID(idps); + SceNpDrm.Aid = accountId; + + Act act = MemoryMarshal.AsRef(actBuf); + GetActKey(actKey, act.PrimKeyTable[(keyId * 0x10)..], 1); + + // reverse version key back to main version key + sceNpDrmTransformVersionKey(vkey2, versionKeyType, 0); + + byte[] encKey2 = new byte[0x10]; + AesHelper.AesEncrypt(vkey2, encKey2, actKey); + + using (MemoryStream rifStream = new MemoryStream()) + { + StreamUtil rifUtil = new StreamUtil(rifStream); + + rifUtil.WriteInt16(0x0); + rifUtil.WriteInt16(0x1); + + rifUtil.WriteInt32(0x2); + rifUtil.WriteUInt64(accountId); + + rifUtil.WriteStrWithPadding(contentId, 0x00, 0x30); + + rifUtil.WriteBytes(encKey1); // enckey1 + rifUtil.WriteBytes(encKey2); // enckey2 + + rifUtil.WriteUInt64(SceRtc.ksceRtcGetCurrentSecureTick()); + rifUtil.WriteUInt64(0x00); // expiry + + rifUtil.WritePadding(0xFF, 0x28); + } + } + public static int Main(string[] args) { - if (args.Length == 0) { Console.WriteLine("Chovy-Sign v2 (CLI)"); @@ -211,7 +265,7 @@ namespace ChovySign_CLI Console.WriteLine("--output-folder [output_folder]"); Console.WriteLine("--vkey [versionkey] [contentid] [key_index]"); - Console.WriteLine("--vkey-extract [eboot.pbp]"); + Console.WriteLine("--vkey-extract [eboot.pbp] [key_index]"); Console.WriteLine("--vkey-gen [act.dat] [license.rif] [console_id] [key_index]"); Console.WriteLine("--keys-txt-gen [act.dat] [console_id] [psp_license_folder]"); diff --git a/ChovySign-GUI/ChovySign-GUI.csproj b/ChovySign-GUI/ChovySign-GUI.csproj index 3c52a58..1f0c11c 100644 --- a/ChovySign-GUI/ChovySign-GUI.csproj +++ b/ChovySign-GUI/ChovySign-GUI.csproj @@ -16,8 +16,6 @@ - - @@ -25,8 +23,7 @@ - - + diff --git a/ChovySign-GUI/Global/KeySelector.axaml.cs b/ChovySign-GUI/Global/KeySelector.axaml.cs index 1931c1b..58b8a3d 100644 --- a/ChovySign-GUI/Global/KeySelector.axaml.cs +++ b/ChovySign-GUI/Global/KeySelector.axaml.cs @@ -153,19 +153,19 @@ namespace ChovySign_GUI.Global break; case VersionKeyMethod.EBOOT_PBP_METHOD: CmaBackupPicker ebootBackupSelector = new CmaBackupPicker(); - ebootBackupSelector.BackupType = ((keyIndex == 1) ? "PSGAME" : "PGAME"); + ebootBackupSelector.BackupType = new string[] { "PGAME", "PSGAME" }; string? gameBackupFolder = await ebootBackupSelector.ShowDialog(currentWindow); string accountId = ebootBackupSelector.AccountId; if (gameBackupFolder is null) break; if (accountId == "") break; - key = CMAVersionKeyHelper.GetKeyFromGamePsvimg(gameBackupFolder, accountId); + key = CMAVersionKeyHelper.GetKeyFromGamePsvimg(gameBackupFolder, accountId, this.keyIndex); rif = CMAVersionKeyHelper.GetRifFromLicensePsvimg(gameBackupFolder, accountId); break; case VersionKeyMethod.KEYS_TXT_METHOD: CmaBackupPicker pspLicenseBackupSelector = new CmaBackupPicker(); - pspLicenseBackupSelector.BackupType = "PGAME"; + pspLicenseBackupSelector.BackupType = new string[] { "PGAME", "PSGAME" }; pspLicenseBackupSelector.Filter = KeysTxtMethod.TitleIds; gameBackupFolder = await pspLicenseBackupSelector.ShowDialog(currentWindow); @@ -186,10 +186,8 @@ namespace ChovySign_GUI.Global if (key is not null) { if (key.KeyIndex != this.keyIndex) - { - await MessageBox.Show(currentWindow, "VersionKey obtained, but had keyindex: " + key.KeyIndex + " however keyindex " + this.keyIndex + " was required.", "KeyIndex mismatch!", MessageBoxButtons.Ok); - return; - } + sceNpDrmTransformVersionKey(key.VersionKey, key.KeyIndex, this.keyIndex); + // its a revoolution~ VersionKey = key.VersionKey; } diff --git a/ChovySign-GUI/Popup/Global/CmaBackupPicker.axaml.cs b/ChovySign-GUI/Popup/Global/CmaBackupPicker.axaml.cs index a9e4701..671169f 100644 --- a/ChovySign-GUI/Popup/Global/CmaBackupPicker.axaml.cs +++ b/ChovySign-GUI/Popup/Global/CmaBackupPicker.axaml.cs @@ -3,7 +3,8 @@ using Avalonia.Interactivity; using ChovySign_GUI.Global; using GameBuilder.Psp; using LibChovy.Config; -using Org.BouncyCastle.Utilities.Bzip2; +using Org.BouncyCastle.Asn1; +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -16,7 +17,7 @@ namespace ChovySign_GUI.Popup.Global private const string lookingInLabelText = "Looking in: "; private string[]? gameDirectories; - private string backupSubFolder = ""; + private string[] backupSubFolders; private string[]? filter; @@ -69,50 +70,80 @@ namespace ChovySign_GUI.Popup.Global } } - private string accountIdSearchFolder + private string[] accountIdSearchFolders { get { - string searchIn = Path.Combine(BackupDir, this.BackupType); + string[] searchIn = new string[this.BackupType.Length]; + for (int i = 0; i < this.BackupType.Length; i++) + { + searchIn[i] = Path.Combine(BackupDir, this.BackupType[i]); + } + return searchIn; } } - private string backupSearchFolder + private string[] backupSearchFolders { get { - if (AccountId == "") return accountIdSearchFolder; - return Path.Combine(accountIdSearchFolder, AccountId); + string[] backupFolders = new string[this.BackupType.Length]; + string[] searchFolders = this.accountIdSearchFolders; + for (int i = 0; i < this.BackupType.Length; i++) + { + if (this.AccountId == "") backupFolders[i] = searchFolders[i]; + backupFolders[i] = Path.Combine(searchFolders[i], this.AccountId); + } + return backupFolders; } } - public string BackupType + public string[] BackupType { get { - return backupSubFolder; + return backupSubFolders; } set { - backupSubFolder = value; - lookingInLbl.Content = lookingInLabelText + backupSubFolder; + backupSubFolders = value; + lookingInLbl.Content = lookingInLabelText + String.Join(", ", backupSubFolders); reloadAccountIdsList(); reloadBackupsList(); } } + private string[] GetAllDriectories(string[] dirList) + { + List foundDir = new List(); + + foreach(string dirSearch in dirList) + { + if (!Directory.Exists(dirSearch)) continue; + foreach(string dir in Directory.GetDirectories(dirSearch)) + { + if (!foundDir.Contains(dir)) + { + foundDir.Add(dir); + } + } + } + + return foundDir.ToArray(); + } + private void reloadAccountIdsList() { try { - string[] usedAccountIds = Directory.GetDirectories(accountIdSearchFolder); + string[] usedAccountIds = GetAllDriectories(accountIdSearchFolders); List accountIdLst = new List(); foreach (string accountId in usedAccountIds) { string aid = Path.GetFileName(accountId); + if (accountIdLst.Contains(aid)) continue; if (aid.Length != 16) continue; accountIdLst.Add(aid); - } this.accId.Items = accountIdLst.ToArray(); @@ -142,8 +173,8 @@ namespace ChovySign_GUI.Popup.Global this.backupList.Items = new string[0]; try { - if(!Directory.Exists(backupSearchFolder)) { return; } - string[] gameBackupDirectories = Directory.GetDirectories(backupSearchFolder); + string[] gameBackupDirectories = GetAllDriectories(backupSearchFolders); + List filteredGameDirectories = new List(); List gameList = new List(); foreach (string gameDirectory in gameBackupDirectories) @@ -180,7 +211,7 @@ namespace ChovySign_GUI.Popup.Global { InitializeComponent(); this.cmaDir.FilePath = BackupDir; - this.backupSubFolder = "APP"; + this.backupSubFolders = new string[] { "APP" }; this.accId.SelectionChanged += onAccountSelectionChanged; this.cmaDir.FileChanged += onCmaDirChanged; this.backupList.SelectionChanged += onSelectedBackupChanged; @@ -191,6 +222,7 @@ namespace ChovySign_GUI.Popup.Global private void onSelectedBackupChanged(object? sender, SelectionChangedEventArgs e) { ListBox? lstBox = sender as ListBox; + if (lstBox is null) return; if (lstBox.SelectedIndex == -1) selectBtn.IsEnabled = false; else selectBtn.IsEnabled = true; } diff --git a/ChovySign-GUI/Popup/Global/KeySelector/EBOOTMETHOD.PNG b/ChovySign-GUI/Popup/Global/KeySelector/EBOOTMETHOD.PNG new file mode 100644 index 0000000..744f09a Binary files /dev/null and b/ChovySign-GUI/Popup/Global/KeySelector/EBOOTMETHOD.PNG differ diff --git a/ChovySign-GUI/Popup/Global/KeySelector/EBOOTMETHOD1.PNG b/ChovySign-GUI/Popup/Global/KeySelector/EBOOTMETHOD1.PNG deleted file mode 100644 index b33206d..0000000 Binary files a/ChovySign-GUI/Popup/Global/KeySelector/EBOOTMETHOD1.PNG and /dev/null differ diff --git a/ChovySign-GUI/Popup/Global/KeySelector/EBOOTMETHOD2.PNG b/ChovySign-GUI/Popup/Global/KeySelector/EBOOTMETHOD2.PNG deleted file mode 100644 index 1077610..0000000 Binary files a/ChovySign-GUI/Popup/Global/KeySelector/EBOOTMETHOD2.PNG and /dev/null differ diff --git a/ChovySign-GUI/Popup/Global/KeySelector/KeyObtainMethods.axaml b/ChovySign-GUI/Popup/Global/KeySelector/KeyObtainMethods.axaml index 6800371..4c2ccc6 100644 --- a/ChovySign-GUI/Popup/Global/KeySelector/KeyObtainMethods.axaml +++ b/ChovySign-GUI/Popup/Global/KeySelector/KeyObtainMethods.axaml @@ -21,8 +21,7 @@