From b863cf74b827962a3ead9aa816c98673884741f5 Mon Sep 17 00:00:00 2001 From: Katy Coe Date: Sun, 27 Oct 2019 22:00:48 +0100 Subject: [PATCH] MachO: Read __mod_init_func instead of LC_FUNCTION_STARTS --- .../FileFormatReaders/MachOReader.cs | 52 ++++++------------- 1 file changed, 16 insertions(+), 36 deletions(-) diff --git a/Il2CppInspector/FileFormatReaders/MachOReader.cs b/Il2CppInspector/FileFormatReaders/MachOReader.cs index 826ead9..49aadc2 100644 --- a/Il2CppInspector/FileFormatReaders/MachOReader.cs +++ b/Il2CppInspector/FileFormatReaders/MachOReader.cs @@ -6,14 +6,13 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.IO; using System.Linq; using NoisyCowStudios.Bin2Object; namespace Il2CppInspector { - internal class MachOReader32 : MachOReader + internal class MachOReader32 : MachOReader { public MachOReader32(Stream stream) : base(stream) { } @@ -30,7 +29,7 @@ namespace Il2CppInspector } } - internal class MachOReader64 : MachOReader + internal class MachOReader64 : MachOReader { public MachOReader64(Stream stream) : base(stream) { } @@ -48,11 +47,16 @@ namespace Il2CppInspector // We need this convoluted generic TReader declaration so that "static T FileFormatReader.Load(Stream)" // is inherited to MachOReader32/64 with a correct definition of T - internal abstract class MachOReader : FileFormatReader where TWord : struct where TReader : FileFormatReader + internal abstract class MachOReader : FileFormatReader + where TWord : struct + where TReader : FileFormatReader + where TConvert : IWordConverter, new() { + private readonly TConvert conv = new TConvert(); + private MachOHeader header; protected readonly List> sections = new List>(); - private MachOLinkEditDataCommand funcTab; + private MachOSection funcTab; private MachOSymtabCommand symTab; protected MachOReader(Stream stream) : base(stream) { } @@ -105,15 +109,15 @@ namespace Il2CppInspector if (section.Name == "__text") { GlobalOffset = (ulong) Convert.ChangeType(section.Address, typeof(ulong)) - section.ImageOffset; } + + // Initialization (pre-main) functions + if (section.Name == "__mod_init_func") { + funcTab = section; + } } } break; - // Location of function table - case MachO.LC_FUNCTION_STARTS: - funcTab = ReadObject(); - break; - // Location of static symbol table case MachO.LC_SYMTAB: symTab = ReadObject(); @@ -128,7 +132,7 @@ namespace Il2CppInspector Position = startPos + loadCommand.Size; } - // Must find LC_FUNCTION_STARTS load command + // Must find __mod_init_func if (funcTab == null) return false; @@ -145,31 +149,7 @@ namespace Il2CppInspector return true; } - public override uint[] GetFunctionTable() { - Position = funcTab.Offset; - var functionPointers = new List(); - - // Decompress ELB128 list of function offsets - // https://en.wikipedia.org/wiki/LEB128 - uint previous = 0; - while (Position < funcTab.Offset + funcTab.Size) { - uint result = 0; - int shift = 0; - byte b; - do { - b = ReadByte(); - result |= (uint)((b & 0x7f) << shift); - shift += 7; - } while ((b & 0x80) != 0); - if (result > 0) { - if (previous == 0) - result &= 0xffffffc; - previous += result; - functionPointers.Add(previous); - } - } - return functionPointers.ToArray(); - } + public override uint[] GetFunctionTable() => ReadArray(funcTab.ImageOffset, conv.Int(funcTab.Size) / (Bits / 8)).Select(x => MapVATR(conv.ULong(x)) & 0xffff_fffe).ToArray(); public override Dictionary GetSymbolTable() { var symbols = new Dictionary();