From f6f012b68c8810beb02796d727df9279f61a034d Mon Sep 17 00:00:00 2001 From: Sam Byass Date: Wed, 27 Oct 2021 10:38:16 +0100 Subject: [PATCH] Cleanup post-29 restorer, performance optimizations --- Cpp2IL.Core/AttributeRestorerPost29.cs | 28 +++++++++++--------------- Cpp2IL.sln.DotSettings.user | 7 +++---- Cpp2IL/Program.cs | 8 ++++++-- 3 files changed, 21 insertions(+), 22 deletions(-) diff --git a/Cpp2IL.Core/AttributeRestorerPost29.cs b/Cpp2IL.Core/AttributeRestorerPost29.cs index 791b66ec..4d03ccba 100644 --- a/Cpp2IL.Core/AttributeRestorerPost29.cs +++ b/Cpp2IL.Core/AttributeRestorerPost29.cs @@ -73,11 +73,11 @@ public static List GetCustomAttributesByAttributeIndex(Il2CppIm if (customAttributeIndex < 0) return ret; //No attributes - var attributeDataRange = LibCpp2IlMain.TheMetadata!.AttributeDataRanges[customAttributeIndex]; - var next = LibCpp2IlMain.TheMetadata!.AttributeDataRanges[customAttributeIndex + 1]; + var attributeDataRange = LibCpp2IlMain.TheMetadata.AttributeDataRanges[customAttributeIndex]; + // var next = LibCpp2IlMain.TheMetadata.AttributeDataRanges[customAttributeIndex + 1]; var start = LibCpp2IlMain.TheMetadata.metadataHeader.attributeDataOffset + attributeDataRange.startOffset; - var end = LibCpp2IlMain.TheMetadata.metadataHeader.attributeDataOffset + next.startOffset; + // var end = LibCpp2IlMain.TheMetadata.metadataHeader.attributeDataOffset + next.startOffset; //Now we start actually reading. Start is a pointer to the address in the metadata file where the attribute data is. @@ -122,11 +122,11 @@ private static CustomAttribute ReadAndCreateCustomAttribute(ModuleDefinition mod bytesRead += compressedRead; pos += compressedRead; - var numFields = LibCpp2IlMain.TheMetadata!.ReadUnityCompressedUIntAtRawAddr(pos, out compressedRead); + var numFields = LibCpp2IlMain.TheMetadata.ReadUnityCompressedUIntAtRawAddr(pos, out compressedRead); bytesRead += compressedRead; pos += compressedRead; - var numProps = LibCpp2IlMain.TheMetadata!.ReadUnityCompressedUIntAtRawAddr(pos, out compressedRead); + var numProps = LibCpp2IlMain.TheMetadata.ReadUnityCompressedUIntAtRawAddr(pos, out compressedRead); bytesRead += compressedRead; pos += compressedRead; @@ -167,7 +167,7 @@ private static CustomAttribute ReadAndCreateCustomAttribute(ModuleDefinition mod fieldIndex = -(fieldIndex + 1); var declaringType = LibCpp2IlMain.TheMetadata.typeDefs[typeIndex]; - field = declaringType!.Fields![fieldIndex].AsManaged(); + field = declaringType.Fields![fieldIndex].AsManaged(); } else { @@ -204,7 +204,7 @@ private static CustomAttribute ReadAndCreateCustomAttribute(ModuleDefinition mod propIndex = -(propIndex + 1); var declaringType = LibCpp2IlMain.TheMetadata.typeDefs[typeIndex]; - prop = declaringType!.Properties![propIndex].AsManaged(); + prop = declaringType.Properties![propIndex].AsManaged(); } else { @@ -224,11 +224,11 @@ private static CustomAttribute ReadAndCreateCustomAttribute(ModuleDefinition mod catch (Exception e) { Logger.WarnNewline($"Failed to parse custom attribute {constructor.DeclaringType!.FullName} due to an exception: {e.GetType()}: {e.Message}"); - return MakeFallbackAttribute(module, constructor.AsManaged()); + return MakeFallbackAttribute(module, constructor.AsManaged()) ?? throw new("Failed to resolve AttributeAttribute type"); } } - private static CustomAttribute MakeFallbackAttribute(ModuleDefinition module, MethodDefinition constructor) + private static CustomAttribute? MakeFallbackAttribute(ModuleDefinition module, MethodDefinition constructor) { var attributeType = module.Types.SingleOrDefault(t => t.Namespace == AssemblyPopulator.InjectedNamespaceName && t.Name == "AttributeAttribute"); @@ -397,11 +397,9 @@ private static CustomAttribute MakeFallbackAttribute(ModuleDefinition module, Me case Il2CppTypeEnum.IL2CPP_TYPE_OBJECT: case Il2CppTypeEnum.IL2CPP_TYPE_GENERICINST: //LibIl2Cpp is slightly unclear here. It checks that they're null, but also doesn't increment the ptr. - throw new Exception("Object not implemented"); - break; + throw new("Object not implemented"); case Il2CppTypeEnum.IL2CPP_TYPE_IL2CPP_TYPE_INDEX: var typeIndex = md.ReadUnityCompressedIntAtRawAddr(pos, out var compressedBytesRead); - pos += compressedBytesRead; bytesRead += compressedBytesRead; if (typeIndex == -1) ret = null; @@ -409,8 +407,8 @@ private static CustomAttribute MakeFallbackAttribute(ModuleDefinition module, Me { //Weirdly, libil2cpp checks "Deserialize managed object" boolean here //But as far as I can see, it's actually returning typeof(x) - var il2cppType = LibCpp2IlMain.Binary!.GetType(typeIndex); - ret = Utils.TryResolveTypeReflectionData(LibCpp2ILUtils.GetTypeReflectionData(il2cppType)); + var il2CppType = LibCpp2IlMain.Binary!.GetType(typeIndex); + ret = Utils.TryResolveTypeReflectionData(LibCpp2ILUtils.GetTypeReflectionData(il2CppType)); if (ret == null) throw new($"Failed to resolve type reflection data for type index {typeIndex}"); @@ -435,8 +433,6 @@ private static Il2CppTypeEnum ReadBlobType(long pos, out int bytesRead, out Type { var enumTypeIndex = LibCpp2IlMain.TheMetadata.ReadUnityCompressedIntAtRawAddr(pos, out var compressedBytesRead); bytesRead += compressedBytesRead; - pos += compressedBytesRead; - var rawType = LibCpp2IlMain.Binary!.GetType(enumTypeIndex); var typeDef = LibCpp2IlReflection.GetTypeDefinitionByTypeIndex(enumTypeIndex)!; type = typeDef.AsManaged(); //Get enum type ret = LibCpp2IlMain.Binary!.GetType(typeDef.elementTypeIndex).type; //Get enum underlying type's type enum diff --git a/Cpp2IL.sln.DotSettings.user b/Cpp2IL.sln.DotSettings.user index a991c739..d3a1da29 100644 --- a/Cpp2IL.sln.DotSettings.user +++ b/Cpp2IL.sln.DotSettings.user @@ -1,9 +1,8 @@  - <SessionState ContinuousTestingMode="0" IsActive="True" Name="Metadata24_1_64BitSupportIsPresent" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"> - <TestAncestor> - <TestId>xUnit::EB3CFC80-2125-48D2-AA2F-548F5AA58342::net5.0::LibCpp2ILTests.Tests</TestId> - </TestAncestor> + + <SessionState ContinuousTestingMode="0" IsActive="True" Name="All tests from Solution" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"> + <Solution /> </SessionState> True True \ No newline at end of file diff --git a/Cpp2IL/Program.cs b/Cpp2IL/Program.cs index 9b08a0c2..1bb6e4bc 100644 --- a/Cpp2IL/Program.cs +++ b/Cpp2IL/Program.cs @@ -4,6 +4,7 @@ using System.IO; using System.IO.Compression; using System.Linq; +using System.Runtime; using CommandLine; using Cpp2IL.Core; using Cpp2IL.Core.Exceptions; @@ -244,6 +245,8 @@ public static int MainWithArgs(Cpp2IlRuntimeArgs runtimeArgs) if (!runtimeArgs.Valid) throw new SoftException("Arguments have Valid = false"); + GCSettings.LatencyMode = GCLatencyMode.SustainedLowLatency; + ConsoleLogger.ShowVerbose = runtimeArgs.EnableVerboseLogging; Cpp2IlApi.InitializeLibCpp2Il(runtimeArgs.PathToAssembly, runtimeArgs.PathToMetadata, runtimeArgs.UnityVersion, runtimeArgs.EnableRegistrationPrompts); @@ -255,8 +258,9 @@ public static int MainWithArgs(Cpp2IlRuntimeArgs runtimeArgs) BaseKeyFunctionAddresses? keyFunctionAddresses = null; - //We have to always run key function scan (if we can), so that attribute reconstruction can run. - if (LibCpp2IlMain.Binary?.InstructionSet != InstructionSet.ARM32) + //We need to run key function sweep if we can for attribute restoration + //or if we want to analyze. But we DON'T need it for restoration on v29 + if (LibCpp2IlMain.Binary?.InstructionSet != InstructionSet.ARM32 && (LibCpp2IlMain.MetadataVersion < 29 || runtimeArgs.EnableAnalysis)) { Logger.InfoNewline("Running Scan for Known Functions...");