private static void GenerateWhitelistInternal()
        {
#if ACTK_DEBUG
            sw = Stopwatch.StartNew();
            sw.Stop();
            Debug.Log("=== Injection Detector Whitelist Build Start ===");
            sw.Start();
#endif
            EditorUtility.DisplayProgressBar(ProgressCaption, "Gathering assemblies", 0);

            var assembliesInBuild = GetAssembliesInBuild();
            if (assembliesInBuild.Length == 0)
            {
                Debug.LogError(EditorTools.ConstructError("Can't find any assemblies in build!"));
            }

            var assembliesAllowedByUser = GetUserWhiteListAssemblies();
            var allAllowedAssemblies    = InjectionRoutines.MergeAllowedAssemblies(assembliesInBuild, assembliesAllowedByUser);

            EditorUtility.DisplayProgressBar(ProgressCaption, "Writing assemblies hashes", 0);

            WriteAllowedAssemblies(allAllowedAssemblies);

#if ACTK_DEBUG
            sw.Stop();
            Debug.Log(ACTkConstants.LogPrefix + "WhiteList build duration: " + sw.ElapsedMilliseconds + " ms.");
#endif

            AssetDatabase.Refresh();
        }
        private WhitelistingResult TryWhitelistAssemblyName(AssemblyName assName, bool singleFile)
        {
            var result = WhitelistingResult.Exists;

            var assNameString = assName.Name;
            var hash          = InjectionRoutines.GetAssemblyHash(assName);

            var allowed = whitelist.FirstOrDefault(allowedAssembly => allowedAssembly.name == assNameString);

            if (allowed != null)
            {
                if (allowed.AddHash(hash))
                {
                    if (singleFile)
                    {
                        ShowNotification(new GUIContent("New hash added!"));
                    }
                    result = WhitelistingResult.Updated;
                }
                else
                {
                    if (singleFile)
                    {
                        ShowNotification(new GUIContent("Assembly already exists!"));
                    }
                }
            }
            else
            {
                allowed = new AllowedAssembly(assNameString, new[] { hash });
                whitelist.Add(allowed);

                if (singleFile)
                {
                    ShowNotification(new GUIContent("Assembly added!"));
                }
                result = WhitelistingResult.Added;
            }

            return(result);
        }
        private static AllowedAssembly[] GetAssembliesInBuild()
        {
#if ACTK_DEBUG_VERBOSE
            sw.Stop();
            Debug.Log(ACTkConstants.LogPrefix + "Trying to guess which assemblies can get into the build...");
            sw.Start();
#endif
            var libraries = BuildPostProcessor.GetGuessedLibrariesForBuild();

#if ACTK_DEBUG_VERBOSE
            sw.Stop();
            Debug.Log(ACTkConstants.LogPrefix + "Total libraries candidates: " + libraries.Length);
            sw.Start();

            var invalidAssemblies = string.Empty;
#endif

            var result = new List <AllowedAssembly>();

            foreach (var libraryPath in libraries)
            {
#if ACTK_DEBUG_PARANIOD
                sw.Stop();
                Debug.Log(ACTkConstants.LogPrefix + "Checking library at the path: " + libraryPath);
                sw.Start();
#endif
                try
                {
                    var assName = AssemblyName.GetAssemblyName(libraryPath);
                    var name    = assName.Name;
                    var hash    = InjectionRoutines.GetAssemblyHash(assName);

                    var allowed = result.FirstOrDefault(allowedAssembly => allowedAssembly.name == name);
                    if (allowed != null)
                    {
                        allowed.AddHash(hash);
                    }
                    else
                    {
                        allowed = new AllowedAssembly(name, new[] { hash });
                        result.Add(allowed);
                    }
                }
                catch
                {
                    // not a valid IL assembly, skipping
#if ACTK_DEBUG_VERBOSE
                    invalidAssemblies += libraryPath + "\n";
#endif
                }
            }

#if ACTK_DEBUG_VERBOSE
            if (!string.IsNullOrEmpty(invalidAssemblies))
            {
                sw.Stop();
                Debug.Log(ACTkConstants.LogPrefix + "Not valid assemblies:\n" + invalidAssemblies);
                sw.Start();
            }
#endif

#if ACTK_DEBUG
            sw.Stop();
            var trace = ACTkConstants.LogPrefix + "Found assemblies in build (" + result.Count + ", " + sw.ElapsedMilliseconds + " ms):\n";

            foreach (var allowedAssembly in result)
            {
                trace += "  Name: " + allowedAssembly.name + "\n";
                trace  = allowedAssembly.hashes.Aggregate(trace, (current, hash) => current + ("    Hash: " + hash + "\n"));
            }
            Debug.Log(trace);
            sw.Start();
#endif
            return(result.ToArray());
        }
Exemple #4
0
        private static void DrawInjectionSection()
        {
            using (var changed = new EditorGUI.ChangeCheckScope())
            {
                var fold = GUITools.DrawFoldHeader("Injection Detector", ACTkEditorPrefsSettings.InjectionFoldout);
                if (changed.changed)
                {
                    ACTkEditorPrefsSettings.InjectionFoldout = fold;
                }
            }

            if (!ACTkEditorPrefsSettings.InjectionFoldout)
            {
                return;
            }

            GUILayout.Space(-3f);

            using (GUITools.Vertical(GUITools.PanelWithBackground))
            {
                var enableInjectionDetector = ACTkSettings.Instance.InjectionDetectorEnabled;

                if (SettingsUtils.IsIL2CPPEnabled())
                {
                    EditorGUILayout.HelpBox("Injection is not possible in IL2CPP,\n" +
                                            "this detector is not needed in IL2CPP builds", MessageType.Info, true);
                    GUILayout.Space(5f);
                }
                else if (!InjectionRoutines.IsTargetPlatformCompatible())
                {
                    EditorGUILayout.HelpBox(
                        "Injection Detection is only supported in non-IL2CPP Standalone and Android builds",
                        MessageType.Warning, true);
                    GUILayout.Space(5f);
                }

                using (new GUILayout.HorizontalScope())
                {
                    EditorGUI.BeginChangeCheck();
                    enableInjectionDetector = EditorGUILayout.ToggleLeft(new GUIContent(
                                                                             "Add mono injection detection support to build",
                                                                             "Injection Detector checks assemblies against whitelist. " +
                                                                             "Please enable this option if you're using Injection Detector " +
                                                                             "and default whitelist will be generated while Unity builds resulting build.\n" +
                                                                             "Has no effect for IL2CPP or unsupported platforms."), enableInjectionDetector
                                                                         );
                    if (EditorGUI.EndChangeCheck())
                    {
                        ACTkSettings.Instance.InjectionDetectorEnabled = enableInjectionDetector;
                    }
                }

                GUILayout.Space(3);

                if (GUILayout.Button(new GUIContent(
                                         "Edit Custom Whitelist (" + ACTkSettings.Instance.InjectionDetectorWhiteList.Count + ")",
                                         "Fill any external assemblies which are not included into the project to the user-defined whitelist to make Injection Detector aware of them."))
                    )
                {
                    UserWhitelistEditor.ShowWindow();
                }

                GUILayout.Space(3);
            }
        }