diff --git a/Editor/ObfusPasses/SymbolObfus/ReflectionCompatibilityDetectionPass.cs b/Editor/ObfusPasses/SymbolObfus/ReflectionCompatibilityDetectionPass.cs new file mode 100644 index 0000000..9d0165c --- /dev/null +++ b/Editor/ObfusPasses/SymbolObfus/ReflectionCompatibilityDetectionPass.cs @@ -0,0 +1,42 @@ +using dnlib.DotNet; +using Obfuz.Settings; +using Obfuz.Utils; +using System.Collections.Generic; +using System.Threading; + +namespace Obfuz.ObfusPasses.SymbolObfus +{ + public class ReflectionCompatibilityDetectionPass : ObfuscationPassBase + { + private readonly SymbolObfuscationSettingsFacade _settings; + + public override ObfuscationPassType Type => ObfuscationPassType.SymbolObfus; + + public ReflectionCompatibilityDetectionPass(SymbolObfuscationSettingsFacade settings) + { + _settings = settings; + } + + public override void Start() + { + + } + + public override void Stop() + { + + } + + public override void Process() + { + var ctx = ObfuscationPassContext.Current; + var assemblyCache = ctx.assemblyCache; + var toObfuscatedModules = ctx.modulesToObfuscate; + var obfuscatedAndNotObfuscatedModules = ctx.allObfuscationRelativeModules; + var toObfuscatedModuleSet = new HashSet(ctx.modulesToObfuscate); + var renamePolicy = SymbolRename.CreateDefaultRenamePolicy(_settings.ruleFiles, _settings.customRenamePolicyTypes); + var reflectionCompatibilityDetector = new ReflectionCompatibilityDetector(ctx.modulesToObfuscate, ctx.allObfuscationRelativeModules, renamePolicy); + reflectionCompatibilityDetector.Analyze(); + } + } +} diff --git a/Editor/ObfusPasses/SymbolObfus/ReflectionCompatibilityDetectionPass.cs.meta b/Editor/ObfusPasses/SymbolObfus/ReflectionCompatibilityDetectionPass.cs.meta new file mode 100644 index 0000000..b98c328 --- /dev/null +++ b/Editor/ObfusPasses/SymbolObfus/ReflectionCompatibilityDetectionPass.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b8a72b9a9142429429296aafb05a2372 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/ObfusPasses/SymbolObfus/ReflectionCompatibilityDetector.cs b/Editor/ObfusPasses/SymbolObfus/ReflectionCompatibilityDetector.cs index 8d644bb..eb9f3de 100644 --- a/Editor/ObfusPasses/SymbolObfus/ReflectionCompatibilityDetector.cs +++ b/Editor/ObfusPasses/SymbolObfus/ReflectionCompatibilityDetector.cs @@ -243,7 +243,15 @@ namespace Obfuz.ObfusPasses.SymbolObfus } else { - throw new Exception("impossible"); + TypeDef enumType = FindLatestTypeOf(method.GetParamCount() + extraSearchInstructionCount)?.ResolveTypeDef(); + if (enumType != null && enumType.IsEnum && IsAnyEnumItemRenamed(enumType)) + { + Debug.LogError($"[ReflectionCompatibilityDetector] Reflection compatibility issue in {_curCallingMethod}: Enum.TryParse field of argument type:{enumType.FullName} is renamed."); + } + else + { + Debug.LogWarning($"[ReflectionCompatibilityDetector] Reflection compatibility issue in {_curCallingMethod}: Enum.TryParse field of argument `type` should not be renamed."); + } } break; } diff --git a/Editor/ObfusPasses/SymbolObfus/SymbolRename.cs b/Editor/ObfusPasses/SymbolObfus/SymbolRename.cs index 1ceddfa..9f221be 100644 --- a/Editor/ObfusPasses/SymbolObfus/SymbolRename.cs +++ b/Editor/ObfusPasses/SymbolObfus/SymbolRename.cs @@ -15,7 +15,6 @@ namespace Obfuz.ObfusPasses.SymbolObfus public class SymbolRename { private readonly bool _useConsistentNamespaceObfuscation; - private readonly bool _detectReflectionCompatibility; private readonly List _obfuscationRuleFiles; private readonly string _mappingXmlPath; @@ -30,7 +29,7 @@ namespace Obfuz.ObfusPasses.SymbolObfus private readonly Dictionary> _customAttributeArgumentsWithTypeByMods = new Dictionary>(); private readonly RenameRecordMap _renameRecordMap; private readonly VirtualMethodGroupCalculator _virtualMethodGroupCalculator; - private readonly List _customPolicies = new List(); + private readonly List _customPolicyTypes; class CustomAttributeInfo { @@ -43,24 +42,12 @@ namespace Obfuz.ObfusPasses.SymbolObfus public SymbolRename(SymbolObfuscationSettingsFacade settings) { _useConsistentNamespaceObfuscation = settings.useConsistentNamespaceObfuscation; - _detectReflectionCompatibility = settings.detectReflectionCompatibility; _mappingXmlPath = settings.symbolMappingFile; _obfuscationRuleFiles = settings.ruleFiles.ToList(); _renameRecordMap = new RenameRecordMap(settings.symbolMappingFile, settings.debug, settings.keepUnknownSymbolInSymbolMappingFile); _virtualMethodGroupCalculator = new VirtualMethodGroupCalculator(); _nameMaker = settings.debug ? NameMakerFactory.CreateDebugNameMaker() : NameMakerFactory.CreateNameMakerBaseASCIICharSet(settings.obfuscatedNamePrefix); - - foreach (var customPolicyType in settings.customRenamePolicyTypes) - { - if (Activator.CreateInstance(customPolicyType, new object[] { this }) is IObfuscationPolicy customPolicy) - { - _customPolicies.Add(customPolicy); - } - else - { - Debug.LogWarning($"Custom rename policy type {customPolicyType} is not a valid IObfuscationPolicy"); - } - } + _customPolicyTypes = settings.customRenamePolicyTypes; } public void Init() @@ -72,7 +59,14 @@ namespace Obfuz.ObfusPasses.SymbolObfus _toObfuscatedModuleSet = new HashSet(ctx.modulesToObfuscate); _nonObfuscatedButReferencingObfuscatedModuleSet = new HashSet(ctx.allObfuscationRelativeModules.Where(m => !_toObfuscatedModuleSet.Contains(m))); - var obfuscateRuleConfig = new ConfigurableRenamePolicy(ctx.coreSettings.assembliesToObfuscate, ctx.modulesToObfuscate, _obfuscationRuleFiles); + _renamePolicy = CreateDefaultRenamePolicy(_obfuscationRuleFiles, _customPolicyTypes); + BuildCustomAttributeArguments(); + } + + public static IObfuscationPolicy CreateDefaultRenamePolicy(List obfuscationRuleFiles, List customPolicyTypes) + { + var ctx = ObfuscationPassContext.Current; + var obfuscateRuleConfig = new ConfigurableRenamePolicy(ctx.coreSettings.assembliesToObfuscate, ctx.modulesToObfuscate, obfuscationRuleFiles); var totalRenamePolicies = new List { new SupportPassPolicy(ctx.passPolicy), @@ -80,10 +74,49 @@ namespace Obfuz.ObfusPasses.SymbolObfus new UnityRenamePolicy(), obfuscateRuleConfig, }; - totalRenamePolicies.AddRange(_customPolicies); - _renamePolicy = new CacheRenamePolicy(new CombineRenamePolicy(totalRenamePolicies.ToArray())); - BuildCustomAttributeArguments(); + foreach (var customPolicyType in customPolicyTypes) + { + if (Activator.CreateInstance(customPolicyType, new object[] { null }) is IObfuscationPolicy customPolicy) + { + totalRenamePolicies.Add(customPolicy); + } + else + { + Debug.LogWarning($"Custom rename policy type {customPolicyType} is not a valid IObfuscationPolicy"); + } + } + + IObfuscationPolicy renamePolicy = new CacheRenamePolicy(new CombineRenamePolicy(totalRenamePolicies.ToArray())); + PrecomputeNeedRename(ctx.modulesToObfuscate, renamePolicy); + return renamePolicy; + } + + private static void PrecomputeNeedRename(List toObfuscatedModules, IObfuscationPolicy renamePolicy) + { + foreach (ModuleDef mod in toObfuscatedModules) + { + foreach (TypeDef type in mod.GetTypes()) + { + renamePolicy.NeedRename(type); + foreach (var field in type.Fields) + { + renamePolicy.NeedRename(field); + } + foreach (var method in type.Methods) + { + renamePolicy.NeedRename(method); + } + foreach (var property in type.Properties) + { + renamePolicy.NeedRename(property); + } + foreach (var eventDef in type.Events) + { + renamePolicy.NeedRename(eventDef); + } + } + } } private void CollectCArgumentWithTypeOf(IHasCustomAttribute meta, List customAttributes) @@ -149,42 +182,9 @@ namespace Obfuz.ObfusPasses.SymbolObfus } } - private void PrecomputeNeedRename() - { - foreach (ModuleDef mod in _toObfuscatedModules) - { - foreach (TypeDef type in mod.GetTypes()) - { - _renamePolicy.NeedRename(type); - foreach (var field in type.Fields) - { - _renamePolicy.NeedRename(field); - } - foreach (var method in type.Methods) - { - _renamePolicy.NeedRename(method); - } - foreach (var property in type.Properties) - { - _renamePolicy.NeedRename(property); - } - foreach (var eventDef in type.Events) - { - _renamePolicy.NeedRename(eventDef); - } - } - } - } - public void Process() { _renameRecordMap.Init(_toObfuscatedModules, _nameMaker); - PrecomputeNeedRename(); - if (_detectReflectionCompatibility) - { - var reflectionCompatibilityDetector = new ReflectionCompatibilityDetector(_toObfuscatedModules, _obfuscatedAndNotObfuscatedModules, _renamePolicy); - reflectionCompatibilityDetector.Analyze(); - } RenameTypes(); RenameFields(); RenameMethods(); diff --git a/Editor/ObfuscatorBuilder.cs b/Editor/ObfuscatorBuilder.cs index d5945b7..31ae7af 100644 --- a/Editor/ObfuscatorBuilder.cs +++ b/Editor/ObfuscatorBuilder.cs @@ -175,6 +175,11 @@ namespace Obfuz }, }; ObfuscationPassType obfuscationPasses = settings.obfuscationPassSettings.enabledPasses; + + if (obfuscationPasses.HasFlag(ObfuscationPassType.SymbolObfus) && settings.symbolObfusSettings.detectReflectionCompatibility) + { + builder.AddPass(new ReflectionCompatibilityDetectionPass(settings.symbolObfusSettings.ToFacade())); + } if (obfuscationPasses.HasFlag(ObfuscationPassType.ConstEncrypt)) { builder.AddPass(new ConstEncryptPass(settings.constEncryptSettings.ToFacade()));