// See: IL2CPP/Metadata.cs public void GetStrings(Metadata metadata, PluginGetStringsEventInfo data) { // NOTE: Metadata derives from BinaryObjectStream // Everything is available in Metadata except Strings and StringLiterals // See PostProcessMetadata below // Set data.Strings to a complete list of indexes and strings // and set data.IsDataModified }
// This executes just as Il2CppInspector is about to read all of the .NET identifier strings (eg. type names). // We can use this to acquire the strings ourselves instead public void GetStrings(Metadata metadata, PluginGetStringsEventInfo data) { // Don't do anything if this isn't for us if (!IsOurs) { return; } // Tell the user what is happening in case it takes a while PluginServices.For(this).StatusUpdate("Decrypting strings"); // miHoYo workloads use encrypted strings, and we need to know the correct string indexes // to pass to UnityPlayer.dll's GetStringFromIndex function. // To find them, we scan every definition in the metadata that refers to a string index, // combine them, put them in order and remove duplicates var stringIndexes = metadata.Images.Select(x => x.nameIndex) .Concat(metadata.Assemblies.Select(x => x.aname.nameIndex)) .Concat(metadata.Assemblies.Select(x => x.aname.cultureIndex)) .Concat(metadata.Assemblies.Select(x => x.aname.hashValueIndex)) .Concat(metadata.Assemblies.Select(x => x.aname.publicKeyIndex)) .Concat(metadata.Events.Select(x => x.nameIndex)) .Concat(metadata.Fields.Select(x => x.nameIndex)) .Concat(metadata.Methods.Select(x => x.nameIndex)) .Concat(metadata.Params.Select(x => x.nameIndex)) .Concat(metadata.Properties.Select(x => x.nameIndex)) .Concat(metadata.Types.Select(x => x.nameIndex)) .Concat(metadata.Types.Select(x => x.namespaceIndex)) .Concat(metadata.GenericParameters.Select(x => x.nameIndex)) .OrderBy(x => x) .Distinct() .ToList(); // Create a delegate which internally is a function pointer to the GetStringFromIndex function in the DLL var pGetStringFromIndex = (GetStringFromIndex) Marshal.GetDelegateForFunctionPointer(ModuleBase + Offsets[game.Value].GetStringFromIndex, typeof(GetStringFromIndex)); // For each index, call the delegate with the decrypted metadata byte array and index as arguments foreach (var index in stringIndexes) { data.Strings.Add(index, Marshal.PtrToStringAnsi(pGetStringFromIndex(metadataBlob, (uint)index))); } // This tells Il2CppInspector we have handled the strings and not to attempt to read them itself // The strings will be copied from data.Strings to metadata.Strings automatically data.IsDataModified = true; }