diff --git a/Editor/BashUtil.cs b/Editor/BashUtil.cs deleted file mode 100644 index 504565b..0000000 --- a/Editor/BashUtil.cs +++ /dev/null @@ -1,143 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading; -using System.Threading.Tasks; - -namespace Obfuz -{ - public static class BashUtil - { - public static int RunCommand(string workingDir, string program, string[] args, bool log = true) - { - using (Process p = new Process()) - { - p.StartInfo.WorkingDirectory = workingDir; - p.StartInfo.FileName = program; - p.StartInfo.UseShellExecute = false; - p.StartInfo.CreateNoWindow = true; - string argsStr = string.Join(" ", args.Select(arg => "\"" + arg + "\"")); - p.StartInfo.Arguments = argsStr; - if (log) - { - UnityEngine.Debug.Log($"[BashUtil] run => {program} {argsStr}"); - } - p.Start(); - p.WaitForExit(); - return p.ExitCode; - } - } - - - public static (int ExitCode, string StdOut, string StdErr) RunCommand2(string workingDir, string program, string[] args, bool log = true) - { - using (Process p = new Process()) - { - p.StartInfo.WorkingDirectory = workingDir; - p.StartInfo.FileName = program; - p.StartInfo.UseShellExecute = false; - p.StartInfo.CreateNoWindow = true; - p.StartInfo.RedirectStandardOutput = true; - p.StartInfo.RedirectStandardError = true; - string argsStr = string.Join(" ", args); - p.StartInfo.Arguments = argsStr; - if (log) - { - UnityEngine.Debug.Log($"[BashUtil] run => {program} {argsStr}"); - } - p.Start(); - p.WaitForExit(); - - string stdOut = p.StandardOutput.ReadToEnd(); - string stdErr = p.StandardError.ReadToEnd(); - return (p.ExitCode, stdOut, stdErr); - } - } - - - public static void RemoveDir(string dir, bool log = false) - { - if (log) - { - UnityEngine.Debug.Log($"[BashUtil] RemoveDir dir:{dir}"); - } - - int maxTryCount = 5; - for (int i = 0; i < maxTryCount; ++i) - { - try - { - if (!Directory.Exists(dir)) - { - return; - } - foreach (var file in Directory.GetFiles(dir)) - { - File.SetAttributes(file, FileAttributes.Normal); - File.Delete(file); - } - foreach (var subDir in Directory.GetDirectories(dir)) - { - RemoveDir(subDir); - } - Directory.Delete(dir, true); - break; - } - catch (Exception e) - { - UnityEngine.Debug.LogError($"[BashUtil] RemoveDir:{dir} with exception:{e}. try count:{i}"); - Thread.Sleep(100); - } - } - } - - public static void RecreateDir(string dir) - { - if(Directory.Exists(dir)) - { - RemoveDir(dir, true); - } - Directory.CreateDirectory(dir); - } - - private static void CopyWithCheckLongFile(string srcFile, string dstFile) - { - var maxPathLength = 255; -#if UNITY_EDITOR_OSX - maxPathLength = 1024; -#endif - if (srcFile.Length > maxPathLength) - { - UnityEngine.Debug.LogError($"srcFile:{srcFile} path is too long. skip copy!"); - return; - } - if (dstFile.Length > maxPathLength) - { - UnityEngine.Debug.LogError($"dstFile:{dstFile} path is too long. skip copy!"); - return; - } - File.Copy(srcFile, dstFile); - } - - public static void CopyDir(string src, string dst, bool log = false) - { - if (log) - { - UnityEngine.Debug.Log($"[BashUtil] CopyDir {src} => {dst}"); - } - RemoveDir(dst); - Directory.CreateDirectory(dst); - foreach(var file in Directory.GetFiles(src)) - { - CopyWithCheckLongFile(file, $"{dst}/{Path.GetFileName(file)}"); - } - foreach(var subDir in Directory.GetDirectories(src)) - { - CopyDir(subDir, $"{dst}/{Path.GetFileName(subDir)}"); - } - } - } -} diff --git a/Editor/BuildProcess/ObfuzProcess2021.cs b/Editor/BuildProcess/ObfuzProcess2021.cs new file mode 100644 index 0000000..d23d8d7 --- /dev/null +++ b/Editor/BuildProcess/ObfuzProcess2021.cs @@ -0,0 +1,103 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEditor.Build; +using UnityEditor; +using UnityEditor.Build.Reporting; +using UnityEngine.SceneManagement; +using UnityEngine; +using UnityEditor.Compilation; +using System.Reflection; + +namespace Obfuz +{ + +#if UNITY_2021 || UNITY_2020_1_OR_NEWER + internal class ObfuzProcess2021 : IPreprocessBuildWithReport, IPostprocessBuildWithReport + { + private static bool s_inBuild = false; + private static bool s_obfuscated = false; + + public int callbackOrder => 10000; + + public void OnPreprocessBuild(BuildReport report) + { + s_inBuild = true; + s_obfuscated = false; + + CompilationPipeline.compilationFinished += OnCompilationFinished; + } + + private static string GetScriptAssembliesPath(object obj) + { + object settings = obj.GetType().GetProperty("settings").GetValue(obj); + string path = (string)settings.GetType().GetProperty("OutputDirectory").GetValue(settings); + return path; + } + + private void OnCompilationFinished(object obj) + { + if (s_inBuild && !s_obfuscated) + { + RunObfuscate(GetScriptAssembliesPath(obj)); + s_obfuscated = true; + } + } + + public void OnPostprocessBuild(BuildReport report) + { + s_inBuild = false; + s_obfuscated = false; + CompilationPipeline.compilationFinished -= OnCompilationFinished; + } + + private static void RunObfuscate(string scriptAssembliesPath) + { + ObfuzSettings settings = ObfuzSettings.Instance; + if (!settings.enable) + { + Debug.Log("Obfuscation is disabled."); + return; + } + + Debug.Log("Obfuscation begin..."); + var buildTarget = EditorUserBuildSettings.activeBuildTarget; + + + string backupPlayerScriptAssembliesPath = settings.GetOriginalAssemblyBackupDir(buildTarget); + FileUtil.CopyDir(scriptAssembliesPath, backupPlayerScriptAssembliesPath); + + string applicationContentsPath = EditorApplication.applicationContentsPath; + + var opt = new Obfuscator.Options + { + AssemblySearchDirs = new List + { + Path.Combine(applicationContentsPath, "UnityReferenceAssemblies/unity-4.8-api/Facades"), + Path.Combine(applicationContentsPath, "UnityReferenceAssemblies/unity-4.8-api"), + Path.Combine(applicationContentsPath, "Managed/UnityEngine"), + backupPlayerScriptAssembliesPath, + }, + ObfuscationRuleFiles = settings.ruleFiles.ToList(), + mappingXmlPath = settings.mappingFile, + outputDir = ObfuzSettings.Instance.GetObfuscatedAssemblyOutputDir(buildTarget), + }; + var obfuz = new Obfuscator(opt); + obfuz.Run(); + + foreach (var dllName in obfuz.ObfuscatedAssemblyNames) + { + string src = $"{opt.outputDir}/{dllName}.dll"; + string dst = $"{scriptAssembliesPath}/{dllName}.dll"; + File.Copy(src, dst, true); + Debug.Log($"obfuscate dll:{dst}"); + } + + Debug.Log("Obfuscation end."); + } + } +#endif +} diff --git a/Editor/BuildProcess/ObfuzProcess.cs b/Editor/BuildProcess/ObfuzProcess2022OrNewer.cs similarity index 71% rename from Editor/BuildProcess/ObfuzProcess.cs rename to Editor/BuildProcess/ObfuzProcess2022OrNewer.cs index bc4ea77..6ff58f1 100644 --- a/Editor/BuildProcess/ObfuzProcess.cs +++ b/Editor/BuildProcess/ObfuzProcess2022OrNewer.cs @@ -9,10 +9,13 @@ using UnityEditor; using UnityEditor.Build.Reporting; using UnityEngine.SceneManagement; using UnityEngine; +using UnityEditor.Compilation; namespace Obfuz { - internal class ObfuzProcess : IPreprocessBuildWithReport, IProcessSceneWithReport, IPostprocessBuildWithReport + +#if UNITY_2022_1_OR_NEWER + internal class ObfuzProcess2022OrNewer : IPreprocessBuildWithReport, IProcessSceneWithReport, IPostprocessBuildWithReport { private static bool s_inBuild = false; private static bool s_obfuscated = false; @@ -23,6 +26,17 @@ namespace Obfuz { s_inBuild = true; s_obfuscated = false; + + //CompilationPipeline.compilationFinished += OnCompilationFinished; + } + + private void OnCompilationFinished(object obj) + { + if (s_inBuild && !s_obfuscated) + { + RunObfuscate(); + s_obfuscated = true; + } } public void OnProcessScene(Scene scene, BuildReport report) @@ -38,6 +52,7 @@ namespace Obfuz { s_inBuild = false; s_obfuscated = false; + //CompilationPipeline.compilationFinished -= OnCompilationFinished; } private static void RunObfuscate() @@ -55,17 +70,17 @@ namespace Obfuz string originalPlayerScriptAssembliesPath = @"Library\Bee\PlayerScriptAssemblies"; string backupPlayerScriptAssembliesPath = settings.GetOriginalAssemblyBackupDir(buildTarget); - BashUtil.CopyDir(originalPlayerScriptAssembliesPath, backupPlayerScriptAssembliesPath); - + FileUtil.CopyDir(originalPlayerScriptAssembliesPath, backupPlayerScriptAssembliesPath); + string applicationContentsPath = EditorApplication.applicationContentsPath; var opt = new Obfuscator.Options { AssemblySearchDirs = new List { - @"D:\UnityHubs\2022.3.60f1\Editor\Data\MonoBleedingEdge\lib\mono\unityaot-win32\Facades", - @"D:\UnityHubs\2022.3.60f1\Editor\Data\MonoBleedingEdge\lib\mono\unityaot-win32", - @"D:\UnityHubs\2022.3.60f1\Editor\Data\PlaybackEngines\windowsstandalonesupport\Variations\il2cpp\Managed", + Path.Combine(applicationContentsPath, "UnityReferenceAssemblies/unity-4.8-api/Facades"), + Path.Combine(applicationContentsPath, "UnityReferenceAssemblies/unity-4.8-api"), + Path.Combine(applicationContentsPath, "Managed/UnityEngine"), backupPlayerScriptAssembliesPath, }, ObfuscationRuleFiles = settings.ruleFiles.ToList(), @@ -86,4 +101,5 @@ namespace Obfuz Debug.Log("Obfuscation end."); } } +#endif } diff --git a/Editor/FileUtil.cs b/Editor/FileUtil.cs index 781431d..03bc86d 100644 --- a/Editor/FileUtil.cs +++ b/Editor/FileUtil.cs @@ -3,19 +3,94 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace Obfuz { public static class FileUtil { + + public static void RemoveDir(string dir, bool log = false) + { + if (log) + { + UnityEngine.Debug.Log($"[BashUtil] RemoveDir dir:{dir}"); + } + + int maxTryCount = 5; + for (int i = 0; i < maxTryCount; ++i) + { + try + { + if (!Directory.Exists(dir)) + { + return; + } + foreach (var file in Directory.GetFiles(dir)) + { + File.SetAttributes(file, FileAttributes.Normal); + File.Delete(file); + } + foreach (var subDir in Directory.GetDirectories(dir)) + { + RemoveDir(subDir); + } + Directory.Delete(dir, true); + break; + } + catch (Exception e) + { + UnityEngine.Debug.LogError($"[BashUtil] RemoveDir:{dir} with exception:{e}. try count:{i}"); + Thread.Sleep(100); + } + } + } + public static void RecreateDir(string dir) { if (Directory.Exists(dir)) { - Directory.Delete(dir, true); + RemoveDir(dir, true); } Directory.CreateDirectory(dir); } + + private static void CopyWithCheckLongFile(string srcFile, string dstFile) + { + var maxPathLength = 255; +#if UNITY_EDITOR_OSX + maxPathLength = 1024; +#endif + if (srcFile.Length > maxPathLength) + { + UnityEngine.Debug.LogError($"srcFile:{srcFile} path is too long. skip copy!"); + return; + } + if (dstFile.Length > maxPathLength) + { + UnityEngine.Debug.LogError($"dstFile:{dstFile} path is too long. skip copy!"); + return; + } + File.Copy(srcFile, dstFile); + } + + public static void CopyDir(string src, string dst, bool log = false) + { + if (log) + { + UnityEngine.Debug.Log($"[BashUtil] CopyDir {src} => {dst}"); + } + RemoveDir(dst); + Directory.CreateDirectory(dst); + foreach (var file in Directory.GetFiles(src)) + { + CopyWithCheckLongFile(file, $"{dst}/{Path.GetFileName(file)}"); + } + foreach (var subDir in Directory.GetDirectories(src)) + { + CopyDir(subDir, $"{dst}/{Path.GetFileName(subDir)}"); + } + } } }