mirror of
https://github.com/LBPUnion/UnionPatcher.git
synced 2025-07-10 11:01:31 +00:00
Preliminary ELF file checks
This commit is contained in:
parent
07880be045
commit
4a68509d2b
3 changed files with 124 additions and 13 deletions
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.IO;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using Eto;
|
using Eto;
|
||||||
using Eto.Drawing;
|
using Eto.Drawing;
|
||||||
|
@ -21,14 +22,14 @@ namespace LBPUnion.UnionPatcher.Gui {
|
||||||
layout.Add(new Label {
|
layout.Add(new Label {
|
||||||
Text = errorMessage,
|
Text = errorMessage,
|
||||||
});
|
});
|
||||||
|
|
||||||
layout.BeginHorizontal();
|
layout.BeginHorizontal();
|
||||||
layout.BeginVertical();
|
layout.BeginVertical();
|
||||||
layout.Add(null);
|
layout.Add(null);
|
||||||
layout.Add(button = new Button {
|
layout.Add(button = new Button {
|
||||||
Text = "OK",
|
Text = "OK",
|
||||||
});
|
});
|
||||||
|
|
||||||
layout.EndVertical();
|
layout.EndVertical();
|
||||||
layout.EndHorizontal();
|
layout.EndHorizontal();
|
||||||
layout.EndHorizontal();
|
layout.EndHorizontal();
|
||||||
|
@ -42,10 +43,10 @@ namespace LBPUnion.UnionPatcher.Gui {
|
||||||
button.Click += delegate {
|
button.Click += delegate {
|
||||||
dialog.Close();
|
dialog.Close();
|
||||||
};
|
};
|
||||||
|
|
||||||
return dialog;
|
return dialog;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Control CreatePatchButton(int tabIndex = 0) {
|
public Control CreatePatchButton(int tabIndex = 0) {
|
||||||
Button control = new() {
|
Button control = new() {
|
||||||
Text = EasterEgg.Restitch ? "Restitch!" : "Patch!",
|
Text = EasterEgg.Restitch ? "Restitch!" : "Patch!",
|
||||||
|
@ -53,21 +54,38 @@ namespace LBPUnion.UnionPatcher.Gui {
|
||||||
};
|
};
|
||||||
|
|
||||||
control.Click += delegate {
|
control.Click += delegate {
|
||||||
if(string.IsNullOrEmpty(this.filePicker.FilePath)) {
|
if(string.IsNullOrWhiteSpace(this.filePicker.FilePath)) {
|
||||||
this.CreateOkDialog("Form Error", "No file specified!").ShowModal();
|
this.CreateOkDialog("Form Error", "No file specified!").ShowModal();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(string.IsNullOrEmpty(this.serverUrl.Text)) {
|
if(string.IsNullOrWhiteSpace(this.serverUrl.Text)) {
|
||||||
this.CreateOkDialog("Form Error", "No server URL specified!").ShowModal();
|
this.CreateOkDialog("Form Error", "No server URL specified!").ShowModal();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(string.IsNullOrEmpty(this.outputFileName.FilePath)) {
|
if(string.IsNullOrWhiteSpace(this.outputFileName.FilePath)) {
|
||||||
this.CreateOkDialog("Form Error", "No output file specified!").ShowModal();
|
this.CreateOkDialog("Form Error", "No output file specified!").ShowModal();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ElfFile eboot = new(this.filePicker.FilePath);
|
||||||
|
|
||||||
|
if(eboot.IsValid == false) {
|
||||||
|
this.CreateOkDialog("Eboot Error", $"{eboot.Name} is not a valid ELF file (magic number mismatch)").ShowModal();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(eboot.Is64Bit == null) {
|
||||||
|
this.CreateOkDialog("Eboot Error", $"{eboot.Name} does not target a valid system").ShowModal();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(string.IsNullOrWhiteSpace(eboot.Architecture)) {
|
||||||
|
this.CreateOkDialog("Eboot Error", $"{eboot.Name} does not target a valid architecture (PowerPC or ARM)").ShowModal();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Patcher.PatchFile(this.filePicker.FilePath, this.serverUrl.Text, this.outputFileName.FilePath);
|
Patcher.PatchFile(this.filePicker.FilePath, this.serverUrl.Text, this.outputFileName.FilePath);
|
||||||
}
|
}
|
||||||
|
@ -87,7 +105,7 @@ namespace LBPUnion.UnionPatcher.Gui {
|
||||||
Text = "Help",
|
Text = "Help",
|
||||||
TabIndex = tabIndex,
|
TabIndex = tabIndex,
|
||||||
};
|
};
|
||||||
|
|
||||||
control.Click += delegate {
|
control.Click += delegate {
|
||||||
Process process = new();
|
Process process = new();
|
||||||
|
|
||||||
|
@ -98,7 +116,7 @@ namespace LBPUnion.UnionPatcher.Gui {
|
||||||
|
|
||||||
return control;
|
return control;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MainForm() {
|
public MainForm() {
|
||||||
this.Title = EasterEgg.Restitch ? "Union Restitcher" : "Union Patcher";
|
this.Title = EasterEgg.Restitch ? "Union Restitcher" : "Union Patcher";
|
||||||
this.ClientSize = new Size(500, -1);
|
this.ClientSize = new Size(500, -1);
|
||||||
|
@ -126,4 +144,4 @@ namespace LBPUnion.UnionPatcher.Gui {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
74
UnionPatcher/ElfFile.cs
Normal file
74
UnionPatcher/ElfFile.cs
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Buffers.Binary;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Linux ELF header refspec: https://refspecs.linuxfoundation.org/elf/gabi4+/ch4.eheader.html
|
||||||
|
Wikipedia entry on ELF: https://en.wikipedia.org/wiki/Executable_and_Linkable_Format
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace LBPUnion.UnionPatcher {
|
||||||
|
public class ElfFile {
|
||||||
|
private enum WordSize : byte {
|
||||||
|
ThirtyTwoBits = 0x01,
|
||||||
|
SixtyFourBits = 0x02
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum Endianness : byte {
|
||||||
|
Little = 0x01,
|
||||||
|
Big = 0x02
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum InstructionSetArchitecture : UInt16 {
|
||||||
|
PowerPC = 0x15, //64-bit PowerPC (PS3)
|
||||||
|
ARM = 0x28 //32-bit ARM (Vita)
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Name { get; } = "Binary Blob";
|
||||||
|
|
||||||
|
public bool IsValid { get; }
|
||||||
|
public bool? Is64Bit { get; } = null;
|
||||||
|
public bool? IsBigEndian { get; } = null;
|
||||||
|
public string Architecture { get; } = null;
|
||||||
|
|
||||||
|
public byte[] Contents { get; } = null;
|
||||||
|
|
||||||
|
public ElfFile(byte[] fileContents) {
|
||||||
|
IsValid = fileContents[0x00..0x04].SequenceEqual(new byte[] {0x7F, (byte)'E', (byte)'L', (byte)'F'});
|
||||||
|
if(IsValid == false) return;
|
||||||
|
|
||||||
|
byte identClassValue = fileContents[0x04];
|
||||||
|
byte identDataValue = fileContents[0x05];
|
||||||
|
|
||||||
|
if(identClassValue == (byte)WordSize.ThirtyTwoBits || identClassValue == (byte)WordSize.SixtyFourBits)
|
||||||
|
Is64Bit = identClassValue == (byte)WordSize.SixtyFourBits;
|
||||||
|
|
||||||
|
if(identDataValue == (byte)Endianness.Little || identDataValue == (byte)Endianness.Big)
|
||||||
|
IsBigEndian = identDataValue == (byte)Endianness.Big;
|
||||||
|
|
||||||
|
Architecture = GetFileArchitecture(fileContents, IsBigEndian == true);
|
||||||
|
|
||||||
|
Contents = fileContents;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ElfFile(FileInfo file) : this(File.ReadAllBytes(file.FullName)) {
|
||||||
|
Name = file.Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ElfFile(string fileName) : this(new FileInfo(fileName)) {}
|
||||||
|
|
||||||
|
private string GetFileArchitecture(byte[] elfHeader, bool isBigEndian) {
|
||||||
|
byte[] architectureBytes = elfHeader[0x12..0x14];
|
||||||
|
UInt16 fileArch = (isBigEndian) ?
|
||||||
|
BinaryPrimitives.ReadUInt16BigEndian(architectureBytes) :
|
||||||
|
BinaryPrimitives.ReadUInt16LittleEndian(architectureBytes);
|
||||||
|
|
||||||
|
foreach(InstructionSetArchitecture arch in Enum.GetValues(typeof(InstructionSetArchitecture))) {
|
||||||
|
if(fileArch == (UInt16)arch)
|
||||||
|
return arch.ToString();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,13 +15,32 @@ namespace LBPUnion.UnionPatcher {
|
||||||
return fileName = Path.GetFileName(Process.GetCurrentProcess().MainModule?.FileName);
|
return fileName = Path.GetFileName(Process.GetCurrentProcess().MainModule?.FileName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Main(string[] args) {
|
public static void Main(string[] args) {
|
||||||
if(args.Length < 3) {
|
if(args.Length < 3) {
|
||||||
PrintHelp();
|
PrintHelp();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ElfFile eboot = new(new FileInfo(args[0]));
|
||||||
|
|
||||||
|
if(eboot.IsValid == false) {
|
||||||
|
Console.WriteLine($"{eboot.Name} is not a valid ELF file (magic number mismatch)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(eboot.Is64Bit == null) {
|
||||||
|
Console.WriteLine($"{eboot.Name} does not target a valid system");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(string.IsNullOrWhiteSpace(eboot.Architecture)) {
|
||||||
|
Console.WriteLine($"{eboot.Name} does not target a valid architecture (PowerPC or ARM)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine($"{eboot.Name} targets {eboot.Architecture}");
|
||||||
|
|
||||||
Patcher.PatchFile(args[0], args[1], args[2]);
|
Patcher.PatchFile(args[0], args[1], args[2]);
|
||||||
Console.WriteLine($"Successfully patched Server URL to {args[1]}.");
|
Console.WriteLine($"Successfully patched Server URL to {args[1]}.");
|
||||||
}
|
}
|
||||||
|
@ -31,4 +50,4 @@ namespace LBPUnion.UnionPatcher {
|
||||||
Console.WriteLine($" Usage: {FileName} <Input EBOOT.elf> <Server URL> <Output filename>");
|
Console.WriteLine($" Usage: {FileName} <Input EBOOT.elf> <Server URL> <Output filename>");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue