This commit is contained in:
Dagg 2023-03-19 07:19:50 +00:00 committed by GitHub
commit 11d32d0cd6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 203 additions and 211 deletions

1
.gitignore vendored
View file

@ -9,6 +9,7 @@
*.user *.user
*.userosscache *.userosscache
*.sln.docstates *.sln.docstates
.vscode
# User-specific files (MonoDevelop/Xamarin Studio) # User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs *.userprefs

View file

@ -24,25 +24,8 @@ public class FilePatchForm : Form {
return control; return control;
} }
public Control CreateHelpButton(int tabIndex = 0) {
Button control = new() {
Text = "Help",
TabIndex = tabIndex,
};
control.Click += delegate {
Process process = new();
process.StartInfo.UseShellExecute = true;
process.StartInfo.FileName = "https://www.lbpunion.com";
process.Start();
};
return control;
}
public FilePatchForm() { public FilePatchForm() {
this.Title = "UnionPatcher - File Patch"; this.Title = "File Patch";
this.ClientSize = new Size(500, -1); this.ClientSize = new Size(500, -1);
this.Content = new TableLayout { this.Content = new TableLayout {
Spacing = new Size(5,5), Spacing = new Size(5,5),
@ -61,7 +44,7 @@ public class FilePatchForm : Form {
new TableCell(this.outputFileName = new FilePicker { TabIndex = 2, FileAction = FileAction.SaveFile, Filters = { new FileFilter("ELF files", "*.elf", "*.ELF"), new FileFilter("All Files", "*.*") }}) new TableCell(this.outputFileName = new FilePicker { TabIndex = 2, FileAction = FileAction.SaveFile, Filters = { new FileFilter("ELF files", "*.elf", "*.ELF"), new FileFilter("All Files", "*.*") }})
), ),
new TableRow( new TableRow(
new TableCell(this.CreateHelpButton(4)), new TableCell(),
new TableCell(this.CreatePatchButton(3)) new TableCell(this.CreatePatchButton(3))
), ),
}, },

View file

@ -8,8 +8,8 @@ namespace LBPUnion.UnionPatcher.Gui.Forms;
public class ModeSelectionForm : Form { public class ModeSelectionForm : Form {
#region UI #region UI
public ModeSelectionForm() { public ModeSelectionForm() {
this.Title = "Welcome to UnionPatcher"; this.Title = "UnionPatcher";
this.ClientSize = new Size(500, -1); this.ClientSize = new Size(200, -1);
this.Content = new TableLayout { this.Content = new TableLayout {
Spacing = new Size(5, 5), Spacing = new Size(5, 5),
Padding = new Padding(10, 10, 10, 10), Padding = new Padding(10, 10, 10, 10),
@ -17,9 +17,6 @@ public class ModeSelectionForm : Form {
new TableRow( new TableRow(
new TableCell(new Button(openRemotePatcher) { Text = "Remote Patcher (PS3)" }) new TableCell(new Button(openRemotePatcher) { Text = "Remote Patcher (PS3)" })
), ),
new TableRow(
new TableCell(new Button(openLocalPatcher) { Text = "Local Patch (RPCS3)", Enabled = false })
),
new TableRow( new TableRow(
new TableCell(new Button(openFilePatcher) { Text = "File Patch (PS3/RPCS3)" }) new TableCell(new Button(openFilePatcher) { Text = "File Patch (PS3/RPCS3)" })
), ),

View file

@ -1,5 +1,6 @@
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.Threading.Tasks;
using Eto.Drawing; using Eto.Drawing;
using Eto.Forms; using Eto.Forms;
@ -31,7 +32,7 @@ public class RemotePatchForm : Form
Width = 200, Width = 200,
}; };
control.Click += delegate { control.Click += async delegate {
if (string.IsNullOrEmpty(this.ps3LocalIP.Text)) if (string.IsNullOrEmpty(this.ps3LocalIP.Text))
{ {
Gui.CreateOkDialog("Error", "No PS3 IP address specified!"); Gui.CreateOkDialog("Error", "No PS3 IP address specified!");
@ -56,24 +57,33 @@ public class RemotePatchForm : Form
return; return;
} }
Task patchTask = null;
if (this.lbpGameID.Text.ToUpper().StartsWith('B'))
{
patchTask = this.RemotePatcher.DiscEBOOTRemotePatch(this.ps3LocalIP.Text, this.lbpGameID.Text, this.serverUrl.Text, this.ftpUser.Text, this.ftpPass.Text);
}
else
{
patchTask = this.RemotePatcher.PSNEBOOTRemotePatch(this.ps3LocalIP.Text, this.lbpGameID.Text, this.serverUrl.Text, this.ftpUser.Text, this.ftpPass.Text);
}
// Something went horribly wrong, this should be impossible to encounter.
if (patchTask == null) return;
Control revertButton = this.FindChild("revert");
foreach (Control control in this.Controls) control.Enabled = false;
Gui.CreateOkDialog("Sit Tight!", $"We're patching your title for {this.ps3LocalIP.Text}! Maybe grab some tea?");
try try
{ {
if (this.lbpGameID.Text.ToUpper().StartsWith('B')) await patchTask;
{ Gui.CreateOkDialog("Have fun!", $"The Server URL for {this.lbpGameID.Text} on the PS3 at {this.ps3LocalIP.Text} has been patched to {this.serverUrl.Text}");
this.RemotePatcher.DiscEBOOTRemotePatch(this.ps3LocalIP.Text, this.lbpGameID.Text, this.serverUrl.Text, this.ftpUser.Text, this.ftpPass.Text);
}
else
{
this.RemotePatcher.PSNEBOOTRemotePatch(this.ps3LocalIP.Text, this.lbpGameID.Text, this.serverUrl.Text, this.ftpUser.Text, this.ftpPass.Text);
}
} }
catch (Exception e) catch (Exception e)
{ {
Gui.CreateOkDialog("Error occurred while patching", "An error occured while patching:\n" + e); Gui.CreateOkDialog("Error occurred while patching", "An error occured while patching:\n" + e.Message);
return;
} }
foreach (Control control in this.Controls) control.Enabled = true;
Gui.CreateOkDialog("Success!", $"The Server URL for {this.lbpGameID.Text} on the PS3 at {this.ps3LocalIP.Text} has been patched to {this.serverUrl.Text}");
}; };
return control; return control;
@ -85,10 +95,10 @@ public class RemotePatchForm : Form
{ {
Text = "Revert EBOOT", Text = "Revert EBOOT",
TabIndex = tabIndex, TabIndex = tabIndex,
Width = 200, Width = 50,
}; };
control.Click += delegate { control.Click += async delegate {
if (string.IsNullOrEmpty(this.ps3LocalIP.Text)) if (string.IsNullOrEmpty(this.ps3LocalIP.Text))
{ {
Gui.CreateOkDialog("Form Error", "No PS3 IP address specified!"); Gui.CreateOkDialog("Form Error", "No PS3 IP address specified!");
@ -101,36 +111,19 @@ public class RemotePatchForm : Form
return; return;
} }
foreach (Control control in this.Controls) control.Enabled = false;
Task revertTask = this.RemotePatcher.RevertEBOOT(this.ps3LocalIP.Text, this.lbpGameID.Text, this.serverUrl.Text, this.ftpUser.Text, this.ftpPass.Text);
try try
{ {
this.RemotePatcher.RevertEBOOT(this.ps3LocalIP.Text, this.lbpGameID.Text, this.serverUrl.Text, this.ftpUser.Text, this.ftpPass.Text); await revertTask;
Gui.CreateOkDialog("Success!", $"UnionPatcher reverted your the EBOOT for {this.lbpGameID.Text} to stock. You're ready to patch your EBOOT again.");
} }
catch (Exception e) catch (Exception e)
{ {
Gui.CreateOkDialog("Error occurred while reverting EBOOT", "An error occured while patching:\n" + e); Gui.CreateOkDialog("Error occurred while reverting EBOOT", "An error occured while patching:\n" + e.Message);
return;
} }
foreach (Control control in this.Controls) control.Enabled = true;
Gui.CreateOkDialog("Success!", $"UnionRemotePatcher reverted your the EBOOT for {this.lbpGameID.Text} to stock. You're ready to patch your EBOOT again.");
};
return control;
}
public Control CreateHelpButton(int tabIndex = 0)
{
Button control = new()
{
Text = "Help",
TabIndex = tabIndex,
};
control.Click += delegate {
Process process = new();
process.StartInfo.UseShellExecute = true;
process.StartInfo.FileName = "https://www.lbpunion.com";
process.Start();
}; };
return control; return control;
@ -138,7 +131,7 @@ public class RemotePatchForm : Form
void InitializeComponent() void InitializeComponent()
{ {
this.Title = "UnionPatcher - Remote Patch"; this.Title = "Remote Patcher";
this.MinimumSize = new Size(450, 200); this.MinimumSize = new Size(450, 200);
this.Resizable = false; this.Resizable = false;
this.Padding = 10; this.Padding = 10;
@ -169,11 +162,8 @@ public class RemotePatchForm : Form
new TableCell(this.ftpPass = new TextBox { TabIndex = 4 }) new TableCell(this.ftpPass = new TextBox { TabIndex = 4 })
), ),
new TableRow( new TableRow(
new TableCell(this.CreateHelpButton(7)), new TableCell(this.CreateRevertEBOOTButton(6)),
new TableRow( new TableCell(this.CreatePatchButton(5))
new TableCell(this.CreatePatchButton(5)),
new TableCell(this.CreateRevertEBOOTButton(6))
)
), ),
}, },
}; };

View file

@ -5,6 +5,7 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Net; using System.Net;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Threading.Tasks;
using LBPUnion.UnionPatcher.Communication; using LBPUnion.UnionPatcher.Communication;
namespace LBPUnion.UnionPatcher; namespace LBPUnion.UnionPatcher;
@ -17,22 +18,27 @@ public class RemotePatch
{ {
Console.WriteLine("Getting users..."); Console.WriteLine("Getting users...");
Dictionary<string, string> users = new(); Task<Dictionary<string, string>> users = Task.Run(() =>
string[] userFolders = FTP.ListDirectory($"ftp://{ps3Ip}/dev_hdd0/home/", user, pass);
string username = "";
for (int i = 0; i < userFolders.Length; i++)
{ {
username = FTP.ReadFile($"ftp://{ps3Ip}/dev_hdd0/home/{userFolders[i]}/localusername", user, Dictionary<string, string> users = new();
pass);
users.Add(userFolders[i], username);
Console.WriteLine("User found: " + username + $" <{userFolders[i]}>"); string[] userFolders = FTP.ListDirectory($"ftp://{ps3Ip}/dev_hdd0/home/", user, pass);
}
return users; string username = "";
for (int i = 0; i < userFolders.Length; i++)
{
username = FTP.ReadFile($"ftp://{ps3Ip}/dev_hdd0/home/{userFolders[i]}/localusername", user,
pass);
users.Add(userFolders[i], username);
Console.WriteLine("User found: " + username + $" <{userFolders[i]}>");
}
return users;
});
return users.Result;
} }
public static void LaunchSCETool(string args) public static void LaunchSCETool(string args)
@ -44,13 +50,15 @@ public class RemotePatch
platformExecutable = "scetool/win64/scetool.exe"; platformExecutable = "scetool/win64/scetool.exe";
break; break;
case OSPlatform.Linux: case OSPlatform.Linux:
if(RuntimeInformation.ProcessArchitecture == Architecture.X64) if (RuntimeInformation.ProcessArchitecture == Architecture.X64)
{ {
platformExecutable = "scetool/linux64/scetool"; platformExecutable = "scetool/linux64/scetool";
} else if (RuntimeInformation.ProcessArchitecture == Architecture.Arm) }
else if (RuntimeInformation.ProcessArchitecture == Architecture.Arm)
{ {
platformExecutable = "scetool/linuxarm/scetool"; platformExecutable = "scetool/linuxarm/scetool";
} else if (RuntimeInformation.ProcessArchitecture == Architecture.Arm64) }
else if (RuntimeInformation.ProcessArchitecture == Architecture.Arm64)
{ {
platformExecutable = "scetool/linuxarm64/scetool"; platformExecutable = "scetool/linuxarm64/scetool";
} }
@ -87,154 +95,167 @@ public class RemotePatch
Console.WriteLine("\n===== END SCETOOL =====\n\n"); Console.WriteLine("\n===== END SCETOOL =====\n\n");
} }
public void RevertEBOOT(string ps3ip, string gameID, string serverURL, string user, string pass) public Task RevertEBOOT(string ps3ip, string gameID, string serverURL, string user, string pass)
{ {
Console.WriteLine("Restoring original EBOOT.BIN from EBOOT.BIN.BAK"); Console.WriteLine("Restoring original EBOOT.BIN from EBOOT.BIN.BAK");
// Create a simple directory structure return Task.Run(() =>
Directory.CreateDirectory(@"eboot"); {
Directory.CreateDirectory($@"eboot/{gameID}"); // Create a simple directory structure
Directory.CreateDirectory($@"eboot/{gameID}/original"); Directory.CreateDirectory(@"eboot");
Directory.CreateDirectory($@"eboot/{gameID}");
Directory.CreateDirectory($@"eboot/{gameID}/original");
// Now we'll check and see if a backup exists on the server, if so download it and then upload it back as EBOOT.BIN // Now we'll check and see if a backup exists on the server, if so download it and then upload it back as EBOOT.BIN
if (FTP.FileExists($"ftp://{ps3ip}/dev_hdd0/game/{gameID}/USRDIR/EBOOT.BIN.BAK", user, pass)) if (FTP.FileExists($"ftp://{ps3ip}/dev_hdd0/game/{gameID}/USRDIR/EBOOT.BIN.BAK", user, pass))
{ {
FTP.DownloadFile($"ftp://{ps3ip}/dev_hdd0/game/{gameID}/USRDIR/EBOOT.BIN.BAK", @$"eboot/{gameID}/original/EBOOT.BIN.BAK", user, pass);
FTP.UploadFile(@$"eboot/{gameID}/original/EBOOT.BIN.BAK", $"ftp://{ps3ip}/dev_hdd0/game/{gameID}/USRDIR/EBOOT.BIN", user, pass); FTP.DownloadFile($"ftp://{ps3ip}/dev_hdd0/game/{gameID}/USRDIR/EBOOT.BIN.BAK", @$"eboot/{gameID}/original/EBOOT.BIN.BAK", user, pass);
} FTP.UploadFile(@$"eboot/{gameID}/original/EBOOT.BIN.BAK", $"ftp://{ps3ip}/dev_hdd0/game/{gameID}/USRDIR/EBOOT.BIN", user, pass);
else
{ }
throw new WebException("Could not find EBOOT.BIN.BAK on server."); else
} {
throw new WebException("Could not find EBOOT.BIN.BAK on server.");
}
});
} }
public void PSNEBOOTRemotePatch(string ps3ip, string gameID, string serverURL, string user, string pass) public Task PSNEBOOTRemotePatch(string ps3ip, string gameID, string serverURL, string user, string pass)
{ {
Console.WriteLine("Detected Digital Copy - Running in Full Mode"); Console.WriteLine("Detected Digital Copy - Running in Full Mode");
string idps = ""; // Create a new thread so we don't occupy the UI thread.
string contentID = ""; return Task.Run(() =>
Dictionary<string, string> users;
this._ps3Mapi.ConnectTarget(ps3ip);
this._ps3Mapi.PS3.RingBuzzer(PS3MAPI.PS3Cmd.BuzzerMode.Double);
this._ps3Mapi.PS3.Notify("UnionRemotePatcher Connected! Patching...");
// Create simple directory structure
Directory.CreateDirectory(@"rifs");
Directory.CreateDirectory(@"eboot");
Directory.CreateDirectory($@"eboot/{gameID}");
Directory.CreateDirectory($@"eboot/{gameID}/original");
Directory.CreateDirectory($@"eboot/{gameID}/patched");
// Let's grab and backup our EBOOT
FTP.DownloadFile($"ftp://{ps3ip}/dev_hdd0/game/{gameID}/USRDIR/EBOOT.BIN",
@$"eboot/{gameID}/original/EBOOT.BIN", user, pass);
// Now we'll check and see if a backup exists on the server or not, if we don't have one on the server, then upload one
if (!FTP.FileExists($"ftp://{ps3ip}/dev_hdd0/game/{gameID}/USRDIR/EBOOT.BIN.BAK", user, pass))
FTP.UploadFile(@$"eboot/{gameID}/original/EBOOT.BIN",
$"ftp://{ps3ip}/dev_hdd0/game/{gameID}/USRDIR/EBOOT.BIN.BAK", user, pass);
// Start getting idps and act.dat - these will help us decrypt a PSN eboot
idps = PS3MAPI.PS3MAPIClientServer.PS3_GetIDPS();
File.WriteAllBytes(@"data/idps", IDPSHelper.StringToByteArray(idps));
// Scan the users on the system
users = GetUsers(ps3ip, user, pass);
// Scan the system for a license for the game
foreach (string currentUser in users.Keys.ToArray())
{ {
if (FTP.FileExists($"ftp://{ps3ip}/dev_hdd0/home/{currentUser}/exdata", user, pass)) string idps = "";
string contentID = "";
Dictionary<string, string> users;
this._ps3Mapi.ConnectTarget(ps3ip);
this._ps3Mapi.PS3.RingBuzzer(PS3MAPI.PS3Cmd.BuzzerMode.Double);
this._ps3Mapi.PS3.Notify("UnionRemotePatcher Connected! Patching...");
// Create simple directory structure
Directory.CreateDirectory(@"rifs");
Directory.CreateDirectory(@"eboot");
Directory.CreateDirectory($@"eboot/{gameID}");
Directory.CreateDirectory($@"eboot/{gameID}/original");
Directory.CreateDirectory($@"eboot/{gameID}/patched");
// Let's grab and backup our EBOOT
FTP.DownloadFile($"ftp://{ps3ip}/dev_hdd0/game/{gameID}/USRDIR/EBOOT.BIN",
@$"eboot/{gameID}/original/EBOOT.BIN", user, pass);
// Now we'll check and see if a backup exists on the server or not, if we don't have one on the server, then upload one
if (!FTP.FileExists($"ftp://{ps3ip}/dev_hdd0/game/{gameID}/USRDIR/EBOOT.BIN.BAK", user, pass))
FTP.UploadFile(@$"eboot/{gameID}/original/EBOOT.BIN",
$"ftp://{ps3ip}/dev_hdd0/game/{gameID}/USRDIR/EBOOT.BIN.BAK", user, pass);
// Start getting idps and act.dat - these will help us decrypt a PSN eboot
idps = PS3MAPI.PS3MAPIClientServer.PS3_GetIDPS();
File.WriteAllBytes(@"data/idps", IDPSHelper.StringToByteArray(idps));
// Scan the users on the system
users = GetUsers(ps3ip, user, pass);
// Scan the system for a license for the game
foreach (string currentUser in users.Keys.ToArray())
{ {
foreach (string fileName in FTP.ListDirectory( if (FTP.FileExists($"ftp://{ps3ip}/dev_hdd0/home/{currentUser}/exdata", user, pass))
$"ftp://{ps3ip}/dev_hdd0/home/{currentUser}/exdata/", user, pass)) {
if (fileName.Contains(gameID)) foreach (string fileName in FTP.ListDirectory(
{ $"ftp://{ps3ip}/dev_hdd0/home/{currentUser}/exdata/", user, pass))
FTP.DownloadFile($"ftp://{ps3ip}/dev_hdd0/home/{currentUser}/exdata/act.dat", @"data/act.dat", if (fileName.Contains(gameID))
user, {
pass); FTP.DownloadFile($"ftp://{ps3ip}/dev_hdd0/home/{currentUser}/exdata/act.dat", @"data/act.dat",
user,
pass);
FTP.DownloadFile($"ftp://{ps3ip}/dev_hdd0/home/{currentUser}/exdata/{fileName}", FTP.DownloadFile($"ftp://{ps3ip}/dev_hdd0/home/{currentUser}/exdata/{fileName}",
@$"rifs/{fileName}", user, pass); @$"rifs/{fileName}", user, pass);
contentID = fileName.Substring(0, fileName.Length - 4); contentID = fileName.Substring(0, fileName.Length - 4);
Console.WriteLine($"Got content ID {contentID}"); Console.WriteLine($"Got content ID {contentID}");
} }
}
} }
}
// Finally, let's decrypt the EBOOT.BIN // Finally, let's decrypt the EBOOT.BIN
LaunchSCETool($" -v -d \"{Path.GetFullPath(@$"eboot/{gameID}/original/EBOOT.BIN")}\" \"{Path.GetFullPath(@$"eboot/{gameID}/original/EBOOT.ELF")}\""); LaunchSCETool($" -v -d \"{Path.GetFullPath(@$"eboot/{gameID}/original/EBOOT.BIN")}\" \"{Path.GetFullPath(@$"eboot/{gameID}/original/EBOOT.ELF")}\"");
// Now, patch the EBOOT; // Now, patch the EBOOT;
Patcher.PatchFile($"eboot/{gameID}/original/EBOOT.ELF", serverURL, $"eboot/{gameID}/patched/EBOOT.ELF"); Patcher.PatchFile($"eboot/{gameID}/original/EBOOT.ELF", serverURL, $"eboot/{gameID}/patched/EBOOT.ELF");
// Encrypt the EBOOT (PSN) // Encrypt the EBOOT (PSN)
LaunchSCETool($"--verbose " + LaunchSCETool($"--verbose " +
$"--sce-type=SELF" + $"--sce-type=SELF" +
$" --skip-sections=FALSE" + $" --skip-sections=FALSE" +
$" --self-add-shdrs=TRUE" + $" --self-add-shdrs=TRUE" +
$" --compress-data=TRUE" + $" --compress-data=TRUE" +
$" --key-revision=0A" + $" --key-revision=0A" +
$" --self-app-version=0001000000000000" + $" --self-app-version=0001000000000000" +
$" --self-auth-id=1010000001000003" + $" --self-auth-id=1010000001000003" +
$" --self-vendor-id=01000002" + $" --self-vendor-id=01000002" +
$" --self-ctrl-flags=0000000000000000000000000000000000000000000000000000000000000000" + $" --self-ctrl-flags=0000000000000000000000000000000000000000000000000000000000000000" +
$" --self-cap-flags=00000000000000000000000000000000000000000000003B0000000100040000" + $" --self-cap-flags=00000000000000000000000000000000000000000000003B0000000100040000" +
$" --self-type=NPDRM" + $" --self-type=NPDRM" +
$" --self-fw-version=0003005500000000" + $" --self-fw-version=0003005500000000" +
$" --np-license-type=FREE" + $" --np-license-type=FREE" +
$" --np-app-type=SPRX" + $" --np-app-type=SPRX" +
$" --np-content-id={contentID}" + $" --np-content-id={contentID}" +
$" --np-real-fname=EBOOT.BIN" + $" --np-real-fname=EBOOT.BIN" +
$" --encrypt eboot/{gameID}/patched/EBOOT.ELF eboot/{gameID}/patched/EBOOT.BIN"); $" --encrypt eboot/{gameID}/patched/EBOOT.ELF eboot/{gameID}/patched/EBOOT.BIN");
// And upload the encrypted, patched EBOOT to the system. // And upload the encrypted, patched EBOOT to the system.
FTP.UploadFile(@$"eboot/{gameID}/patched/EBOOT.BIN", FTP.UploadFile(@$"eboot/{gameID}/patched/EBOOT.BIN",
$"ftp://{ps3ip}/dev_hdd0/game/{gameID}/USRDIR/EBOOT.BIN", user, pass); $"ftp://{ps3ip}/dev_hdd0/game/{gameID}/USRDIR/EBOOT.BIN", user, pass);
});
} }
// Cut-down version that only patches disc copies // Cut-down version that only patches disc copies
public void DiscEBOOTRemotePatch(string ps3ip, string gameID, string serverURL, string user, string pass) public Task DiscEBOOTRemotePatch(string ps3ip, string gameID, string serverURL, string user, string pass)
{ {
Console.WriteLine("Detected Disc Copy - Running in Simplified Mode"); Console.WriteLine("Detected Disc Copy - Running in Simplified Mode");
// Create a simple directory structure // Create a new thread so we don't occupy the UI thread.
Directory.CreateDirectory(@"eboot"); return Task.Run(() =>
Directory.CreateDirectory($@"eboot/{gameID}"); {
Directory.CreateDirectory($@"eboot/{gameID}/original"); // Create a simple directory structure
Directory.CreateDirectory($@"eboot/{gameID}/patched"); Directory.CreateDirectory(@"eboot");
Directory.CreateDirectory($@"eboot/{gameID}");
Directory.CreateDirectory($@"eboot/{gameID}/original");
Directory.CreateDirectory($@"eboot/{gameID}/patched");
// Let's grab and backup our EBOOT // Let's grab and backup our EBOOT
FTP.DownloadFile($"ftp://{ps3ip}/dev_hdd0/game/{gameID}/USRDIR/EBOOT.BIN", FTP.DownloadFile($"ftp://{ps3ip}/dev_hdd0/game/{gameID}/USRDIR/EBOOT.BIN",
@$"eboot/{gameID}/original/EBOOT.BIN", user, pass); @$"eboot/{gameID}/original/EBOOT.BIN", user, pass);
// Now we'll check and see if a backup exists on the server or not, if we don't have one on the server, then upload one // Now we'll check and see if a backup exists on the server or not, if we don't have one on the server, then upload one
if (!FTP.FileExists($"ftp://{ps3ip}/dev_hdd0/game/{gameID}/USRDIR/EBOOT.BIN.BAK", user, pass)) if (!FTP.FileExists($"ftp://{ps3ip}/dev_hdd0/game/{gameID}/USRDIR/EBOOT.BIN.BAK", user, pass))
FTP.UploadFile(@$"eboot/{gameID}/original/EBOOT.BIN", FTP.UploadFile(@$"eboot/{gameID}/original/EBOOT.BIN",
$"ftp://{ps3ip}/dev_hdd0/game/{gameID}/USRDIR/EBOOT.BIN.BAK", user, pass); $"ftp://{ps3ip}/dev_hdd0/game/{gameID}/USRDIR/EBOOT.BIN.BAK", user, pass);
// Check for keys in the data directory // Check for keys in the data directory
if (!File.Exists("data/keys")) if (!File.Exists("data/keys"))
throw new FileNotFoundException( throw new FileNotFoundException(
"UnionRemotePatcher cannot find the keys, ldr_curves, or vsh_curves files required to continue. Please make sure you have copies of these files placed in the data directory where you found the executable to run UnionRemotePatcher. Without them, we can't patch your game."); "UnionRemotePatcher cannot find the keys, ldr_curves, or vsh_curves files required to continue. Please make sure you have copies of these files placed in the data directory where you found the executable to run UnionRemotePatcher. Without them, we can't patch your game.");
// Decrypt the EBOOT // Decrypt the EBOOT
LaunchSCETool($"-v -d eboot/{gameID}/original/EBOOT.BIN eboot/{gameID}/original/EBOOT.ELF"); LaunchSCETool($"-v -d eboot/{gameID}/original/EBOOT.BIN eboot/{gameID}/original/EBOOT.ELF");
// Now, patch the EBOOT; // Now, patch the EBOOT;
Patcher.PatchFile($"eboot/{gameID}/original/EBOOT.ELF", serverURL, $"eboot/{gameID}/patched/EBOOT.ELF"); Patcher.PatchFile($"eboot/{gameID}/original/EBOOT.ELF", serverURL, $"eboot/{gameID}/patched/EBOOT.ELF");
// Encrypt the EBOOT (Disc) // Encrypt the EBOOT (Disc)
LaunchSCETool( LaunchSCETool(
$" -v --sce-type=SELF --skip-sections=FALSE --key-revision=0A --self-app-version=0001000000000000 --self-auth-id=1010000001000003 --self-vendor-id=01000002 --self-ctrl-flags=0000000000000000000000000000000000000000000000000000000000000000 --self-cap-flags=00000000000000000000000000000000000000000000003B0000000100040000 --self-type=APP --self-fw-version=0003005500000000 --compress-data true --encrypt \"{Path.GetFullPath(@$"eboot/{gameID}/patched/EBOOT.ELF")}\" \"{Path.GetFullPath(@$"eboot/{gameID}/patched/EBOOT.BIN")}\""); $" -v --sce-type=SELF --skip-sections=FALSE --key-revision=0A --self-app-version=0001000000000000 --self-auth-id=1010000001000003 --self-vendor-id=01000002 --self-ctrl-flags=0000000000000000000000000000000000000000000000000000000000000000 --self-cap-flags=00000000000000000000000000000000000000000000003B0000000100040000 --self-type=APP --self-fw-version=0003005500000000 --compress-data true --encrypt \"{Path.GetFullPath(@$"eboot/{gameID}/patched/EBOOT.ELF")}\" \"{Path.GetFullPath(@$"eboot/{gameID}/patched/EBOOT.BIN")}\"");
// And upload the encrypted, patched EBOOT to the system. // And upload the encrypted, patched EBOOT to the system.
FTP.UploadFile(@$"eboot/{gameID}/patched/EBOOT.BIN", FTP.UploadFile(@$"eboot/{gameID}/patched/EBOOT.BIN",
$"ftp://{ps3ip}/dev_hdd0/game/{gameID}/USRDIR/EBOOT.BIN", user, pass); $"ftp://{ps3ip}/dev_hdd0/game/{gameID}/USRDIR/EBOOT.BIN", user, pass);
});
} }
} }