From 7120970ece8b6745a22ab45be1e782ef7811f056 Mon Sep 17 00:00:00 2001 From: LukeFZ <17146677+LukeFZ@users.noreply.github.com> Date: Fri, 1 Dec 2023 08:14:12 +0100 Subject: [PATCH] Use actual size of static array initializers --- Il2CppInspector.Common/IL2CPP/Il2CppBinary.cs | 5 +++++ .../IL2CPP/Il2CppBinaryClasses.cs | 8 +++++++ .../IL2CPP/Il2CppInspector.cs | 1 + .../Outputs/AssemblyShims.cs | 22 +++++++++++++++++-- .../Outputs/CSharpCodeStubs.cs | 4 ++-- Il2CppInspector.Common/Reflection/TypeInfo.cs | 2 ++ 6 files changed, 38 insertions(+), 4 deletions(-) diff --git a/Il2CppInspector.Common/IL2CPP/Il2CppBinary.cs b/Il2CppInspector.Common/IL2CPP/Il2CppBinary.cs index d08547f..e6de2ad 100644 --- a/Il2CppInspector.Common/IL2CPP/Il2CppBinary.cs +++ b/Il2CppInspector.Common/IL2CPP/Il2CppBinary.cs @@ -89,6 +89,8 @@ namespace Il2CppInspector // One assembly may contain multiple modules public Dictionary Modules { get; private set; } + public List TypeDefinitionSizes { get; private set; } + // Status update callback private EventHandler OnStatusUpdate { get; set; } private void StatusUpdate(string status) => OnStatusUpdate?.Invoke(this, status); @@ -424,6 +426,9 @@ namespace Il2CppInspector GenericMethodInvokerIndices.Add(MethodSpecs[tableEntry.genericMethodIndex], tableEntry.indices.invokerIndex); } + TypeDefinitionSizes = Image.ReadMappedObjectPointerArray( + MetadataRegistration.typeDefinitionsSizes, (int) MetadataRegistration.typeDefinitionsSizesCount); + // Plugin hook to pre-process binary isModified |= PluginHooks.PostProcessBinary(this).IsStreamModified; } diff --git a/Il2CppInspector.Common/IL2CPP/Il2CppBinaryClasses.cs b/Il2CppInspector.Common/IL2CPP/Il2CppBinaryClasses.cs index 9138f8b..dbfe032 100644 --- a/Il2CppInspector.Common/IL2CPP/Il2CppBinaryClasses.cs +++ b/Il2CppInspector.Common/IL2CPP/Il2CppBinaryClasses.cs @@ -291,4 +291,12 @@ namespace Il2CppInspector [Version(Min = 27.1)] public int adjustorThunk; } + + public class Il2CppTypeDefinitionSizes + { + public uint instanceSize; + public int nativeSize; + public uint staticFieldsSize; + public uint threadStaticFieldsSize; + } } diff --git a/Il2CppInspector.Common/IL2CPP/Il2CppInspector.cs b/Il2CppInspector.Common/IL2CPP/Il2CppInspector.cs index 67d33ed..d3d4160 100644 --- a/Il2CppInspector.Common/IL2CPP/Il2CppInspector.cs +++ b/Il2CppInspector.Common/IL2CPP/Il2CppInspector.cs @@ -66,6 +66,7 @@ namespace Il2CppInspector public Il2CppMethodSpec[] MethodSpecs => Binary.MethodSpecs; public Dictionary GenericMethodPointers { get; } public Dictionary GenericMethodInvokerIndices => Binary.GenericMethodInvokerIndices; + public List TypeDefinitionSizes => Binary.TypeDefinitionSizes; // TODO: Finish all file access in the constructor and eliminate the need for this public IFileFormatStream BinaryImage => Binary.Image; diff --git a/Il2CppInspector.Common/Outputs/AssemblyShims.cs b/Il2CppInspector.Common/Outputs/AssemblyShims.cs index 4c61e64..016b6f3 100644 --- a/Il2CppInspector.Common/Outputs/AssemblyShims.cs +++ b/Il2CppInspector.Common/Outputs/AssemblyShims.cs @@ -7,6 +7,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Linq; using dnlib.DotNet; @@ -45,12 +46,26 @@ namespace Il2CppInspector.Outputs // Attribute arguments var attrArgs = args.Select(a => - new CANamedArgument(true, module.CorLibTypes.String, a.prop, new CAArgument(module.CorLibTypes.String, a.value))); + { + var arg = ToArgument(a.value); + return new CANamedArgument(true, arg.Type, a.prop, arg); + }).ToList(); var attr = new CustomAttribute(attCtorRef, null, attrArgs); def.CustomAttributes.Add(attr); return attr; + + CAArgument ToArgument(object value) + { + return value switch + { + string str => new CAArgument(module.CorLibTypes.String, str), + int i => new CAArgument(module.CorLibTypes.Int32, i), + bool b => new CAArgument(module.CorLibTypes.Boolean, b), + _ => throw new UnreachableException() + }; + } } } @@ -249,7 +264,10 @@ namespace Il2CppInspector.Outputs // Static array initializer preview if (field.HasFieldRVA) { - var preview = model.Package.Metadata.ReadBytes((long) field.DefaultValueMetadataAddress, 8); + // Attempt to get field size + var fieldSize = field.FieldType.Sizes.nativeSize; + + var preview = model.Package.Metadata.ReadBytes((long) field.DefaultValueMetadataAddress, fieldSize); var previewText = string.Join(" ", preview.Select(b => $"{b:x2}")); mField.AddAttribute(module, metadataPreviewAttribute, ("Data", previewText)); diff --git a/Il2CppInspector.Common/Outputs/CSharpCodeStubs.cs b/Il2CppInspector.Common/Outputs/CSharpCodeStubs.cs index cbb8585..d2a0338 100644 --- a/Il2CppInspector.Common/Outputs/CSharpCodeStubs.cs +++ b/Il2CppInspector.Common/Outputs/CSharpCodeStubs.cs @@ -426,10 +426,10 @@ namespace Il2CppInspector.Outputs sb.Append($" // Metadata: {field.DefaultValueMetadataAddress.ToAddressString()}"); // For static array initializers, output metadata address and preview if (field.HasFieldRVA && !SuppressMetadata) { - var preview = model.Package.Metadata.ReadBytes((long) field.DefaultValueMetadataAddress, 8); + var preview = model.Package.Metadata.ReadBytes((long) field.DefaultValueMetadataAddress, field.FieldType.Sizes.nativeSize); var previewText = string.Join(" ", preview.Select(b => $"{b:x2}")); - sb.Append($" // Starts with: {previewText} - Metadata: {field.DefaultValueMetadataAddress.ToAddressString()}"); + sb.Append($" // Static value: {previewText} - Metadata: {field.DefaultValueMetadataAddress.ToAddressString()}"); } sb.Append("\n"); } diff --git a/Il2CppInspector.Common/Reflection/TypeInfo.cs b/Il2CppInspector.Common/Reflection/TypeInfo.cs index cfc54eb..b3d66ef 100644 --- a/Il2CppInspector.Common/Reflection/TypeInfo.cs +++ b/Il2CppInspector.Common/Reflection/TypeInfo.cs @@ -20,6 +20,7 @@ namespace Il2CppInspector.Reflection { // IL2CPP-specific data public Il2CppTypeDefinition Definition { get; } + public Il2CppTypeDefinitionSizes Sizes { get; } public int Index { get; } = -1; // This dictionary will cache all instantiated generic types out of this definition. @@ -739,6 +740,7 @@ namespace Il2CppInspector.Reflection var pkg = Assembly.Model.Package; Definition = pkg.TypeDefinitions[typeIndex]; + Sizes = pkg.TypeDefinitionSizes[typeIndex]; MetadataToken = (int) Definition.token; Index = typeIndex; Namespace = Regex.Replace(pkg.Strings[Definition.namespaceIndex], @"[^A-Za-z0-9_\-\.<>{}]", "");