Пример #1
0
        // See: IL2CPP/Il2CppInspector.cs
        public void PostProcessPackage(Il2CppInspector.Il2CppInspector package, PluginPostProcessPackageEventInfo data)
        {
            // This is called once per IL2CPP binary after it has been merged with global-metadata.dat
            // and all of the data linked together

            // It contains surrogate properties to everything in Metadata and Il2CppBinary
            // plus all calculated default field values (FieldDefaultValue), default parameter values (ParameterDefaultValue),
            // field offsets (FieldOffsets), custom attribute generators (CustomAttributeGenerators),
            // function addresses (FunctionAddresses) and metadata usages (MetadataUsages) etc.

            // Set data.IsDataModified if you modify the Il2CppInspector
        }
Пример #2
0
        // A "package" is the combination of global-metadata.dat, the application binary,
        // and some analysis which links them both together into a single unit, the Il2CppInspector object.

        // This executes after all the low-level processing and analysis of the application is completed,
        // but before any higher-level abstractions are created, such as the .NET type model or C++ application model.

        // Therefore this is a good place to make any final changes to the data that the high level models and output modules will rely on
        // In this case, we are going to acquire all of the string literals that we deferred earlier
        public void PostProcessPackage(Il2CppInspector.Il2CppInspector package, PluginPostProcessPackageEventInfo 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 string literals");

            // Calculate the number of string literals
            // This calculation depends on being able to scan MetadataUsages for all of the StringLiteral uses
            // and finding the one with the highest index. The creation of MetadataUsages requires data
            // from both global-metadata.dat and the application binary; this data is merged together
            // when the Il2CppInspector object is initialized, so this is the earliest opportunity we have to examine it
            var stringLiteralCount = package.MetadataUsages.Where(u => u.Type == MetadataUsageType.StringLiteral).Max(u => u.SourceIndex) + 1;

            // Create a delegate which internally is a function pointer to the GetStringLiteralFromIndex function in the DLL
            var pGetStringLiteralFromIndex = (GetStringLiteralFromIndex)
                                             Marshal.GetDelegateForFunctionPointer(ModuleBase + Offsets[game.Value].GetStringLiteralFromIndex, typeof(GetStringLiteralFromIndex));

            var stringLiterals = new List <string>();
            var length         = 0;

            // For each index, call the delegate with the decrypted metadata byte array, index and a pointer as arguments
            // In this case, the function returns an array of UTF8-encoded characters,
            // and populates 'length' with the number of bytes returned
            for (uint index = 0; index < stringLiteralCount; index++)
            {
                var decryptedBytesUnmanaged = pGetStringLiteralFromIndex(metadataBlob, index, ref length);
                var str = new byte[length];
                Marshal.Copy(decryptedBytesUnmanaged, str, 0, length);

                stringLiterals.Add(Encoding.UTF8.GetString(str));
            }

            // If we had used IGetStringLiterals above, we would have set data.StringLiterals,
            // but here we modify the package (the Il2CppInspector object) directly instead
            package.Metadata.StringLiterals = stringLiterals.ToArray();

            // We don't set FullyProcessed so that other plugins can perform further post-processing modifications
            // IsDataModified tells Il2CppInspector that the contents of its internal data structures have been changed
            // Note this is different from IsStreamModified; changing the data in memory
            // does not automatically rewrite the stream.
            data.IsDataModified = true;
        }