diff --git a/Il2CppInspector.CLI/Program.cs b/Il2CppInspector.CLI/Program.cs index e9a7526..d27a8c8 100644 --- a/Il2CppInspector.CLI/Program.cs +++ b/Il2CppInspector.CLI/Program.cs @@ -139,9 +139,13 @@ namespace Il2CppInspector.CLI return 1; } - // Check image base - var loadOptions = new LoadOptions(); + // Set load options + var loadOptions = new LoadOptions { + ImageBase = 0xffffffff_ffffffff, + BinaryFilePath = options.BinaryFiles.First() + }; + // Check image base if (!string.IsNullOrEmpty(options.ElfImageBaseString)) { try { loadOptions.ImageBase = Convert.ToUInt64(options.ElfImageBaseString, 16); diff --git a/Il2CppInspector.Common/FileFormatReaders/ElfReader.cs b/Il2CppInspector.Common/FileFormatReaders/ElfReader.cs index 8a00a9b..f5f23b2 100644 --- a/Il2CppInspector.Common/FileFormatReaders/ElfReader.cs +++ b/Il2CppInspector.Common/FileFormatReaders/ElfReader.cs @@ -188,7 +188,7 @@ namespace Il2CppInspector if (!shtShouldBeOrdered.Any()) { // If the first file offset of the first PHT is zero, assume a dumped image - if (conv.ULong(program_header_table[0].p_vaddr) == 0ul) { + if (program_header_table.Any(t => conv.ULong(t.p_vaddr) == 0ul)) { Console.WriteLine("ELF binary appears to be a dumped memory image"); isMemoryImage = true; } @@ -207,10 +207,10 @@ namespace Il2CppInspector // Dumped images must be rebased if (isMemoryImage) { - if (!(LoadOptions?.ImageBase is ulong newImageBase)) + if (LoadOptions.ImageBase == 0xffffffff_ffffffff) throw new InvalidOperationException("To load a dumped ELF image, you must specify the image base virtual address"); - rebase(conv.FromULong(newImageBase)); + rebase(conv.FromULong(LoadOptions.ImageBase)); } // Get dynamic table if it exists (must be done after rebasing) @@ -667,7 +667,8 @@ namespace Il2CppInspector public override uint[] GetFunctionTable() { // INIT_ARRAY contains a list of pointers to initialization functions (not all functions in the binary) // INIT_ARRAYSZ contains the size of INIT_ARRAY - if (getDynamic(Elf.DT_INIT_ARRAY) == null || getDynamic(Elf.DT_INIT_ARRAYSZ) == null) + // INIT_ARRAY is probably broken in dumped images and resaved dumped images + if (getDynamic(Elf.DT_INIT_ARRAY) == null || getDynamic(Elf.DT_INIT_ARRAYSZ) == null || isMemoryImage) return Array.Empty(); var init = MapVATR(conv.ULong(getDynamic(Elf.DT_INIT_ARRAY).d_un)); diff --git a/Il2CppInspector.Common/FileFormatReaders/LoadOptions.cs b/Il2CppInspector.Common/FileFormatReaders/LoadOptions.cs index ee0e716..eed36be 100644 --- a/Il2CppInspector.Common/FileFormatReaders/LoadOptions.cs +++ b/Il2CppInspector.Common/FileFormatReaders/LoadOptions.cs @@ -10,6 +10,10 @@ namespace Il2CppInspector public class LoadOptions { // For dumped ELF files, the virtual address to which we should rebase - ignored for other file types - public ulong? ImageBase { get; set; } + // Use 2^64-1 to prevent rebasing on a dumped file + public ulong ImageBase { get; set; } + + // For Linux process memory map inputs, we need the full path so we can find the .bin files + public string BinaryFilePath { get; set; } } } \ No newline at end of file diff --git a/Il2CppInspector.GUI/App.xaml.cs b/Il2CppInspector.GUI/App.xaml.cs index 1feed87..c4f876b 100644 --- a/Il2CppInspector.GUI/App.xaml.cs +++ b/Il2CppInspector.GUI/App.xaml.cs @@ -34,7 +34,7 @@ namespace Il2CppInspectorGUI } } - public LoadOptions LoadOptions { get; private set; } = null; + public LoadOptions LoadOptions { get; private set; } public List AppModels { get; } = new List(); @@ -45,9 +45,15 @@ namespace Il2CppInspectorGUI private void StatusUpdate(object sender, string status) => OnStatusUpdate?.Invoke(sender, status); + // Initialization entry point + protected override void OnStartup(StartupEventArgs e) { + ResetLoadOptions(); + } + public void ResetLoadOptions() { LoadOptions = new LoadOptions { - ImageBase = 0ul + ImageBase = 0xffffffff_ffffffff, + BinaryFilePath = null }; } @@ -94,6 +100,9 @@ namespace Il2CppInspectorGUI // Attempt to load an IL2CPP binary file public async Task LoadBinaryAsync(string binaryFile) { + // For loaders which require the file path to find additional files + LoadOptions.BinaryFilePath = binaryFile; + var stream = new MemoryStream(await File.ReadAllBytesAsync(binaryFile)); return await LoadBinaryAsync(stream); } diff --git a/Il2CppInspector.GUI/HexStringValueConverter.cs b/Il2CppInspector.GUI/HexStringValueConverter.cs index e97ef58..d1ce1a4 100644 --- a/Il2CppInspector.GUI/HexStringValueConverter.cs +++ b/Il2CppInspector.GUI/HexStringValueConverter.cs @@ -20,7 +20,7 @@ namespace Il2CppInspector.GUI } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { - if (value == null || targetType != typeof(ulong?)) + if (value == null || targetType != typeof(ulong)) return DependencyProperty.UnsetValue; try { diff --git a/Il2CppInspector.GUI/LoadOptionsDialog.xaml.cs b/Il2CppInspector.GUI/LoadOptionsDialog.xaml.cs index 1e31969..201a561 100644 --- a/Il2CppInspector.GUI/LoadOptionsDialog.xaml.cs +++ b/Il2CppInspector.GUI/LoadOptionsDialog.xaml.cs @@ -25,9 +25,6 @@ namespace Il2CppInspector.GUI InitializeComponent(); var app = (App) Application.Current; - if (app.LoadOptions == null) - app.ResetLoadOptions(); - DataContext = app.LoadOptions; }