Put new discoveries into practice
This commit is contained in:
parent
c15e345b30
commit
f087076653
|
@ -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<Act>(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]");
|
||||
|
|
|
@ -16,8 +16,6 @@
|
|||
<None Remove="Icon.png" />
|
||||
<None Remove="Popup\Global\KeySelector\ACTRIFMETHOD.PNG" />
|
||||
<None Remove="Popup\Global\KeySelector\EBOOTMETHOD.PNG" />
|
||||
<None Remove="Popup\Global\KeySelector\EBOOTMETHOD1.png" />
|
||||
<None Remove="Popup\Global\KeySelector\EBOOTMETHOD2.png" />
|
||||
<None Remove="Popup\Global\KeySelector\KEYSTXTMETHOD.PNG" />
|
||||
<None Remove="PS1CD.PNG" />
|
||||
<None Remove="UMD.png" />
|
||||
|
@ -25,8 +23,7 @@
|
|||
<ItemGroup>
|
||||
<AvaloniaResource Include="ICON.PNG" />
|
||||
<AvaloniaResource Include="Popup\Global\KeySelector\ACTRIFMETHOD.PNG" />
|
||||
<AvaloniaResource Include="Popup\Global\KeySelector\EBOOTMETHOD1.PNG" />
|
||||
<AvaloniaResource Include="Popup\Global\KeySelector\EBOOTMETHOD2.PNG" />
|
||||
<AvaloniaResource Include="Popup\Global\KeySelector\EBOOTMETHOD.PNG" />
|
||||
<AvaloniaResource Include="Popup\Global\KeySelector\KEYSTXTMETHOD.PNG" />
|
||||
<AvaloniaResource Include="Ps1\PS1CD.PNG" />
|
||||
<AvaloniaResource Include="Psp\UMD.PNG">
|
||||
|
|
|
@ -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<string>(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<string>(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;
|
||||
}
|
||||
|
|
|
@ -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<string> foundDir = new List<string>();
|
||||
|
||||
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<string> accountIdLst = new List<string>();
|
||||
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<string> filteredGameDirectories = new List<string>();
|
||||
List<string> gameList = new List<string>();
|
||||
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;
|
||||
}
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 27 KiB |
Binary file not shown.
Before Width: | Height: | Size: 23 KiB |
Binary file not shown.
Before Width: | Height: | Size: 28 KiB |
|
@ -21,8 +21,7 @@
|
|||
<Button Content="IDPS+RIF+ACT Method" Click="actRifMethodClick" Grid.Row="0" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||
<Button Content="KEYS.TXT Method" Click="keysTxtMethodClick" Grid.Row="0" Grid.Column="2" HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||
|
||||
<Image Name="ebootMethodPs1Graphic" Source="/Popup/Global/KeySelector/EBOOTMETHOD1.PNG" Grid.Row="1" Grid.Column="0" VerticalAlignment="Top" HorizontalAlignment="Stretch"/>
|
||||
<Image Name="ebootMethodPspGraphic" Source="/Popup/Global/KeySelector/EBOOTMETHOD2.PNG" Grid.Row="1" Grid.Column="0" VerticalAlignment="Top" HorizontalAlignment="Stretch"/>
|
||||
<Image Name="ebootMethodGraphic" Source="/Popup/Global/KeySelector/EBOOTMETHOD.PNG" Grid.Row="1" Grid.Column="0" VerticalAlignment="Top" HorizontalAlignment="Stretch"/>
|
||||
<Image Name="actRifMethodGraphic" Source="/Popup/Global/KeySelector/ACTRIFMETHOD.PNG" Grid.Row="1" Grid.Column="1" VerticalAlignment="Top" HorizontalAlignment="Stretch"/>
|
||||
<Image Name="keysTxtMethodGraphic" Source="/Popup/Global/KeySelector/KEYSTXTMETHOD.PNG" Grid.Row="1" Grid.Column="2" VerticalAlignment="Top" HorizontalAlignment="Stretch"/>
|
||||
</Grid>
|
||||
|
|
|
@ -20,8 +20,6 @@ namespace ChovySign_GUI.Popup.Global.KeySelector
|
|||
set
|
||||
{
|
||||
keyIndex = value;
|
||||
if (keyIndex == 1) { ebootMethodPspGraphic.IsVisible = false; ebootMethodPs1Graphic.IsVisible = true; }
|
||||
else { ebootMethodPspGraphic.IsVisible = true; ebootMethodPs1Graphic.IsVisible = false; }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -117,6 +117,10 @@ namespace Li.Utilities
|
|||
{
|
||||
WriteBytesWithPadding(Encoding.UTF8.GetBytes(str), b, len);
|
||||
}
|
||||
public void WriteUInt64(UInt64 v)
|
||||
{
|
||||
WriteBytes(BitConverter.GetBytes(v));
|
||||
}
|
||||
public void WriteInt64(Int64 v)
|
||||
{
|
||||
WriteBytes(BitConverter.GetBytes(v));
|
||||
|
|
|
@ -137,3 +137,17 @@ EP9000-UCES01242_00-PRESELLADDONPCK0 FE1E0A3B419BB9376D084ABEC54A526B DBD40050D8
|
|||
EP9000-UCES01242_00-PRESELLADDONPCK1 45331A2B5F214CD4E1297227126FAE95 FC1310D9604F5DC4FFF1015299A33524 A46821B0D75A1EA5932A9C6E6CC41E9B 70C67F9198F5105DFE70AA867679E0D3
|
||||
EP9000-UCES01242_00-PRESELLADDONPCK3 3C67064205AF3B6F5516E1008F7E9578 3DA0A4525880F6E65D921B406291D0E0 FDB5E4B9E8FE2EBED8BE487F8B585ED9 C07F639AC4C4E5E3E3DED4054F600514
|
||||
EP9000-UCES01242_00-PRESELLADDONPCK2 211625C7ACF3AD87FB80C088B5A816D0 731870DDA5D2B6A454FC32B196B39BB4 034B72CB73F41ECE183E17C5F1F5DB2F 01BDE1B45251E03597DE2D00F745E0E0
|
||||
EP0001-NPEH00029_00-GPCASSASSINPGO02 3256531B6287569F75A12C24DB1D92F5 779E4C9FA20A2DC30DBBFDC05B6F8CE9 0E446F48989AF17569671B0BC24EE951 CBFD89B5ED02344EC13485B31E32DAB1
|
||||
EP0006-NPEW00073_00-TPCFIFA11P000001 266993E225B9FE02F6784CF706624989 F19D7EDF0BDC5889A96DACB9B8D1AC68 C12E67459716BACCC208707B65793E1D 5C2104AB3DDB9974E444259EA0C75C2A
|
||||
EP1004-ULES00502_00-GPCGRANDTH000001 0E39CF82632FFF40CB6431ED3D612C55 80C952D1EAE9B0486080B9A34E0F7C26 FD1233140909948C810391716D4730C9 9A1B891F7885430FBF0E2AD3B1AA15EE
|
||||
EP1063-NPEH00101_00-PRAM001122334455 30CDDC33A4E18D8C9335278B7E05BB9B 4A1FBE67782A0324E4C7756F3854FE2B 60C5698A260CD64F8EF4ABFC936A354F D46F9CFBC83E2BCAE3C0AEB44D678756
|
||||
EP1063-NPEH00101_00-TICKET0011223344 891C6358BCD5FA5822125170C9CFDC88 67128C1321601EB91F7FCF0D643A5A83 C0713C15C91ABF06278CC0A9437F1F27 53FAB2836B5DC5C89A2CC9D68CE5C23E
|
||||
EP4293-ULES01515_00-GBPSPGAMERG00100 2CD73C4EFC809558543F1B3E3C272AB9 64794493FD2B4B960FB73AD6B1E140F7 766898B4E6BD91A138C242B4D56B1EE1 E849705F7C20FA3E4A963A01A632B8AA
|
||||
EP9000-NPEG90013_00-DPCRESISTA000001 D9621D80C5BEF35B42DC2A18E8C1C1F2 D27AC3D28A9D564F8EE713B1C485C1B7 9BBB0AD3A6BDA78720ADBC73E30018BD 4EEE59B99F8DD06D97DFF7E196B317C0
|
||||
EP9000-NPEG90019_00-LBPPSPEPSN000001 C0F7AD7D7012202CF27BBE670265BF05 1DCF8692689FB9CC0E010DE98EF77C23 8957E078A33C249D6CFEBF4A69CD21EE 6ADCB170B8A861E2035BAA20CB5BAA2C
|
||||
EP9000-NPEW00068_00-TPCPSPGOPR000001 C3602E7EE9CA1B5D4600C5AA54BB1055 B53C53352F887C2DA84E5BDE29EB72AF 8CFA5E61BE013AFCFE418126CEF4D809 36644FDB1346637D6AF6C21426692FB8
|
||||
EP9000-UCED90042_00-DPCSOCOMFTDEMO01 47D6208DF789C4ECD86692CF4D60A322 ECA7BAEC11B35B8F54280FE0D389B3B6 78DA407B23310875D52648802F7E4974 1878AC0652D24B8AEFB286358D2B5E60
|
||||
EP9000-UCES00422_00-RIDGERACER2DEMO1 D5041BB4CBFBDFD6470F9F9EE6FE5A12 8A9833DB42B4848FEA6BF46E0CCCBB6D F09D093506D205CAE121D641C0AAB354 33B9BB2EE725BF8AD6AED826447C6BE9
|
||||
EP9000-UCES00694_00-PFXTRMJUSTPSPGO2 0A4368759887952E157998EA5EA27396 71539E955A231AA6AB7044DA6E3D80AD FCCFB57EA5C15E1E5554811ECC7203E3 3041033FCD90D2ABA50545F6227410EB
|
||||
EP9000-UCES01264_00-LBPPSPEFULL00001 297DBC7870E72EF195D85611A10B94E7 A9F0F0D181C264D15CB3AFC553EB63A7 0D905696883327C8F4CE4DC45B185FB8 900132071EB7175615C1CA822C804BA0
|
||||
EP9001-NPEW00051_00-TPCGRANTUR000001 FEA1848910E05C9D45C9FBFA8863C1BE DE374F786E6CBF4E057B1C9EB64B3124 D50C141C8A7B0B840903F60A3796FB5B A346DCD09D173B36E524B29D776066C3
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace LibChovy.VersionKey
|
|||
catch { return null; }
|
||||
}
|
||||
|
||||
public static NpDrmInfo? GetKeyFromGamePsvimg(string gameBackupFolder, string accountId)
|
||||
public static NpDrmInfo? GetKeyFromGamePsvimg(string gameBackupFolder, string accountId, int keyIndex)
|
||||
{
|
||||
string gamePsvimgFile = Path.Combine(gameBackupFolder, "game", "game.psvimg");
|
||||
if (!File.Exists(gamePsvimgFile)) return null;
|
||||
|
@ -36,7 +36,7 @@ namespace LibChovy.VersionKey
|
|||
using (PSVIMGFileStream? pbp = GetFileFromPsvImg(gamePsvimgFile, "/EBOOT.PBP", cmaKey))
|
||||
{
|
||||
if (pbp is null) return null;
|
||||
return EbootPbpMethod.GetVersionKey(pbp);
|
||||
return EbootPbpMethod.GetVersionKey(pbp, keyIndex);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace LibChovy.VersionKey
|
|||
AMCTRL.bbmac_getkey(mkey, bbmac, versionKey);
|
||||
return versionKey;
|
||||
}
|
||||
public static NpDrmInfo GetVersionKey(Stream ebootStream)
|
||||
public static NpDrmInfo GetVersionKey(Stream ebootStream, int keyIndex)
|
||||
{
|
||||
using (ebootStream)
|
||||
{
|
||||
|
@ -39,32 +39,35 @@ namespace LibChovy.VersionKey
|
|||
switch (psarMagic)
|
||||
{
|
||||
case "NPUMDIMG":
|
||||
int keyType = ebootUtil.ReadInt32();
|
||||
int orginalKeyIndex = ebootUtil.ReadInt32();
|
||||
string contentId = ebootUtil.ReadStringAt(dataPsarLocation + 0x10);
|
||||
|
||||
byte[] npUmdHdr = ebootUtil.ReadBytesAt(dataPsarLocation, 0xC0);
|
||||
byte[] npUmdHeaderHash = ebootUtil.ReadBytesAt(dataPsarLocation + 0xC0, 0x10);
|
||||
|
||||
byte[] versionkey = getKey(npUmdHeaderHash, npUmdHdr);
|
||||
|
||||
return new NpDrmInfo(versionkey, contentId, keyType);
|
||||
|
||||
SceNpDrm.sceNpDrmTransformVersionKey(versionkey, orginalKeyIndex, keyIndex);
|
||||
return new NpDrmInfo(versionkey, contentId, keyIndex);
|
||||
case "PSISOIMG":
|
||||
using (DNASStream dnas = new DNASStream(ebootStream, dataPsarLocation + 0x400))
|
||||
{
|
||||
contentId = ebootUtil.ReadStringAt(dataPspLocation + 0x560);
|
||||
keyType = dnas.KeyIndex;
|
||||
orginalKeyIndex = dnas.KeyIndex;
|
||||
versionkey = dnas.VersionKey;
|
||||
|
||||
return new NpDrmInfo(versionkey, contentId, keyType);
|
||||
SceNpDrm.sceNpDrmTransformVersionKey(versionkey, orginalKeyIndex, keyIndex);
|
||||
return new NpDrmInfo(versionkey, contentId, keyIndex);
|
||||
}
|
||||
case "PSTITLEI":
|
||||
using (DNASStream dnas = new DNASStream(ebootStream, dataPsarLocation + 0x200))
|
||||
{
|
||||
contentId = ebootUtil.ReadStringAt(dataPspLocation + 0x560);
|
||||
keyType = dnas.KeyIndex;
|
||||
orginalKeyIndex = dnas.KeyIndex;
|
||||
versionkey = dnas.VersionKey;
|
||||
|
||||
return new NpDrmInfo(versionkey, contentId, keyType);
|
||||
SceNpDrm.sceNpDrmTransformVersionKey(versionkey, orginalKeyIndex, keyIndex);
|
||||
return new NpDrmInfo(versionkey, contentId, keyIndex);
|
||||
}
|
||||
default:
|
||||
throw new Exception("Cannot obtain versionkey from this EBOOT.PBP (magic:" + psarMagic + ")");
|
||||
|
|
BIN
Methods.png
BIN
Methods.png
Binary file not shown.
Before Width: | Height: | Size: 154 KiB After Width: | Height: | Size: 96 KiB |
|
@ -197,6 +197,7 @@ namespace PspCrypto
|
|||
var encData = encryptor.TransformFinalBlock(buffer, 0, buffer.Length);
|
||||
encData.AsSpan().CopyTo(oubput);
|
||||
}
|
||||
|
||||
#if false
|
||||
public static byte[] AesDecrypt(Aes aes, byte[] data, int offset, int length)
|
||||
{
|
||||
|
|
|
@ -1080,7 +1080,7 @@ namespace PspCrypto
|
|||
|
||||
unsafe
|
||||
{
|
||||
var ecdsa = ECDsaHelper.Create(curve, sig.public_key.x, sig.public_key.y);
|
||||
ECDsa ecdsa = ECDsaHelper.Create(curve, sig.public_key.x, sig.public_key.y);
|
||||
|
||||
if (ecdsa.VerifyHash(sig.message_hash, sig.signature.sig))
|
||||
{
|
||||
|
|
|
@ -3,6 +3,7 @@ using System;
|
|||
using System.Buffers.Binary;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
@ -433,6 +434,14 @@ namespace PspCrypto
|
|||
}
|
||||
|
||||
}
|
||||
public static int sceNpDrmTransformVersionKey(Span<byte> versionKey, int srcKeyType, int dstKeyType)
|
||||
{
|
||||
// reverse the previous "GenVersionKey" step ..
|
||||
int ret = ReverseGenVersionKey(versionKey, srcKeyType);
|
||||
if (ret >= 0)
|
||||
ret = GenVersionKey(versionKey, dstKeyType); // generate a new version key of this type
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static int sceNpDrmGetIDps(Span<byte> idps)
|
||||
{
|
||||
|
@ -444,7 +453,7 @@ namespace PspCrypto
|
|||
return -0x7faaf6ff;
|
||||
}
|
||||
|
||||
private static int GetActKey(Span<byte> key, ReadOnlySpan<byte> keyTable, int count)
|
||||
public static int GetActKey(Span<byte> key, ReadOnlySpan<byte> keyTable, int count)
|
||||
{
|
||||
Span<byte> idps = stackalloc byte[16];
|
||||
Span<byte> decKey = stackalloc byte[16];
|
||||
|
@ -525,6 +534,22 @@ namespace PspCrypto
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
private static int ReverseGenVersionKey(Span<byte> versionkey, int type)
|
||||
{
|
||||
type &= 0xffffff;
|
||||
int ret = 0;
|
||||
if (type != 0)
|
||||
{
|
||||
ret = unchecked((int)0x80550901);
|
||||
if (type < 4)
|
||||
{
|
||||
ret = AesHelper.AesDecrypt(versionkey, versionkey, KeyVault.drmVersionKeyKey.AsSpan().Slice(type * 0x10, 0x10));
|
||||
ret = ret == 16 ? 0 : unchecked((int)0x80550902);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
private static int GenVersionKey(Span<byte> versionKey, int type)
|
||||
{
|
||||
type &= 0xffffff;
|
||||
|
|
|
@ -11,16 +11,10 @@ atleast one of these are free in *most* regions;
|
|||
however failing that, you can also use a PSP DLC license-
|
||||
|
||||
-- if you don't have a hacked PSVita:
|
||||
Note: If the game you are using to do this with any games besides PETZ SADDLE CLUB, LOCOROCO MIDNIGHT CARNIVAL or APE QUEST STARTER PACK;
|
||||
you will be limited to the same game type as the license is for,
|
||||
i.e a PS1 game will only be usable to create a PS1 game,
|
||||
and a PSP game will only be usable to create a PSP game
|
||||
(this is different' if you use the henkaku method)
|
||||
|
||||
Copy the game to your PC using Content Manager,
|
||||
open chovy-sign2 and click the "Get Keys" button
|
||||
-- if you are using "APE QUEST, LOCOROCO MIDNIGHT CARNIVAL, or PETZ SADDLE CLUB, and want to make a PS1 game select "KEYS.TXT" instead-)
|
||||
select "EBOOT.PBP" method, click on the game
|
||||
|
||||
(note: there may be some issues if you try this while having DLC for the game installed ...)
|
||||
|
||||
you should see the RIF and KEY fields populate, and your good to go!
|
||||
|
|
Loading…
Reference in New Issue