重构为Pipeline

backup
walon 2025-04-21 09:57:34 +08:00
parent 61eab9ed11
commit 33a4f1bf2f
12 changed files with 186 additions and 45 deletions

View File

@ -81,7 +81,8 @@ namespace Obfuz
var opt = new Obfuscator.Options var opt = new Obfuscator.Options
{ {
AssemblySearchDirs = new List<string> obfuscationAssemblyNames = settings.obfuscationAssemblyNames.ToList(),
assemblySearchDirs = new List<string>
{ {
#if UNITY_2021_1_OR_NEWER #if UNITY_2021_1_OR_NEWER
Path.Combine(applicationContentsPath, "UnityReferenceAssemblies/unity-4.8-api/Facades"), Path.Combine(applicationContentsPath, "UnityReferenceAssemblies/unity-4.8-api/Facades"),
@ -95,17 +96,23 @@ namespace Obfuz
Path.Combine(applicationContentsPath, "Managed/UnityEngine"), Path.Combine(applicationContentsPath, "Managed/UnityEngine"),
backupPlayerScriptAssembliesPath, backupPlayerScriptAssembliesPath,
}.Concat(settings.extraAssemblySearchDirs).ToList(), }.Concat(settings.extraAssemblySearchDirs).ToList(),
ObfuscationRuleFiles = settings.ruleFiles.ToList(), obfuscationRuleFiles = settings.ruleFiles.ToList(),
mappingXmlPath = settings.mappingFile, mappingXmlPath = settings.mappingFile,
outputDir = ObfuzSettings.Instance.GetObfuscatedAssemblyOutputDir(buildTarget), outputDir = ObfuzSettings.Instance.GetObfuscatedAssemblyOutputDir(buildTarget),
}; };
var obfuz = new Obfuscator(opt); var obfuz = new Obfuscator(opt);
obfuz.Run(); obfuz.Run();
foreach (var dllName in obfuz.ObfuscatedAssemblyNames) foreach (var dllName in settings.obfuscationAssemblyNames)
{ {
string src = $"{opt.outputDir}/{dllName}.dll"; string src = $"{opt.outputDir}/{dllName}.dll";
string dst = $"{scriptAssembliesPath}/{dllName}.dll"; string dst = $"{scriptAssembliesPath}/{dllName}.dll";
if (!File.Exists(src))
{
Debug.LogWarning($"obfuscation assembly not found! skip copy. path:{src}");
continue;
}
File.Copy(src, dst, true); File.Copy(src, dst, true);
Debug.Log($"obfuscate dll:{dst}"); Debug.Log($"obfuscate dll:{dst}");
} }

View File

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Obfuz
{
public interface IObfuscationPass
{
void Start(ObfuscatorContext ctx);
void Stop(ObfuscatorContext ctx);
void Process(ObfuscatorContext ctx);
}
}

View File

