Correctly handle valid virtual addresses not mapped to the image file

This commit is contained in:
Katy Coe
2019-10-16 18:30:30 +02:00
parent 38e04b72b7
commit 41d6b45f3b
4 changed files with 17 additions and 7 deletions

View File

@@ -84,9 +84,12 @@ namespace Il2CppInspector
return ReadArray<uint>(init_array.sh_offset, (int) init_array.sh_size / 4);
}
// Map a virtual address to an offset into the image file. Throws an exception if the virtual address is not mapped into the file.
// Note if uiAddr is a valid segment but filesz < memsz and the adjusted uiAddr falls between the range of filesz and memsz,
// an exception will be thrown. This area of memory is assumed to contain all zeroes.
public override uint MapVATR(uint uiAddr)
{
var program_header_table = program_table_element.First(x => uiAddr >= x.p_vaddr && uiAddr <= (x.p_vaddr + x.p_memsz));
var program_header_table = program_table_element.First(x => uiAddr >= x.p_vaddr && uiAddr <= (x.p_vaddr + x.p_filesz));
return uiAddr - (program_header_table.p_vaddr - program_header_table.p_offset);
}
}

View File

@@ -93,7 +93,7 @@ namespace Il2CppInspector
return 0;
var section = sections.First(x => uiAddr - GlobalOffset >= x.BaseMemory &&
uiAddr - GlobalOffset < x.BaseMemory + x.SizeMemory);
uiAddr - GlobalOffset < x.BaseMemory + x.SizeImage);
return uiAddr - section.BaseMemory - GlobalOffset + section.BaseImage;
}
}

View File

@@ -133,10 +133,10 @@ namespace Il2CppInspector
var def = TypeDefinitions[i];
var pFieldOffsets = Binary.FieldOffsetData[i];
if (pFieldOffsets != 0) {
Binary.Image.Stream.Position = Binary.Image.MapVATR((uint) pFieldOffsets);
BinaryImage.Position = BinaryImage.MapVATR((uint) pFieldOffsets);
for (var f = 0; f < def.field_count; f++)
offsets.Add(def.fieldStart + f, Binary.Image.Stream.ReadInt32());
offsets.Add(def.fieldStart + f, BinaryImage.Stream.ReadInt32());
}
}

View File

@@ -46,9 +46,16 @@ namespace Il2CppInspector.Reflection
// Per-module method pointer array uses the bottom 24 bits of the method's metadata token
// Derived from il2cpp::vm::MetadataCache::GetMethodPointer
else {
var method = (Definition.token & 0xffffff) - 1;
pkg.BinaryImage.Position = pkg.BinaryImage.MapVATR(Assembly.Module.methodPointers + method * 4);
VirtualAddress = pkg.BinaryImage.ReadUInt32();
var method = (Definition.token & 0xffffff);
if (method != 0) {
// In the event of an exception, the method pointer is not set in the file
// This probably means it has been optimized away by the compiler, or is an unused generic method
try {
pkg.BinaryImage.Position =
pkg.BinaryImage.MapVATR(Assembly.Module.methodPointers + (method - 1) * 4);
VirtualAddress = pkg.BinaryImage.ReadUInt32();
} catch (Exception) { }
}
}
// Remove ARM Thumb marker LSB if necessary