fix: 修复 ReflectionCompatibilityDetector处理Unity 6000新增的Enum.TryParse(Type,bool, out object)函数时抛出异常的bug
refactor: 将 ReflectionCompatibilityDetector移到独立的ReflectionCompatibilityDetectionPassmain
parent
4ad3ed76dc
commit
59b1166ff3
|
@ -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<ModuleDef>(ctx.modulesToObfuscate);
|
||||||
|
var renamePolicy = SymbolRename.CreateDefaultRenamePolicy(_settings.ruleFiles, _settings.customRenamePolicyTypes);
|
||||||
|
var reflectionCompatibilityDetector = new ReflectionCompatibilityDetector(ctx.modulesToObfuscate, ctx.allObfuscationRelativeModules, renamePolicy);
|
||||||
|
reflectionCompatibilityDetector.Analyze();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b8a72b9a9142429429296aafb05a2372
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -243,7 +243,15 @@ namespace Obfuz.ObfusPasses.SymbolObfus
|
||||||
}
|
}
|
||||||
else
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,6 @@ namespace Obfuz.ObfusPasses.SymbolObfus
|
||||||
public class SymbolRename
|
public class SymbolRename
|
||||||
{
|
{
|
||||||
private readonly bool _useConsistentNamespaceObfuscation;
|
private readonly bool _useConsistentNamespaceObfuscation;
|
||||||
private readonly bool _detectReflectionCompatibility;
|
|
||||||
private readonly List<string> _obfuscationRuleFiles;
|
private readonly List<string> _obfuscationRuleFiles;
|
||||||
private readonly string _mappingXmlPath;
|
private readonly string _mappingXmlPath;
|
||||||
|
|
||||||
|
@ -30,7 +29,7 @@ namespace Obfuz.ObfusPasses.SymbolObfus
|
||||||
private readonly Dictionary<ModuleDef, List<CustomAttributeInfo>> _customAttributeArgumentsWithTypeByMods = new Dictionary<ModuleDef, List<CustomAttributeInfo>>();
|
private readonly Dictionary<ModuleDef, List<CustomAttributeInfo>> _customAttributeArgumentsWithTypeByMods = new Dictionary<ModuleDef, List<CustomAttributeInfo>>();
|
||||||
private readonly RenameRecordMap _renameRecordMap;
|
private readonly RenameRecordMap _renameRecordMap;
|
||||||
private readonly VirtualMethodGroupCalculator _virtualMethodGroupCalculator;
|
private readonly VirtualMethodGroupCalculator _virtualMethodGroupCalculator;
|
||||||
private readonly List<IObfuscationPolicy> _customPolicies = new List<IObfuscationPolicy>();
|
private readonly List<Type> _customPolicyTypes;
|
||||||
|
|
||||||
class CustomAttributeInfo
|
class CustomAttributeInfo
|
||||||
{
|
{
|
||||||
|
@ -43,24 +42,12 @@ namespace Obfuz.ObfusPasses.SymbolObfus
|
||||||
public SymbolRename(SymbolObfuscationSettingsFacade settings)
|
public SymbolRename(SymbolObfuscationSettingsFacade settings)
|
||||||
{
|
{
|
||||||
_useConsistentNamespaceObfuscation = settings.useConsistentNamespaceObfuscation;
|
_useConsistentNamespaceObfuscation = settings.useConsistentNamespaceObfuscation;
|
||||||
_detectReflectionCompatibility = settings.detectReflectionCompatibility;
|
|
||||||
_mappingXmlPath = settings.symbolMappingFile;
|
_mappingXmlPath = settings.symbolMappingFile;
|
||||||
_obfuscationRuleFiles = settings.ruleFiles.ToList();
|
_obfuscationRuleFiles = settings.ruleFiles.ToList();
|
||||||
_renameRecordMap = new RenameRecordMap(settings.symbolMappingFile, settings.debug, settings.keepUnknownSymbolInSymbolMappingFile);
|
_renameRecordMap = new RenameRecordMap(settings.symbolMappingFile, settings.debug, settings.keepUnknownSymbolInSymbolMappingFile);
|
||||||
_virtualMethodGroupCalculator = new VirtualMethodGroupCalculator();
|
_virtualMethodGroupCalculator = new VirtualMethodGroupCalculator();
|
||||||
_nameMaker = settings.debug ? NameMakerFactory.CreateDebugNameMaker() : NameMakerFactory.CreateNameMakerBaseASCIICharSet(settings.obfuscatedNamePrefix);
|
_nameMaker = settings.debug ? NameMakerFactory.CreateDebugNameMaker() : NameMakerFactory.CreateNameMakerBaseASCIICharSet(settings.obfuscatedNamePrefix);
|
||||||
|
_customPolicyTypes = settings.customRenamePolicyTypes;
|
||||||
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");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Init()
|
public void Init()
|
||||||
|
@ -72,7 +59,14 @@ namespace Obfuz.ObfusPasses.SymbolObfus
|
||||||
_toObfuscatedModuleSet = new HashSet<ModuleDef>(ctx.modulesToObfuscate);
|
_toObfuscatedModuleSet = new HashSet<ModuleDef>(ctx.modulesToObfuscate);
|
||||||
_nonObfuscatedButReferencingObfuscatedModuleSet = new HashSet<ModuleDef>(ctx.allObfuscationRelativeModules.Where(m => !_toObfuscatedModuleSet.Contains(m)));
|
_nonObfuscatedButReferencingObfuscatedModuleSet = new HashSet<ModuleDef>(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<string> obfuscationRuleFiles, List<Type> customPolicyTypes)
|
||||||
|
{
|
||||||
|
var ctx = ObfuscationPassContext.Current;
|
||||||
|
var obfuscateRuleConfig = new ConfigurableRenamePolicy(ctx.coreSettings.assembliesToObfuscate, ctx.modulesToObfuscate, obfuscationRuleFiles);
|
||||||
var totalRenamePolicies = new List<IObfuscationPolicy>
|
var totalRenamePolicies = new List<IObfuscationPolicy>
|
||||||
{
|
{
|
||||||
new SupportPassPolicy(ctx.passPolicy),
|
new SupportPassPolicy(ctx.passPolicy),
|
||||||
|
@ -80,10 +74,49 @@ namespace Obfuz.ObfusPasses.SymbolObfus
|
||||||
new UnityRenamePolicy(),
|
new UnityRenamePolicy(),
|
||||||
obfuscateRuleConfig,
|
obfuscateRuleConfig,
|
||||||
};
|
};
|
||||||
totalRenamePolicies.AddRange(_customPolicies);
|
|
||||||
|
|
||||||
_renamePolicy = new CacheRenamePolicy(new CombineRenamePolicy(totalRenamePolicies.ToArray()));
|
foreach (var customPolicyType in customPolicyTypes)
|
||||||
BuildCustomAttributeArguments();
|
{
|
||||||
|
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<ModuleDef> 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<CustomAttributeInfo> customAttributes)
|
private void CollectCArgumentWithTypeOf(IHasCustomAttribute meta, List<CustomAttributeInfo> 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()
|
public void Process()
|
||||||
{
|
{
|
||||||
_renameRecordMap.Init(_toObfuscatedModules, _nameMaker);
|
_renameRecordMap.Init(_toObfuscatedModules, _nameMaker);
|
||||||
PrecomputeNeedRename();
|
|
||||||
if (_detectReflectionCompatibility)
|
|
||||||
{
|
|
||||||
var reflectionCompatibilityDetector = new ReflectionCompatibilityDetector(_toObfuscatedModules, _obfuscatedAndNotObfuscatedModules, _renamePolicy);
|
|
||||||
reflectionCompatibilityDetector.Analyze();
|
|
||||||
}
|
|
||||||
RenameTypes();
|
RenameTypes();
|
||||||
RenameFields();
|
RenameFields();
|
||||||
RenameMethods();
|
RenameMethods();
|
||||||
|
|
|
@ -175,6 +175,11 @@ namespace Obfuz
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
ObfuscationPassType obfuscationPasses = settings.obfuscationPassSettings.enabledPasses;
|
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))
|
if (obfuscationPasses.HasFlag(ObfuscationPassType.ConstEncrypt))
|
||||||
{
|
{
|
||||||
builder.AddPass(new ConstEncryptPass(settings.constEncryptSettings.ToFacade()));
|
builder.AddPass(new ConstEncryptPass(settings.constEncryptSettings.ToFacade()));
|
||||||
|
|
Loading…
Reference in New Issue