@ -160,8 +160,6 @@ namespace Obfuz
private readonly Dictionary<string, AssemblyRuleSpec> _assemblyRuleSpecs = new Dictionary<string, AssemblyRuleSpec>(); private readonly Dictionary<string, AssemblyRuleSpec> _assemblyRuleSpecs = new Dictionary<string, AssemblyRuleSpec>();
public List<string> ObfuscatedAssemblyNames => _assemblyRuleSpecs.Keys.ToList();
private static readonly MethodRule s_noneMethodRule = new MethodRule private static readonly MethodRule s_noneMethodRule = new MethodRule
{ {
@ -520,6 +518,10 @@ namespace Obfuz
{ {
throw new Exception($"Invalid xml file, assembly name is empty"); throw new Exception($"Invalid xml file, assembly name is empty");
} }
if (!_obfuscationAssemblyNames.Contains(assemblyName))
{
throw new Exception($"unknown assembly name:{assemblyName}, not in ObfuzSettings.obfuscationAssemblyNames");
}
if (_assemblyRuleSpecs.ContainsKey(assemblyName)) if (_assemblyRuleSpecs.ContainsKey(assemblyName))
{ {
throw new Exception($"Invalid xml file, duplicate assembly name {assemblyName}"); throw new Exception($"Invalid xml file, duplicate assembly name {assemblyName}");
@ -703,6 +705,13 @@ namespace Obfuz
private readonly Dictionary<TypeDef, TypeDefComputeCache> _typeRenameCache = new Dictionary<TypeDef, TypeDefComputeCache>(); private readonly Dictionary<TypeDef, TypeDefComputeCache> _typeRenameCache = new Dictionary<TypeDef, TypeDefComputeCache>();
private readonly HashSet<string> _obfuscationAssemblyNames;
public ObfuscateRuleConfig(List<string> obfuscationAssemblyNames)
{
this._obfuscationAssemblyNames = obfuscationAssemblyNames.ToHashSet();
}
private TypeDefComputeCache GetOrCreateTypeDefRenameComputeCache(TypeDef typeDef) private TypeDefComputeCache GetOrCreateTypeDefRenameComputeCache(TypeDef typeDef)
{ {
if (_typeRenameCache.TryGetValue(typeDef, out var cache)) if (_typeRenameCache.TryGetValue(typeDef, out var cache))

View File

@ -0,0 +1,14 @@
namespace Obfuz
{
public abstract class ObfuscationPassBase : IObfuscationPass
{
public virtual void Start(ObfuscatorContext ctx)
{
}
public virtual void Stop(ObfuscatorContext ctx)
{
}
public abstract void Process(ObfuscatorContext ctx);
}
}

View File

@ -1,5 +1,6 @@
using dnlib.DotNet; using dnlib.DotNet;
using Obfuz.Rename; using Obfuz.Rename;
using Obfuz.Virtualization;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
@ -16,46 +17,60 @@ namespace Obfuz
{ {
public class Options public class Options
{ {
public List<string> AssemblySearchDirs; public List<string> obfuscationAssemblyNames;
public List<string> ObfuscationRuleFiles; public List<string> assemblySearchDirs;
public List<string> obfuscationRuleFiles;
public string mappingXmlPath; public string mappingXmlPath;
public string outputDir; public string outputDir;
} }
private readonly Options _options; private readonly Options _options;
private readonly AssemblyCache _assemblyCache; private readonly AssemblyCache _assemblyCache;
private readonly ObfuscateRuleConfig _obfuscateRuleConfig;
private readonly List<ObfuzAssemblyInfo> _obfuzAssemblies = new List<ObfuzAssemblyInfo>(); private readonly List<ObfuzAssemblyInfo> _obfuzAssemblies = new List<ObfuzAssemblyInfo>();
private readonly IRenamePolicy _renamePolicy;
private readonly INameMaker _nameMaker;
private SymbolRename _symbolRename;
public IList<string> ObfuscatedAssemblyNames => _obfuzAssemblies.Select(x => x.name).ToList(); private readonly List<string> _obfuscationAssemblyNames;
public IList<string> ObfuscationAssemblyNames => _obfuscationAssemblyNames;
private readonly ObfuzPipeline _pipeline = new ObfuzPipeline();
private readonly ObfuscatorContext _ctx;
public Obfuscator(Options options) public Obfuscator(Options options)
{ {
_options = options; _options = options;
_assemblyCache = new AssemblyCache(new PathAssemblyResolver(options.AssemblySearchDirs.ToArray())); _obfuscationAssemblyNames = options.obfuscationAssemblyNames;
_obfuscateRuleConfig = new ObfuscateRuleConfig(); _assemblyCache = new AssemblyCache(new PathAssemblyResolver(options.assemblySearchDirs.ToArray()));
_obfuscateRuleConfig.LoadXmls(options.ObfuscationRuleFiles);
_renamePolicy = new CacheRenamePolicy(new CombineRenamePolicy(new SystemRenamePolicy(), new UnityRenamePolicy(), _obfuscateRuleConfig)); _pipeline.AddPass(new DataVirtualizationPass());
//_nameMaker = new TestNameMaker(); _pipeline.AddPass(new RenameSymbolPass());
_nameMaker = NameMakerFactory.CreateNameMakerBaseASCIICharSet();
_ctx = new ObfuscatorContext
{
assemblyCache = _assemblyCache,
assemblies = _obfuzAssemblies,
obfuscationAssemblyNames = _obfuscationAssemblyNames,
obfuscationRuleFiles = options.obfuscationRuleFiles,
mappingXmlPath = _options.mappingXmlPath,
outputDir = options.outputDir,
};
} }
public void Run() public void Run()
{ {
LoadAssemblies(); LoadAssemblies();
Rename(); _pipeline.Start(_ctx);
Save(); DoObfuscation();
OnObfuscationFinished();
} }
private void LoadAssemblies() private void LoadAssemblies()
{ {
foreach (string assName in _obfuscateRuleConfig.ObfuscatedAssemblyNames) foreach (string assName in _obfuscationAssemblyNames)
{ {
ModuleDefMD mod = _assemblyCache.TryLoadModule(assName); ModuleDefMD mod = _assemblyCache.TryLoadModule(assName);
if (mod == null) if (mod == null)
@ -88,26 +103,20 @@ namespace Obfuz
} }
} }
private void Rename() private void DoObfuscation()
{
var ctx = new ObfuscatorContext
{
assemblyCache = _assemblyCache,
assemblies = _obfuzAssemblies,
renamePolicy = _renamePolicy,
nameMaker = _nameMaker,
mappingXmlPath = _options.mappingXmlPath,
outputDir = _options.outputDir,
};
_symbolRename = new SymbolRename(ctx);
_symbolRename.Process();
}
private void Save()
{ {
string outputDir = _options.outputDir; string outputDir = _options.outputDir;
FileUtil.RecreateDir(outputDir); FileUtil.RecreateDir(outputDir);
_symbolRename.Save();
_pipeline.Run(_ctx);
}
private void OnObfuscationFinished()
{
string outputDir = _options.outputDir;
_pipeline.Stop(_ctx);
foreach (var ass in _obfuzAssemblies) foreach (var ass in _obfuzAssemblies)
{ {
string outputFile = $"{outputDir}/{ass.module.Name}"; string outputFile = $"{outputDir}/{ass.module.Name}";

View File

@ -23,10 +23,8 @@ namespace Obfuz
public List<ObfuzAssemblyInfo> assemblies; public List<ObfuzAssemblyInfo> assemblies;
public IRenamePolicy renamePolicy; public List<string> obfuscationAssemblyNames;
public List<string> obfuscationRuleFiles;
public INameMaker nameMaker;
public string mappingXmlPath; public string mappingXmlPath;
public string outputDir; public string outputDir;

View File

@ -1,7 +1,40 @@
namespace Obfuz using System.Collections.Generic;
namespace Obfuz
{ {
public class ObfuzPipeline public class ObfuzPipeline
{ {
private readonly List<IObfuscationPass> _passes = new List<IObfuscationPass>();
public ObfuzPipeline AddPass(IObfuscationPass pass)
{
_passes.Add(pass);
return this;
}
public void Start(ObfuscatorContext ctx)
{
foreach (var pass in _passes)
{
pass.Start(ctx);
}
}
public void Stop(ObfuscatorContext ctx)
{
foreach (var pass in _passes)
{
pass.Stop(ctx);
}
}
public void Run(ObfuscatorContext ctx)
{
foreach (var pass in _passes)
{
pass.Process(ctx);
}
}
} }
} }

View File

@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Obfuz.Rename
{
public class RenameSymbolPass : ObfuscationPassBase
{
private SymbolRename _symbolRename;
public override void Start(ObfuscatorContext ctx)
{
_symbolRename = new SymbolRename(ctx);
}
public override void Stop(ObfuscatorContext ctx)
{
_symbolRename.Save();
}
public override void Process(ObfuscatorContext ctx)
{
_symbolRename.Process();
}
}
}

View File

@ -21,6 +21,7 @@ namespace Obfuz
private readonly AssemblyCache _assemblyCache; private readonly AssemblyCache _assemblyCache;
private readonly List<ObfuzAssemblyInfo> _obfuzAssemblies; private readonly List<ObfuzAssemblyInfo> _obfuzAssemblies;
private readonly HashSet<ModuleDef> _obfuscatedModules = new HashSet<ModuleDef>(); private readonly HashSet<ModuleDef> _obfuscatedModules = new HashSet<ModuleDef>();
private readonly ObfuscateRuleConfig _obfuscateRuleConfig;
private readonly IRenamePolicy _renamePolicy; private readonly IRenamePolicy _renamePolicy;
private readonly INameMaker _nameMaker; private readonly INameMaker _nameMaker;
private readonly Dictionary<ModuleDef, List<CustomAttributeInfo>> _customAttributeArgumentsWithTypeByMods = new Dictionary<ModuleDef, List<CustomAttributeInfo>>(); private readonly Dictionary<ModuleDef, List<CustomAttributeInfo>> _customAttributeArgumentsWithTypeByMods = new Dictionary<ModuleDef, List<CustomAttributeInfo>>();
@ -40,8 +41,10 @@ namespace Obfuz
_mappingXmlPath = ctx.mappingXmlPath; _mappingXmlPath = ctx.mappingXmlPath;
_assemblyCache = ctx.assemblyCache; _assemblyCache = ctx.assemblyCache;
_obfuzAssemblies = ctx.assemblies; _obfuzAssemblies = ctx.assemblies;
_renamePolicy = ctx.renamePolicy; _obfuscateRuleConfig = new ObfuscateRuleConfig(ctx.obfuscationAssemblyNames);
_nameMaker = ctx.nameMaker; _obfuscateRuleConfig.LoadXmls(ctx.obfuscationRuleFiles);
_renamePolicy = new CacheRenamePolicy(new CombineRenamePolicy(new SystemRenamePolicy(), new UnityRenamePolicy(), _obfuscateRuleConfig));
_nameMaker = NameMakerFactory.CreateNameMakerBaseASCIICharSet();
foreach (var mod in ctx.assemblies) foreach (var mod in ctx.assemblies)
{ {

View File

@ -29,6 +29,7 @@ namespace Obfuz
private SerializedObject _serializedObject; private SerializedObject _serializedObject;
private SerializedProperty _enable; private SerializedProperty _enable;
private SerializedProperty _obfuscationAssemblyNames;
private SerializedProperty _mappingFile; private SerializedProperty _mappingFile;
private SerializedProperty _ruleFiles; private SerializedProperty _ruleFiles;
private SerializedProperty _extraAssemblySearchDirs; private SerializedProperty _extraAssemblySearchDirs;
@ -49,6 +50,7 @@ namespace Obfuz
_serializedObject?.Dispose(); _serializedObject?.Dispose();
_serializedObject = new SerializedObject(setting); _serializedObject = new SerializedObject(setting);
_enable = _serializedObject.FindProperty("enable"); _enable = _serializedObject.FindProperty("enable");
_obfuscationAssemblyNames = _serializedObject.FindProperty("obfuscationAssemblyNames");
_mappingFile = _serializedObject.FindProperty("mappingFile"); _mappingFile = _serializedObject.FindProperty("mappingFile");
_ruleFiles = _serializedObject.FindProperty("ruleFiles"); _ruleFiles = _serializedObject.FindProperty("ruleFiles");
_extraAssemblySearchDirs = _serializedObject.FindProperty("extraAssemblySearchDirs"); _extraAssemblySearchDirs = _serializedObject.FindProperty("extraAssemblySearchDirs");
@ -72,6 +74,7 @@ namespace Obfuz
EditorGUI.BeginChangeCheck(); EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(_enable); EditorGUILayout.PropertyField(_enable);
EditorGUILayout.PropertyField(_obfuscationAssemblyNames);
EditorGUILayout.PropertyField(_mappingFile); EditorGUILayout.PropertyField(_mappingFile);
EditorGUILayout.PropertyField(_ruleFiles); EditorGUILayout.PropertyField(_ruleFiles);
EditorGUILayout.PropertyField(_extraAssemblySearchDirs); EditorGUILayout.PropertyField(_extraAssemblySearchDirs);

View File

@ -1,3 +1,4 @@
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Runtime.Remoting.Messaging; using System.Runtime.Remoting.Messaging;
using UnityEditor; using UnityEditor;
@ -12,6 +13,9 @@ namespace Obfuz
[Tooltip("enable Obfuz")] [Tooltip("enable Obfuz")]
public bool enable = true; public bool enable = true;
[Tooltip("obfuscation assembly names")]
public string[] obfuscationAssemblyNames;
[Tooltip("path of mapping.xml")] [Tooltip("path of mapping.xml")]
public string mappingFile = "Assets/Obfuz/mapping.xml"; public string mappingFile = "Assets/Obfuz/mapping.xml";

View File

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Obfuz.Virtualization
{
public class DataVirtualizationPass : ObfuscationPassBase
{
public override void Process(ObfuscatorContext ctx)
{
}
}
}