ELF: Tidy up LoadOptions and handling of dumped files

This commit is contained in:
Katy Coe
2020-12-13 01:37:28 +01:00
parent 752cd6184c
commit 625cba808f
6 changed files with 28 additions and 13 deletions

View File

@@ -139,9 +139,13 @@ namespace Il2CppInspector.CLI
return 1; return 1;
} }
// Check image base // Set load options
var loadOptions = new LoadOptions(); var loadOptions = new LoadOptions {
ImageBase = 0xffffffff_ffffffff,
BinaryFilePath = options.BinaryFiles.First()
};
// Check image base
if (!string.IsNullOrEmpty(options.ElfImageBaseString)) { if (!string.IsNullOrEmpty(options.ElfImageBaseString)) {
try { try {
loadOptions.ImageBase = Convert.ToUInt64(options.ElfImageBaseString, 16); loadOptions.ImageBase = Convert.ToUInt64(options.ElfImageBaseString, 16);

View File

@@ -188,7 +188,7 @@ namespace Il2CppInspector
if (!shtShouldBeOrdered.Any()) { if (!shtShouldBeOrdered.Any()) {
// If the first file offset of the first PHT is zero, assume a dumped image // 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"); Console.WriteLine("ELF binary appears to be a dumped memory image");
isMemoryImage = true; isMemoryImage = true;
} }
@@ -207,10 +207,10 @@ namespace Il2CppInspector
// Dumped images must be rebased // Dumped images must be rebased
if (isMemoryImage) { 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"); 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) // Get dynamic table if it exists (must be done after rebasing)
@@ -667,7 +667,8 @@ namespace Il2CppInspector
public override uint[] GetFunctionTable() { public override uint[] GetFunctionTable() {
// INIT_ARRAY contains a list of pointers to initialization functions (not all functions in the binary) // INIT_ARRAY contains a list of pointers to initialization functions (not all functions in the binary)
// INIT_ARRAYSZ contains the size of INIT_ARRAY // 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<uint>(); return Array.Empty<uint>();
var init = MapVATR(conv.ULong(getDynamic(Elf.DT_INIT_ARRAY).d_un)); var init = MapVATR(conv.ULong(getDynamic(Elf.DT_INIT_ARRAY).d_un));

View File

@@ -10,6 +10,10 @@ namespace Il2CppInspector
public class LoadOptions public class LoadOptions
{ {
// For dumped ELF files, the virtual address to which we should rebase - ignored for other file types // 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; }
} }
} }

View File

@@ -34,7 +34,7 @@ namespace Il2CppInspectorGUI
} }
} }
public LoadOptions LoadOptions { get; private set; } = null; public LoadOptions LoadOptions { get; private set; }
public List<AppModel> AppModels { get; } = new List<AppModel>(); public List<AppModel> AppModels { get; } = new List<AppModel>();
@@ -45,9 +45,15 @@ namespace Il2CppInspectorGUI
private void StatusUpdate(object sender, string status) => OnStatusUpdate?.Invoke(sender, status); private void StatusUpdate(object sender, string status) => OnStatusUpdate?.Invoke(sender, status);
// Initialization entry point
protected override void OnStartup(StartupEventArgs e) {
ResetLoadOptions();
}
public void ResetLoadOptions() { public void ResetLoadOptions() {
LoadOptions = new LoadOptions { LoadOptions = new LoadOptions {
ImageBase = 0ul ImageBase = 0xffffffff_ffffffff,
BinaryFilePath = null
}; };
} }
@@ -94,6 +100,9 @@ namespace Il2CppInspectorGUI
// Attempt to load an IL2CPP binary file // Attempt to load an IL2CPP binary file
public async Task<bool> LoadBinaryAsync(string binaryFile) { public async Task<bool> 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)); var stream = new MemoryStream(await File.ReadAllBytesAsync(binaryFile));
return await LoadBinaryAsync(stream); return await LoadBinaryAsync(stream);
} }

View File

@@ -20,7 +20,7 @@ namespace Il2CppInspector.GUI
} }
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { 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; return DependencyProperty.UnsetValue;
try { try {

View File

@@ -25,9 +25,6 @@ namespace Il2CppInspector.GUI
InitializeComponent(); InitializeComponent();
var app = (App) Application.Current; var app = (App) Application.Current;
if (app.LoadOptions == null)
app.ResetLoadOptions();
DataContext = app.LoadOptions; DataContext = app.LoadOptions;
} }