Ejemplo n.º 1
0
        private static void HookClassFromType()
        {
            LogSupport.Info("xref scanning type to class");
            var lib = LoadLibrary("GameAssembly.dll");

            LogSupport.Info($"lib: {lib}");
            var classFromTypeEntryPoint = GetProcAddress(lib, nameof(IL2CPP.il2cpp_class_from_il2cpp_type));

            LogSupport.Info($"hook_method: {classFromTypeEntryPoint}");


            var scanner      = new XrefScanner(classFromTypeEntryPoint);
            var targetMethod = scanner.JumpTargets().Single();

            LogSupport.Info($"target_method: {targetMethod}");

            if (targetMethod == IntPtr.Zero)
            {
                return;
            }

            IntPtr *targetVarPointer = &targetMethod;

            DoHook((IntPtr)targetVarPointer,
                   Marshal.GetFunctionPointerForDelegate(new TypeToClassDelegate(ClassFromTypePatch)));
            ourOriginalTypeToClassMethod = Marshal.GetDelegateForFunctionPointer <TypeToClassDelegate>(targetMethod);

            LogSupport.Info("patched");
        }
Ejemplo n.º 2
0
        public static void DoPass(RewriteGlobalContext context)
        {
            var targetAssembly = context.TryGetAssemblyByName("UnityEngine");

            if (targetAssembly == null)
            {
                LogSupport.Info("No UnityEngine.dll, will not generate forwarders");
                return;
            }

            var targetModule = targetAssembly.NewAssembly.MainModule;

            foreach (var assemblyRewriteContext in context.Assemblies)
            {
                if (!assemblyRewriteContext.NewAssembly.Name.Name.StartsWith("UnityEngine."))
                {
                    continue;
                }
                foreach (var mainModuleType in assemblyRewriteContext.NewAssembly.MainModule.Types)
                {
                    var importedType = targetModule.ImportReference(mainModuleType);
                    var exportedType = new ExportedType(mainModuleType.Namespace, mainModuleType.Name, importedType.Module, importedType.Scope)
                    {
                        Attributes = TypeAttributes.Forwarder
                    };
                    targetModule.ExportedTypes.Add(exportedType);

                    AddNestedTypes(mainModuleType, exportedType, targetModule);
                }
            }
        }
