From 76cb8fbcbb67c758400430c9315aa330f02863d3 Mon Sep 17 00:00:00 2001 From: walon Date: Fri, 30 May 2025 18:24:54 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8DPrebuildCommandExt.GenerateAl?= =?UTF-8?q?l=E4=B8=AD=E7=94=9F=E6=88=90=E6=A1=A5=E6=8E=A5=E5=87=BD?= =?UTF-8?q?=E6=95=B0=E6=97=B6=E5=A6=82=E6=9E=9C=E6=B7=B7=E6=B7=86=E7=A8=8B?= =?UTF-8?q?=E5=BA=8F=E9=9B=86=E6=98=AF=E9=A2=84=E7=BC=96=E8=AF=91=E7=9A=84?= =?UTF-8?q?dll=EF=BC=8C=E5=B9=B6=E4=B8=8D=E5=9C=A8=E7=83=AD=E6=9B=B4?= =?UTF-8?q?=E6=96=B0dll=E8=BE=93=E5=87=BA=E7=9B=AE=E5=BD=95=E4=B8=AD?= =?UTF-8?q?=EF=BC=8C=E4=BC=9A=E9=94=99=E8=AF=AF=E5=9C=B0=E4=BB=8E=E6=90=9C?= =?UTF-8?q?=E7=B4=A2=E7=9B=AE=E5=BD=95=E5=8A=A0=E8=BD=BD=E5=8E=9F=E5=A7=8B?= =?UTF-8?q?=E6=8F=92=E4=BB=B6dll=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Editor/ObfuscateUtil.cs | 49 ++++++----- .../Editor/PrebuildCommandExt.cs | 86 ++++++++++++++++++- 2 files changed, 107 insertions(+), 28 deletions(-) diff --git a/com.code-philosophy.obfuz4hybridclr/Editor/ObfuscateUtil.cs b/com.code-philosophy.obfuz4hybridclr/Editor/ObfuscateUtil.cs index 6667c59..62a71c5 100644 --- a/com.code-philosophy.obfuz4hybridclr/Editor/ObfuscateUtil.cs +++ b/com.code-philosophy.obfuz4hybridclr/Editor/ObfuscateUtil.cs @@ -3,14 +3,8 @@ using Obfuz.Settings; using Obfuz; using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using UnityEditor; -using HybridCLR.Editor.Commands; -using HybridCLR.Editor.Installer; using System.IO; -using HybridCLR.Editor.ABI; using UnityEngine; using Obfuz.Unity; @@ -34,11 +28,9 @@ namespace Obfuz4HybridCLR } } - public static void CompileAndObfuscateHotUpdateAssemblies(BuildTarget target) + public static void ObfuscateHotUpdateAssemblies(BuildTarget target, string outputDir) { string hotUpdateDllPath = SettingsUtil.GetHotUpdateDllsOutputDirByTarget(target); - BashUtil.RemoveDir(hotUpdateDllPath); - CompileDllCommand.CompileDll(target); AssemblySettings assemblySettings = ObfuzSettings.Instance.assemblySettings; ObfuscationProcess.ValidateReferences(hotUpdateDllPath, new HashSet(assemblySettings.GetAssembliesToObfuscate()), new HashSet(assemblySettings.GetObfuscationRelativeAssemblyNames())); @@ -46,10 +38,31 @@ namespace Obfuz4HybridCLR { hotUpdateDllPath, }; - Obfuscate(target, assemblySearchPaths, hotUpdateDllPath); + if (AreSameDirectory(hotUpdateDllPath, outputDir)) + { + throw new Exception($"hotUpdateDllPath:{hotUpdateDllPath} can't be same to outputDir:{outputDir}"); + } + Obfuscate(target, assemblySearchPaths, outputDir); + foreach (string hotUpdateAssemblyName in SettingsUtil.HotUpdateAssemblyNamesExcludePreserved) + { + string srcFile = $"{hotUpdateDllPath}/{hotUpdateAssemblyName}.dll"; + string dstFile = $"{outputDir}/{hotUpdateAssemblyName}.dll"; + // only copy non obfuscated assemblies + if (File.Exists(srcFile) && !File.Exists(dstFile)) + { + File.Copy(srcFile, dstFile, true); + Debug.Log($"[CompileAndObfuscateDll] Copy nonObfuscated assembly {srcFile} to {dstFile}"); + } + } } - public static void Obfuscate(BuildTarget target, List assemblySearchPaths, string outputPath) + /// + /// output obfuscated assemblies to ObfuzSettings.Instance.GetObfuscatedAssemblyOutputPath(target) + /// + /// + /// + /// + public static void Obfuscate(BuildTarget target, List assemblySearchPaths, string obfuscatedAssemblyOutputPath) { var obfuzSettings = ObfuzSettings.Instance; @@ -57,11 +70,6 @@ namespace Obfuz4HybridCLR ObfuscatorBuilder builder = ObfuscatorBuilder.FromObfuzSettings(obfuzSettings, target, true); builder.InsertTopPriorityAssemblySearchPaths(assemblySearchDirs); - string obfuscatedAssemblyOutputPath = obfuzSettings.GetObfuscatedAssemblyOutputPath(target); - if (AreSameDirectory(outputPath, obfuscatedAssemblyOutputPath)) - { - throw new Exception($"outputPath:{outputPath} can't be same to ObfuscatedAssemblyOutputPath:{obfuscatedAssemblyOutputPath}"); - } foreach (var assemblySearchDir in builder.CoreSettingsFacade.assemblySearchPaths) { if (AreSameDirectory(assemblySearchDir, obfuscatedAssemblyOutputPath)) @@ -72,15 +80,6 @@ namespace Obfuz4HybridCLR Obfuscator obfuz = builder.Build(); obfuz.Run(); - - Directory.CreateDirectory(outputPath); - foreach (string srcFile in Directory.GetFiles(obfuscatedAssemblyOutputPath, "*.dll")) - { - string fileName = Path.GetFileName(srcFile); - string destFile = $"{outputPath}/{fileName}"; - File.Copy(srcFile, destFile, true); - Debug.Log($"Copy {srcFile} to {destFile}"); - } } } } diff --git a/com.code-philosophy.obfuz4hybridclr/Editor/PrebuildCommandExt.cs b/com.code-philosophy.obfuz4hybridclr/Editor/PrebuildCommandExt.cs index 857255c..f5c161e 100644 --- a/com.code-philosophy.obfuz4hybridclr/Editor/PrebuildCommandExt.cs +++ b/com.code-philosophy.obfuz4hybridclr/Editor/PrebuildCommandExt.cs @@ -13,11 +13,27 @@ using HybridCLR.Editor.Link; using HybridCLR.Editor.Meta; using UnityEditor.Build; using HybridCLR.Editor.Installer; +using HybridCLR.Editor.MethodBridge; +using System.Linq; +using Analyzer = HybridCLR.Editor.MethodBridge.Analyzer; +using HybridCLR.Editor.Settings; +using Obfuz.Utils; +using FileUtil = Obfuz.Utils.FileUtil; +using IAssemblyResolver = HybridCLR.Editor.Meta.IAssemblyResolver; +using CombinedAssemblyResolver = HybridCLR.Editor.Meta.CombinedAssemblyResolver; +using MetaUtil = HybridCLR.Editor.Meta.MetaUtil; +using AssemblyCache = HybridCLR.Editor.Meta.AssemblyCache; namespace Obfuz4HybridCLR { public static class PrebuildCommandExt { + public static string GetObfuscatedHotUpdateAssemblyOutputPath(BuildTarget target) + { + return $"{ObfuzSettings.Instance.ObfuzRootDir}/{target}/ObfuscatedHotUpdateAssemblies"; + } + + [MenuItem("HybridCLR/ObfuzExtension/GenerateAll")] public static void GenerateAll() { @@ -27,18 +43,82 @@ namespace Obfuz4HybridCLR throw new BuildFailedException($"You have not initialized HybridCLR, please install it via menu 'HybridCLR/Installer'"); } BuildTarget target = EditorUserBuildSettings.activeBuildTarget; - ObfuscateUtil.CompileAndObfuscateHotUpdateAssemblies(target); + CompileDllCommand.CompileDll(target); Il2CppDefGeneratorCommand.GenerateIl2CppDef(); LinkGeneratorCommand.GenerateLinkXml(target); StripAOTDllCommand.GenerateStripedAOTDlls(target); - MethodBridgeGeneratorCommand.GenerateMethodBridgeAndReversePInvokeWrapper(target); AOTReferenceGeneratorCommand.GenerateAOTGenericReference(target); + + string obfuscatedHotUpdateDllPath = GetObfuscatedHotUpdateAssemblyOutputPath(target); + ObfuscateUtil.ObfuscateHotUpdateAssemblies(target, obfuscatedHotUpdateDllPath); + GenerateMethodBridgeAndReversePInvokeWrapper(target, obfuscatedHotUpdateDllPath); } [MenuItem("HybridCLR/ObfuzExtension/CompileAndObfuscateDll")] public static void CompileAndObfuscateDll() { - ObfuscateUtil.CompileAndObfuscateHotUpdateAssemblies(EditorUserBuildSettings.activeBuildTarget); + BuildTarget target = EditorUserBuildSettings.activeBuildTarget; + CompileDllCommand.CompileDll(target); + + string obfuscatedHotUpdateDllPath = GetObfuscatedHotUpdateAssemblyOutputPath(target); + ObfuscateUtil.ObfuscateHotUpdateAssemblies(target, obfuscatedHotUpdateDllPath); + } + + public static IAssemblyResolver CreateObfuscatedHotUpdateAssemblyResolver(BuildTarget target, List obfuscatedHotUpdateAssemblies, string obfuscatedHotUpdateDllPath) + { + return new FixedSetAssemblyResolver(obfuscatedHotUpdateDllPath, obfuscatedHotUpdateAssemblies); + } + + public static IAssemblyResolver CreateObfuscatedHotUpdateAndAOTAssemblyResolver(BuildTarget target, List hotUpdateAssemblies, List assembliesToObfuscate, string obfuscatedHotUpdateDllPath) + { + return new CombinedAssemblyResolver( + CreateObfuscatedHotUpdateAssemblyResolver(target, hotUpdateAssemblies.Intersect(assembliesToObfuscate).ToList(), obfuscatedHotUpdateDllPath), + MetaUtil.CreateHotUpdateAssemblyResolver(target, hotUpdateAssemblies.Except(assembliesToObfuscate).ToList()), + MetaUtil.CreateAOTAssemblyResolver(target) + ); + } + + public static void GenerateMethodBridgeAndReversePInvokeWrapper(BuildTarget target, string obfuscatedHotUpdateDllPath) + { + string aotDllDir = SettingsUtil.GetAssembliesPostIl2CppStripDir(target); + List aotAssemblyNames = Directory.Exists(aotDllDir) ? + Directory.GetFiles(aotDllDir, "*.dll", SearchOption.TopDirectoryOnly).Select(Path.GetFileNameWithoutExtension).ToList() + : new List(); + if (aotAssemblyNames.Count == 0) + { + throw new Exception($"no aot assembly found. please run `HybridCLR/Generate/All` or `HybridCLR/Generate/AotDlls` to generate aot dlls before runing `HybridCLR/Generate/MethodBridge`"); + } + AssemblyReferenceDeepCollector collector = new AssemblyReferenceDeepCollector(MetaUtil.CreateAOTAssemblyResolver(target), aotAssemblyNames); + + var methodBridgeAnalyzer = new Analyzer(new Analyzer.Options + { + MaxIterationCount = Math.Min(20, SettingsUtil.HybridCLRSettings.maxMethodBridgeGenericIteration), + Collector = collector, + }); + + methodBridgeAnalyzer.Run(); + + List hotUpdateDlls = SettingsUtil.HotUpdateAssemblyNamesExcludePreserved; + var cache = new AssemblyCache(CreateObfuscatedHotUpdateAndAOTAssemblyResolver(target, hotUpdateDlls, ObfuzSettings.Instance.assemblySettings.GetAssembliesToObfuscate(), obfuscatedHotUpdateDllPath)); + + var reversePInvokeAnalyzer = new MonoPInvokeCallbackAnalyzer(cache, hotUpdateDlls); + reversePInvokeAnalyzer.Run(); + + var calliAnalyzer = new CalliAnalyzer(cache, hotUpdateDlls); + calliAnalyzer.Run(); + var pinvokeAnalyzer = new PInvokeAnalyzer(cache, hotUpdateDlls); + pinvokeAnalyzer.Run(); + var callPInvokeMethodSignatures = pinvokeAnalyzer.PInvokeMethodSignatures; + + string templateFile = $"{SettingsUtil.TemplatePathInPackage}/MethodBridge.cpp.tpl"; + string outputFile = $"{SettingsUtil.GeneratedCppDir}/MethodBridge.cpp"; + + var callNativeMethodSignatures = calliAnalyzer.CalliMethodSignatures.Concat(pinvokeAnalyzer.PInvokeMethodSignatures).ToList(); + + var generateMethodBridgeMethod = typeof(MethodBridgeGeneratorCommand).GetMethod("GenerateMethodBridgeCppFile", BindingFlags.NonPublic | BindingFlags.Static); + generateMethodBridgeMethod.Invoke(null, new object[] { methodBridgeAnalyzer.GenericMethods, reversePInvokeAnalyzer.ReversePInvokeMethods, callNativeMethodSignatures, templateFile, outputFile }); + + MethodBridgeGeneratorCommand.CleanIl2CppBuildCache(); } } }