diff --git a/Il2CppInspector.Common/IL2CPP/Il2CppBinary.cs b/Il2CppInspector.Common/IL2CPP/Il2CppBinary.cs index 219519c..389e60e 100644 --- a/Il2CppInspector.Common/IL2CPP/Il2CppBinary.cs +++ b/Il2CppInspector.Common/IL2CPP/Il2CppBinary.cs @@ -164,6 +164,7 @@ namespace Il2CppInspector public bool FindRegistrationStructs(double metadataVersion) { Image.Version = metadataVersion; + StatusUpdate("Searching for binary metadata"); if (!((FindMetadataFromSymbols() ?? FindMetadataFromCode() ?? FindMetadataFromData()) is (ulong code, ulong meta))) return false; diff --git a/Il2CppInspector.Common/IL2CPP/ImageScan.cs b/Il2CppInspector.Common/IL2CPP/ImageScan.cs index 3cd34ef..d6edc0f 100644 --- a/Il2CppInspector.Common/IL2CPP/ImageScan.cs +++ b/Il2CppInspector.Common/IL2CPP/ImageScan.cs @@ -92,6 +92,7 @@ namespace Il2CppInspector // < 27: mscorlib.dll is always the first CodeGenModule // >= 27: mscorlib.dll is always the last CodeGenModule (Assembly-CSharp.dll is always the first but non-Unity builds don't have this DLL) + // NOTE: winrt.dll + other DLLs can come after mscorlib.dll so we can't use its location to get an accurate module count var offsets = FindAllStrings(imageBytes, "mscorlib.dll\0"); vas = offsets.Select(o => Image.MapFileOffsetToVA(o)); @@ -101,10 +102,21 @@ namespace Il2CppInspector // We'll work back one pointer width at a time trying to find the first CodeGenModule // Let's hope there aren't more than 200 DLLs in any given application :) - for (int backtrack = 0; backtrack < 200 && (codeRegVas?.Count() ?? 0) != 1; backtrack++) { + var maxCodeGenModules = 200; + + for (int backtrack = 0; backtrack < maxCodeGenModules && (codeRegVas?.Count() ?? 0) != 1; backtrack++) { // Unwind from CodeGenModules + x -> CodeRegistration + y codeRegVas = FindAllMappedWords(imageBytes, vas); + // The previous word must be the number of CodeGenModules + if (codeRegVas.Count() == 1) { + var codeGenModuleCount = Image.ReadMappedWord(codeRegVas.First() - ptrSize); + + // Basic validity check + if (codeGenModuleCount <= 0 || codeGenModuleCount > maxCodeGenModules) + codeRegVas = Enumerable.Empty(); + } + // Move to the previous CodeGenModule if the above fails vas = vas.Select(va => va - ptrSize); }