Ejemplo n.º 3
0
        public void InitPrototype <T>(List <T> list, string path, string nameKey)
        {
            LogSupport.Info("start init " + typeof(T).Name);
            try
            {
                list.Clear();
                if (Directory.Exists(path))
                {
                    var subDir = Directory.GetDirectories(path);
                    foreach (var dir in subDir)
                    {
                        var folder = new DirectoryInfo(dir);
                        foreach (FileInfo tFile in folder.GetFiles())
                        {
                            if ((tFile.Name.EndsWith("dll") || tFile.Name.EndsWith("exe")) && tFile.Name.Contains(nameKey))
                            {
                                Assembly ass = Assembly.LoadFile(tFile.DirectoryName + "\\" + tFile.Name);
                                var      tl  = ass.GetTypes().ToList();
                                tl.ForEach(v =>
                                {
                                    if (v.GetInterface(typeof(T).Name) != null)
                                    {
                                        object obj = Activator.CreateInstance(v);
                                        var dp     = (T)obj;
                                        if (dp != null)
                                        {
                                            LogSupport.Info("loading:" + tFile.Name);
                                            //dp.Initialize();

                                            list.Add(dp);
                                        }
                                    }
                                });
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                LogSupport.Error(ex);
            }
            LogSupport.Info("Loaded count:" + list.Count.ToString());
        }
        public static void DoPass(RewriteGlobalContext context)
        {
            int methodsUnstripped = 0;
            int methodsIgnored    = 0;

            foreach (var unityAssembly in context.UnityAssemblies.Assemblies)
            {
                var processedAssembly = context.TryGetAssemblyByName(unityAssembly.Name.Name);
                if (processedAssembly == null)
                {
                    continue;
                }
                var imports = processedAssembly.Imports;

                foreach (var unityType in unityAssembly.MainModule.Types)
                {
                    var processedType = processedAssembly.TryGetTypeByName(unityType.FullName);
                    if (processedType == null)
                    {
                        continue;
                    }

                    foreach (var unityMethod in unityType.Methods)
                    {
                        if (unityMethod.Name == ".cctor" || unityMethod.Name == ".ctor")
                        {
                            continue;
                        }
                        if (unityMethod.IsAbstract)
                        {
                            continue;
                        }

                        var processedMethod = processedType.TryGetMethodByUnityAssemblyMethod(unityMethod);
                        if (processedMethod != null)
                        {
                            continue;
                        }

                        var returnType = ResolveTypeInNewAssemblies(context, unityMethod.ReturnType, imports);
                        if (returnType == null)
                        {
                            LogSupport.Trace($"Method {unityMethod} has unsupported return type {unityMethod.ReturnType}");
                            methodsIgnored++;
                            continue;
                        }

                        var newMethod       = new MethodDefinition(unityMethod.Name, unityMethod.Attributes & ~MethodAttributes.MemberAccessMask | MethodAttributes.Public, returnType);
                        var hadBadParameter = false;
                        foreach (var unityMethodParameter in unityMethod.Parameters)
                        {
                            var convertedType = ResolveTypeInNewAssemblies(context, unityMethodParameter.ParameterType, imports);
                            if (convertedType == null)
                            {
                                hadBadParameter = true;
                                LogSupport.Trace($"Method {unityMethod} has unsupported parameter type {unityMethodParameter.ParameterType}");
                                break;
                            }

                            newMethod.Parameters.Add(new ParameterDefinition(unityMethodParameter.Name, unityMethodParameter.Attributes, convertedType));
                        }

                        if (hadBadParameter)
                        {
                            methodsIgnored++;
                            continue;
                        }

                        foreach (var unityMethodGenericParameter in unityMethod.GenericParameters)
                        {
                            var newParameter = new GenericParameter(unityMethodGenericParameter.Name, newMethod);
                            newParameter.Attributes = unityMethodGenericParameter.Attributes;
                            foreach (var genericParameterConstraint in unityMethodGenericParameter.Constraints)
                            {
                                if (genericParameterConstraint.ConstraintType.FullName == "System.ValueType")
                                {
                                    continue;
                                }
                                if (genericParameterConstraint.ConstraintType.Resolve().IsInterface)
                                {
                                    continue;
                                }

                                var newType = ResolveTypeInNewAssemblies(context, genericParameterConstraint.ConstraintType, imports);
                                if (newType != null)
                                {
                                    newParameter.Constraints.Add(new GenericParameterConstraint(newType));
                                }
                            }

                            newMethod.GenericParameters.Add(newParameter);
                        }

                        if ((unityMethod.ImplAttributes & MethodImplAttributes.InternalCall) != 0)
                        {
                            var delegateType = UnstripGenerator.CreateDelegateTypeForICallMethod(unityMethod, newMethod, imports);
                            processedType.NewType.NestedTypes.Add(delegateType);
                            delegateType.DeclaringType = processedType.NewType;

                            processedType.NewType.Methods.Add(newMethod);

                            var delegateField = UnstripGenerator.GenerateStaticCtorSuffix(processedType.NewType, delegateType, unityMethod, imports);
                            UnstripGenerator.GenerateInvokerMethodBody(newMethod, delegateField, delegateType, processedType, imports);
                        }
                        else
                        {
                            Pass81FillUnstrippedMethodBodies.PushMethod(unityMethod, newMethod, processedType, imports);
                            processedType.NewType.Methods.Add(newMethod);
                        }

                        if (unityMethod.IsGetter)
                        {
                            GetOrCreateProperty(unityMethod, newMethod).GetMethod = newMethod;
                        }
                        else if (unityMethod.IsSetter)
                        {
                            GetOrCreateProperty(unityMethod, newMethod).SetMethod = newMethod;
                        }

                        var paramsMethod = context.CreateParamsMethod(unityMethod, newMethod, imports, type => ResolveTypeInNewAssemblies(context, type, imports));
                        if (paramsMethod != null)
                        {
                            processedType.NewType.Methods.Add(paramsMethod);
                        }

                        methodsUnstripped++;
                    }
                }
            }

            LogSupport.Info(""); // finish the progress line
            LogSupport.Info($"{methodsUnstripped} methods restored");
            LogSupport.Info($"{methodsIgnored} methods failed to restore");
        }
        public static void RegisterTypeInIl2Cpp <T>() where T : class
        {
            var type = typeof(T);

            if (type.IsGenericType || type.IsGenericTypeDefinition)
            {
                throw new ArgumentException($"Type {type} is generic and can't be used in il2cpp");
            }

            var currentPointer = Il2CppClassPointerStore <T> .NativeClassPtr;

            if (currentPointer != IntPtr.Zero)
            {
                throw new ArgumentException($"Type {type} is already registered in il2cpp");
            }

            var baseType         = type.BaseType;
            var baseClassPointer = UnityVersionHandler.Wrap((Il2CppClass *)ReadClassPointerForType(baseType));

            if (baseClassPointer == null)
            {
                throw new ArgumentException($"Base class {baseType} of class {type} is not registered in il2cpp");
            }

            if ((baseClassPointer.Bitfield1 & ClassBitfield1.valuetype) != 0 || (baseClassPointer.Bitfield1 & ClassBitfield1.enumtype) != 0)
            {
                throw new ArgumentException($"Base class {baseType} is value type and can't be inherited from");
            }

            if ((baseClassPointer.Bitfield1 & ClassBitfield1.is_generic) != 0)
            {
                throw new ArgumentException($"Base class {baseType} is generic and can't be inherited from");
            }

            if ((baseClassPointer.Flags & Il2CppClassAttributes.TYPE_ATTRIBUTE_SEALED) != 0)
            {
                throw new ArgumentException($"Base class {baseType} is sealed and can't be inherited from");
            }

            if ((baseClassPointer.Flags & Il2CppClassAttributes.TYPE_ATTRIBUTE_INTERFACE) != 0)
            {
                throw new ArgumentException($"Base class {baseType} is an interface and can't be inherited from");
            }

            lock (InjectedTypes)
                if (!InjectedTypes.Add(typeof(T).FullName))
                {
                    throw new ArgumentException($"Type with FullName {typeof(T).FullName} is already injected. Don't inject the same type twice, or use a different namespace");
                }

            if (ourOriginalTypeToClassMethod == null)
            {
                HookClassFromType();
            }

            var classPointer = UnityVersionHandler.NewClass(baseClassPointer.VtableCount);

            classPointer.Image        = FakeImage;
            classPointer.Parent       = baseClassPointer.ClassPointer;
            classPointer.ElementClass = classPointer.Class = classPointer.CastClass = classPointer.ClassPointer;
            classPointer.NativeSize   = -1;
            classPointer.ActualSize   = classPointer.InstanceSize = baseClassPointer.InstanceSize + (uint)IntPtr.Size;
            classPointer.Bitfield1    = ClassBitfield1.initialized | ClassBitfield1.initialized_and_no_error |
                                        ClassBitfield1.size_inited;
            classPointer.Bitfield2 = ClassBitfield2.has_finalize | ClassBitfield2.is_vtable_initialized;
            classPointer.Name      = Marshal.StringToHGlobalAnsi(type.Name);
            classPointer.Namespace = Marshal.StringToHGlobalAnsi(type.Namespace);

            classPointer.ThisArg.type           = classPointer.ByValArg.type = Il2CppTypeEnum.IL2CPP_TYPE_CLASS;
            classPointer.ThisArg.mods_byref_pin = 64;

            classPointer.Flags = baseClassPointer.Flags; // todo: adjust flags?

            var eligibleMethods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly).Where(IsMethodEligible).ToArray();
            var methodCount     = 2 + eligibleMethods.Length; // 1 is the finalizer, 1 is empty ctor

            classPointer.MethodCount = (ushort)methodCount;
            var methodPointerArray = (Il2CppMethodInfo **)Marshal.AllocHGlobal(methodCount * IntPtr.Size);

            classPointer.Methods = methodPointerArray;

            methodPointerArray[0] = ConvertStaticMethod(FinalizeDelegate, "Finalize", classPointer);
            methodPointerArray[1] = ConvertStaticMethod(CreateEmptyCtor(type), ".ctor", classPointer);
            for (var i = 0; i < eligibleMethods.Length; i++)
            {
                var methodInfo = eligibleMethods[i];
                methodPointerArray[i + 2] = ConvertMethodInfo(methodInfo, classPointer);
            }

            var vTablePointer     = (VirtualInvokeData *)classPointer.VTable;
            var baseVTablePointer = (VirtualInvokeData *)baseClassPointer.VTable;

            classPointer.VtableCount = baseClassPointer.VtableCount;
            for (var i = 0; i < classPointer.VtableCount; i++)
            {
                vTablePointer[i] = baseVTablePointer[i];
                if (Marshal.PtrToStringAnsi(vTablePointer[i].method->name) == "Finalize") // slot number is not static
                {
                    vTablePointer[i].method    = methodPointerArray[0];
                    vTablePointer[i].methodPtr = methodPointerArray[0]->methodPointer;
                }
            }

            var newCounter = Interlocked.Decrement(ref ourClassOverrideCounter);

            FakeTokenClasses[newCounter] = classPointer.Pointer;
            classPointer.ByValArg.data   = classPointer.ThisArg.data = (IntPtr)newCounter;

            RuntimeSpecificsStore.SetClassInfo(classPointer.Pointer, true, true);
            Il2CppClassPointerStore <T> .NativeClassPtr = classPointer.Pointer;

            LogSupport.Info($"Registered mono type {typeof(T)} in il2cpp domain");
        }
Ejemplo n.º 6
0
        public static void Main(UnhollowerOptions options)
        {
            if (string.IsNullOrEmpty(options.SourceDir))
            {
                Console.WriteLine("No input dir specified; use -h for help");
                return;
            }

            if (string.IsNullOrEmpty(options.OutputDir))
            {
                Console.WriteLine("No target dir specified; use -h for help");
                return;
            }
            if (string.IsNullOrEmpty(options.MscorlibPath))
            {
                Console.WriteLine("No mscorlib specified; use -h for help");
                return;
            }

            if (!Directory.Exists(options.OutputDir))
            {
                Directory.CreateDirectory(options.OutputDir);
            }

            RewriteGlobalContext rewriteContext;

            using (new TimingCookie("Reading assemblies"))
                rewriteContext = new RewriteGlobalContext(options, Directory.EnumerateFiles(options.SourceDir, "*.dll"));

            using (new TimingCookie("Computing renames"))
                Pass05CreateRenameGroups.DoPass(rewriteContext);
            using (new TimingCookie("Creating typedefs"))
                Pass10CreateTypedefs.DoPass(rewriteContext);
            using (new TimingCookie("Computing struct blittability"))
                Pass11ComputeTypeSpecifics.DoPass(rewriteContext);
            using (new TimingCookie("Filling typedefs"))
                Pass12FillTypedefs.DoPass(rewriteContext);
            using (new TimingCookie("Filling generic constraints"))
                Pass13FillGenericConstraints.DoPass(rewriteContext);
            using (new TimingCookie("Creating members"))
                Pass15GenerateMemberContexts.DoPass(rewriteContext);
            using (new TimingCookie("Scanning method cross-references"))
                Pass16ScanMethodRefs.DoPass(rewriteContext, options);
            using (new TimingCookie("Finalizing method declarations"))
                Pass18FinalizeMethodContexts.DoPass(rewriteContext);
            LogSupport.Info($"{Pass18FinalizeMethodContexts.TotalPotentiallyDeadMethods} total potentially dead methods");
            using (new TimingCookie("Filling method parameters"))
                Pass19CopyMethodParameters.DoPass(rewriteContext);

            using (new TimingCookie("Creating static constructors"))
                Pass20GenerateStaticConstructors.DoPass(rewriteContext);
            using (new TimingCookie("Creating value type fields"))
                Pass21GenerateValueTypeFields.DoPass(rewriteContext);
            using (new TimingCookie("Creating enums"))
                Pass22GenerateEnums.DoPass(rewriteContext);
            using (new TimingCookie("Creating IntPtr constructors"))
                Pass23GeneratePointerConstructors.DoPass(rewriteContext);
            using (new TimingCookie("Creating type getters"))
                Pass24GenerateTypeStaticGetters.DoPass(rewriteContext);
            using (new TimingCookie("Creating non-blittable struct constructors"))
                Pass25GenerateNonBlittableValueTypeDefaultCtors.DoPass(rewriteContext);

            using (new TimingCookie("Creating generic method static constructors"))
                Pass30GenerateGenericMethodStoreConstructors.DoPass(rewriteContext);
            using (new TimingCookie("Creating field accessors"))
                Pass40GenerateFieldAccessors.DoPass(rewriteContext);
            using (new TimingCookie("Filling methods"))
                Pass50GenerateMethods.DoPass(rewriteContext);
            using (new TimingCookie("Generating implicit conversions"))
                Pass60AddImplicitConversions.DoPass(rewriteContext);
            using (new TimingCookie("Creating properties"))
                Pass70GenerateProperties.DoPass(rewriteContext);

            if (options.UnityBaseLibsDir != null)
            {
                using (new TimingCookie("Unstripping types"))
                    Pass79UnstripTypes.DoPass(rewriteContext);
                using (new TimingCookie("Unstripping fields"))
                    Pass80UnstripFields.DoPass(rewriteContext);
                using (new TimingCookie("Unstripping methods"))
                    Pass80UnstripMethods.DoPass(rewriteContext);
                using (new TimingCookie("Unstripping method bodies"))
                    Pass81FillUnstrippedMethodBodies.DoPass(rewriteContext);
            }
            else
            {
                LogSupport.Warning("Not performing unstripping as unity libs are not specified");
            }

            using (new TimingCookie("Generating forwarded types"))
                Pass89GenerateForwarders.DoPass(rewriteContext);

            using (new TimingCookie("Writing xref cache"))
                Pass89GenerateMethodXrefCache.DoPass(rewriteContext, options);

            using (new TimingCookie("Writing assemblies"))
                Pass90WriteToDisk.DoPass(rewriteContext, options);

            using (new TimingCookie("Writing method pointer map"))
                Pass91GenerateMethodPointerMap.DoPass(rewriteContext, options);

            if (!options.NoCopyUnhollowerLibs)
            {
                File.Copy(typeof(IL2CPP).Assembly.Location, Path.Combine(options.OutputDir, typeof(IL2CPP).Assembly.GetName().Name + ".dll"), true);
                File.Copy(typeof(RuntimeLibMarker).Assembly.Location, Path.Combine(options.OutputDir, typeof(RuntimeLibMarker).Assembly.GetName().Name + ".dll"), true);
                File.Copy(typeof(Decoder).Assembly.Location, Path.Combine(options.OutputDir, typeof(Decoder).Assembly.GetName().Name + ".dll"), true);
            }

            LogSupport.Info("Done!");

            rewriteContext.Dispose();
        }
Ejemplo n.º 7
0
 public void Dispose()
 {
     LogSupport.Info($"Done in {myStopwatch.Elapsed}");
 }
Ejemplo n.º 8
0
 public TimingCookie(string message)
 {
     LogSupport.Info(message + "... ");
     myStopwatch = Stopwatch.StartNew();
 }
        public static void GenerateDeobfuscationMap(UnhollowerOptions options)
        {
            if (string.IsNullOrEmpty(options.SourceDir))
            {
                Console.WriteLine("No input dir specified; use -h for help");
                return;
            }

            if (string.IsNullOrEmpty(options.OutputDir))
            {
                Console.WriteLine("No target dir specified; use -h for help");
                return;
            }
            if (string.IsNullOrEmpty(options.DeobfuscationNewAssembliesPath))
            {
                Console.WriteLine("No obfuscated assembly path specified; use -h for help");
                return;
            }

            if (!Directory.Exists(options.OutputDir))
            {
                Directory.CreateDirectory(options.OutputDir);
            }

            RewriteGlobalContext  rewriteContext;
            IIl2CppMetadataAccess inputAssemblies;
            IIl2CppMetadataAccess systemAssemblies;

            using (new TimingCookie("Reading assemblies"))
                inputAssemblies = new CecilMetadataAccess(Directory.EnumerateFiles(options.DeobfuscationNewAssembliesPath, "*.dll"));

            using (new TimingCookie("Reading system assemblies"))
            {
                if (!string.IsNullOrEmpty(options.SystemLibrariesPath))
                {
                    systemAssemblies = new CecilMetadataAccess(Directory.EnumerateFiles(options.SystemLibrariesPath, "*.dll")
                                                               .Where(it => Path.GetFileName(it).StartsWith("System.") || Path.GetFileName(it) == "mscorlib.dll" || Path.GetFileName(it) == "netstandard.dll"));
                }
                else
                {
                    systemAssemblies = new CecilMetadataAccess(new[] { options.MscorlibPath });
                }
            }

            using (new TimingCookie("Creating rewrite assemblies"))
                rewriteContext = new RewriteGlobalContext(options, inputAssemblies, systemAssemblies, NullMetadataAccess.Instance);
            using (new TimingCookie("Computing renames"))
                Pass05CreateRenameGroups.DoPass(rewriteContext);
            using (new TimingCookie("Creating typedefs"))
                Pass10CreateTypedefs.DoPass(rewriteContext);
            using (new TimingCookie("Computing struct blittability"))
                Pass11ComputeTypeSpecifics.DoPass(rewriteContext);
            using (new TimingCookie("Filling typedefs"))
                Pass12FillTypedefs.DoPass(rewriteContext);
            using (new TimingCookie("Filling generic constraints"))
                Pass13FillGenericConstraints.DoPass(rewriteContext);
            using (new TimingCookie("Creating members"))
                Pass15GenerateMemberContexts.DoPass(rewriteContext);


            RewriteGlobalContext  cleanContext;
            IIl2CppMetadataAccess cleanAssemblies;

            using (new TimingCookie("Reading clean assemblies"))
                cleanAssemblies = new CecilMetadataAccess(Directory.EnumerateFiles(options.SourceDir, "*.dll"));

            using (new TimingCookie("Creating clean rewrite assemblies"))
                cleanContext = new RewriteGlobalContext(options, cleanAssemblies, systemAssemblies, NullMetadataAccess.Instance);
            using (new TimingCookie("Computing clean assembly renames"))
                Pass05CreateRenameGroups.DoPass(cleanContext);
            using (new TimingCookie("Creating clean assembly typedefs"))
                Pass10CreateTypedefs.DoPass(cleanContext);


            var usedNames = new Dictionary <TypeDefinition, (string OldName, int Penalty, bool ForceNs)>();

            using var fileOutput = new FileStream(options.OutputDir + Path.DirectorySeparatorChar + "RenameMap.csv.gz", FileMode.Create, FileAccess.Write);
            using var gzipStream = new GZipStream(fileOutput, CompressionLevel.Optimal, true);
            using var writer     = new StreamWriter(gzipStream, Encoding.UTF8, 65536, true);

            void DoEnum(TypeRewriteContext obfuscatedType, TypeRewriteContext cleanType)
            {
                foreach (var originalTypeField in obfuscatedType.OriginalType.Fields)
                {
                    if (!originalTypeField.Name.IsObfuscated(obfuscatedType.AssemblyContext.GlobalContext.Options))
                    {
                        continue;
                    }
                    var matchedField = cleanType.OriginalType.Fields[obfuscatedType.OriginalType.Fields.IndexOf(originalTypeField)];

                    writer.WriteLine(obfuscatedType.NewType.GetNamespacePrefix() + "." + obfuscatedType.NewType.Name + "::" + Pass22GenerateEnums.GetUnmangledName(originalTypeField) + ";" + matchedField.Name + ";0");
                }
            }

            foreach (var assemblyContext in rewriteContext.Assemblies)
            {
                if (options.DeobfuscationGenerationAssemblies.Count > 0 &&
                    !options.DeobfuscationGenerationAssemblies.Contains(assemblyContext.NewAssembly.Name.Name))
                {
                    continue;
                }

                var cleanAssembly = cleanContext.GetAssemblyByName(assemblyContext.OriginalAssembly.Name.Name);

                void DoType(TypeRewriteContext typeContext, TypeRewriteContext?enclosingType)
                {
                    if (!typeContext.OriginalNameWasObfuscated)
                    {
                        return;
                    }

                    var cleanType = FindBestMatchType(typeContext, cleanAssembly, enclosingType);

                    if (cleanType.Item1 == null)
                    {
                        return;
                    }

                    if (!usedNames.TryGetValue(cleanType.Item1.NewType, out var existing) || existing.Item2 < cleanType.Item2)
                    {
                        usedNames[cleanType.Item1.NewType] = (typeContext.NewType.GetNamespacePrefix() + "." + typeContext.NewType.Name, cleanType.Item2, typeContext.OriginalType.Namespace != cleanType.Item1.OriginalType.Namespace);
                    }
                    else
                    {
                        return;
                    }

                    if (typeContext.OriginalType.IsEnum)
                    {
                        DoEnum(typeContext, cleanType.Item1);
                    }

                    foreach (var originalTypeNestedType in typeContext.OriginalType.NestedTypes)
                    {
                        DoType(typeContext.AssemblyContext.GetContextForOriginalType(originalTypeNestedType), cleanType.Item1);
                    }
                }

                foreach (var typeContext in assemblyContext.Types)
                {
                    if (typeContext.NewType.DeclaringType != null)
                    {
                        continue;
                    }

                    DoType(typeContext, null);
                }
            }


            foreach (var keyValuePair in usedNames)
            {
                writer.WriteLine(keyValuePair.Value.Item1 + ";" + (keyValuePair.Value.ForceNs ? keyValuePair.Key.Namespace + "." : "") + keyValuePair.Key.Name + ";" + keyValuePair.Value.Item2);
            }

            LogSupport.Info("Done!");

            rewriteContext.Dispose();
        }
Ejemplo n.º 10
0
 private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
 {
     LogSupport.Info(e.ToString());
 }
Ejemplo n.º 11
0
        public static void DoPass(RewriteGlobalContext context)
        {
            int fieldsUnstripped = 0;
            int fieldsIgnored    = 0;

            foreach (var unityAssembly in context.UnityAssemblies.Assemblies)
            {
                var processedAssembly = context.TryGetAssemblyByName(unityAssembly.Name.Name);
                if (processedAssembly == null)
                {
                    continue;
                }
                var imports = processedAssembly.Imports;

                foreach (var unityType in unityAssembly.MainModule.Types)
                {
                    var processedType = processedAssembly.TryGetTypeByName(unityType.FullName);
                    if (processedType == null)
                    {
                        continue;
                    }

                    if (!unityType.IsValueType || unityType.IsEnum)
                    {
                        continue;
                    }

                    foreach (var unityField in unityType.Fields)
                    {
                        if (unityField.IsStatic && !unityField.HasConstant)
                        {
                            continue;
                        }
                        if (processedType.NewType.IsExplicitLayout && !unityField.IsStatic)
                        {
                            continue;
                        }

                        var processedField = processedType.TryGetFieldByUnityAssemblyField(unityField);
                        if (processedField != null)
                        {
                            continue;
                        }

                        var fieldType = Pass80UnstripMethods.ResolveTypeInNewAssemblies(context, unityField.FieldType, imports);
                        if (fieldType == null)
                        {
                            LogSupport.Trace($"Field {unityField} on type {unityType.FullName} has unsupported type {unityField.FieldType}, the type will be unusable");
                            fieldsIgnored++;
                            continue;
                        }

                        var newField = new FieldDefinition(unityField.Name, unityField.Attributes & ~FieldAttributes.FieldAccessMask | FieldAttributes.Public, fieldType);

                        if (unityField.HasConstant)
                        {
                            newField.Constant = unityField.Constant;
                        }

                        processedType.NewType.Fields.Add(newField);

                        fieldsUnstripped++;
                    }
                }
            }

            LogSupport.Info(""); // finish the progress line
            LogSupport.Info($"{fieldsUnstripped} fields restored");
            LogSupport.Info($"{fieldsIgnored} fields failed to restore");
        }
        public static void DoPass(RewriteGlobalContext context)
        {
            var unityAssemblyFiles = Directory.EnumerateFiles(context.Options.UnityBaseLibsDir, "*.dll");
            var loadedAssemblies   = unityAssemblyFiles.Select(it =>
                                                               AssemblyDefinition.ReadAssembly(it, new ReaderParameters(ReadingMode.Deferred))).ToList();

            int fieldsUnstripped = 0;
            int fieldsIgnored    = 0;

            foreach (var unityAssembly in loadedAssemblies)
            {
                var processedAssembly = context.TryGetAssemblyByName(unityAssembly.Name.Name);
                if (processedAssembly == null)
                {
                    continue;
                }
                var imports = processedAssembly.Imports;

                foreach (var unityType in unityAssembly.MainModule.Types)
                {
                    var processedType = processedAssembly.TryGetTypeByName(unityType.FullName);
                    if (processedType == null)
                    {
                        continue;
                    }

                    if (!unityType.IsValueType || unityType.IsEnum)
                    {
                        continue;
                    }

                    foreach (var unityField in unityType.Fields)
                    {
                        if (unityField.IsStatic)
                        {
                            continue;
                        }

                        var processedField = processedType.TryGetFieldByUnityAssemblyField(unityField);
                        if (processedField != null)
                        {
                            continue;
                        }

                        var fieldType = Pass80UnstripMethods.ResolveTypeInNewAssemblies(context, unityField.FieldType, imports);
                        if (fieldType == null)
                        {
                            LogSupport.Trace($"Field {unityField} on type {unityType.FullName} has unsupported type {unityField.FieldType}, the type will be unusable");
                            fieldsIgnored++;
                            continue;
                        }

                        var newMethod = new FieldDefinition(unityField.Name, unityField.Attributes & ~FieldAttributes.FieldAccessMask | FieldAttributes.Public, fieldType);

                        processedType.NewType.Fields.Add(newMethod);

                        fieldsUnstripped++;
                    }
                }
            }

            LogSupport.Info(""); // finish the progress line
            LogSupport.Info($"{fieldsUnstripped} fields restored");
            LogSupport.Info($"{fieldsIgnored} fields failed to restore");
        }