IL2CPP: Write reconstructed registration structs back to binary

This commit is contained in:
Katy Coe
2020-12-10 18:03:40 +01:00
parent b2ea6101b5
commit 43d736cf03
2 changed files with 44 additions and 11 deletions

View File

@@ -244,7 +244,6 @@ namespace Il2CppInspector
// Do basic validatation that MetadataRegistration and CodeRegistration are sane // Do basic validatation that MetadataRegistration and CodeRegistration are sane
/* /*
* TODO: Validation can be greatly expanded upon later, eg. pointers in these two structs should actually be pointers
* GlobalMethodPointers (<= 24.1) must be a series of pointers in il2cpp or .text, and in sequential order * GlobalMethodPointers (<= 24.1) must be a series of pointers in il2cpp or .text, and in sequential order
* FieldOffsetPointers (>= 21.1) must be a series of pointers in __const or zero, and in sequential order * FieldOffsetPointers (>= 21.1) must be a series of pointers in __const or zero, and in sequential order
* typeRefPointers must be a series of pointers in __const * typeRefPointers must be a series of pointers in __const
@@ -252,7 +251,6 @@ namespace Il2CppInspector
*/ */
for (var pass = 0; pass <= 1; pass++) for (var pass = 0; pass <= 1; pass++)
if (MetadataRegistration.typesCount < MetadataRegistration.typeDefinitionsSizesCount if (MetadataRegistration.typesCount < MetadataRegistration.typeDefinitionsSizesCount
|| MetadataRegistration.genericClassesCount < MetadataRegistration.genericInstsCount
|| MetadataRegistration.genericMethodTableCount < MetadataRegistration.genericInstsCount || MetadataRegistration.genericMethodTableCount < MetadataRegistration.genericInstsCount
|| CodeRegistration.reversePInvokeWrapperCount > 0x1000 || CodeRegistration.reversePInvokeWrapperCount > 0x1000
|| CodeRegistration.unresolvedVirtualCallCount > 0x4000 // >= 22 || CodeRegistration.unresolvedVirtualCallCount > 0x4000 // >= 22

View File

@@ -7,6 +7,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using NoisyCowStudios.Bin2Object;
namespace Il2CppInspector namespace Il2CppInspector
{ {
@@ -58,8 +59,12 @@ namespace Il2CppInspector
} }
// Reconstruct Il2CppCodeRegistration and Il2CppMetadataRegistration into their original, unobfuscated field order // Reconstruct Il2CppCodeRegistration and Il2CppMetadataRegistration into their original, unobfuscated field order
// Supports metadata >=19, <27 // Supports metadata >=19, <=24.1 (TODO: add CodeGenModules to support <27)
private void ReconstructMetadata(Metadata metadata) { private void ReconstructMetadata(Metadata metadata) {
// Don't cause corruption in unsupported versions
if (Image.Version < 19 || Image.Version > 24.1)
return;
// If the section table is not available, give up and do nothing // If the section table is not available, give up and do nothing
if (!Image.TryGetSections(out var sections)) if (!Image.TryGetSections(out var sections))
return; return;
@@ -314,12 +319,37 @@ namespace Il2CppInspector
CodeRegistration.pmethodPointers = methodPointers.Key; CodeRegistration.pmethodPointers = methodPointers.Key;
CodeRegistration.methodPointersCount = (ulong) methodPointers.Value; CodeRegistration.methodPointersCount = (ulong) methodPointers.Value;
// Force CodeRegistration to pass validation in Il2CppBinary.Configure() // Zero out any unprocessed items
CodeRegistration.reversePInvokeWrapperCount = 0; CodeRegistration.reversePInvokeWrapperCount = 0;
CodeRegistration.reversePInvokeWrappers = 0;
CodeRegistration.delegateWrappersFromManagedToNativeCount = 0;
CodeRegistration.delegateWrappersFromManagedToNative = 0;
CodeRegistration.marshalingFunctionsCount = 0;
CodeRegistration.marshalingFunctions = 0;
CodeRegistration.ccwMarshalingFunctionsCount = 0;
CodeRegistration.ccwMarshalingFunctions = 0;
CodeRegistration.unresolvedVirtualCallCount = 0; CodeRegistration.unresolvedVirtualCallCount = 0;
CodeRegistration.unresolvedVirtualCallPointers = 0;
CodeRegistration.interopDataCount = 0; CodeRegistration.interopDataCount = 0;
CodeRegistration.interopData = 0;
CodeRegistration.guidCount = 0;
CodeRegistration.guids = 0;
CodeRegistration.windowsRuntimeFactoryCount = 0;
CodeRegistration.windowsRuntimeFactoryTable = 0;
CodeRegistration.codeGenModulesCount = 0;
CodeRegistration.pcodeGenModules = 0;
// TODO: Write changes to stream // Write changes to stream
using var sw = new BinaryObjectWriter(Image.Stream.BaseStream, Image.Stream.Endianness, true);
sw.Version = Image.Version;
// Set width of long (convert to sizeof(int) for 32-bit files)
if (Image.Bits == 32) {
sw.PrimitiveMappings.Add(typeof(long), typeof(int));
sw.PrimitiveMappings.Add(typeof(ulong), typeof(uint));
}
sw.WriteObject(Image.MapVATR(CodeRegistrationPointer), CodeRegistration);
isModified = true; isModified = true;
// Things we need from Il2CppMetadataRegistration // Things we need from Il2CppMetadataRegistration
@@ -766,11 +796,16 @@ namespace Il2CppInspector
MetadataRegistration.pfieldOffsets = fieldOffsets.ptr; MetadataRegistration.pfieldOffsets = fieldOffsets.ptr;
MetadataRegistration.fieldOffsetsCount = fieldOffsets.count; MetadataRegistration.fieldOffsetsCount = fieldOffsets.count;
// Force MetadataRegistration to pass validation in Il2CppBinary.Configure() // Zero out any unprocessed items
MetadataRegistration.typeDefinitionsSizesCount = 0; MetadataRegistration.typeDefinitionsSizesCount = 0;
MetadataRegistration.genericClassesCount = MetadataRegistration.genericInstsCount + 1; MetadataRegistration.typeDefinitionsSizes = 0;
MetadataRegistration.genericClassesCount = 0;
MetadataRegistration.genericClasses = 0;
MetadataRegistration.methodReferencesCount = 0;
MetadataRegistration.methodReferences = 0;
// TODO: Write changes to stream // Write changes to stream
sw.WriteObject(Image.MapVATR(MetadataRegistrationPointer), MetadataRegistration);
StatusUpdate("Analyzing IL2CPP image"); StatusUpdate("Analyzing IL2CPP image");
} }