2025-04-05 19:02:50 +08:00
|
|
|
|
using dnlib.DotNet;
|
2025-05-01 10:45:31 +08:00
|
|
|
|
using Obfuz.Emit;
|
2025-04-05 19:02:50 +08:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
2025-04-05 21:47:28 +08:00
|
|
|
|
using System.IO;
|
2025-04-05 19:02:50 +08:00
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading.Tasks;
|
2025-04-05 21:47:28 +08:00
|
|
|
|
using UnityEngine;
|
2025-04-05 19:02:50 +08:00
|
|
|
|
|
|
|
|
|
namespace Obfuz
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
public class Obfuscator
|
|
|
|
|
{
|
2025-05-03 21:43:50 +08:00
|
|
|
|
private readonly string _obfuscatedAssemblyOutputDir;
|
2025-04-05 19:02:50 +08:00
|
|
|
|
private readonly AssemblyCache _assemblyCache;
|
|
|
|
|
|
|
|
|
|
private readonly List<ObfuzAssemblyInfo> _obfuzAssemblies = new List<ObfuzAssemblyInfo>();
|
|
|
|
|
|
2025-04-05 21:47:28 +08:00
|
|
|
|
|
2025-05-03 21:43:50 +08:00
|
|
|
|
private readonly List<string> _toObfuscatedAssemblyNames;
|
|
|
|
|
private readonly List<string> _notObfuscatedAssemblyNamesReferencingObfuscated;
|
2025-04-21 09:57:34 +08:00
|
|
|
|
|
|
|
|
|
private readonly ObfuzPipeline _pipeline = new ObfuzPipeline();
|
|
|
|
|
|
|
|
|
|
private readonly ObfuscatorContext _ctx;
|
2025-04-17 22:02:48 +08:00
|
|
|
|
|
2025-05-03 21:43:50 +08:00
|
|
|
|
public Obfuscator(List<string> toObfuscatedAssemblyNames,
|
|
|
|
|
List<string> notObfuscatedAssemblyNamesReferencingObfuscated,
|
|
|
|
|
List<string> assemblySearchDirs,
|
|
|
|
|
string obfuscatedAssemblyOutputDir,
|
|
|
|
|
List<IObfuscationPass> obfuscationPasses)
|
2025-04-05 19:02:50 +08:00
|
|
|
|
{
|
2025-05-03 21:43:50 +08:00
|
|
|
|
_toObfuscatedAssemblyNames = toObfuscatedAssemblyNames;
|
|
|
|
|
_notObfuscatedAssemblyNamesReferencingObfuscated = notObfuscatedAssemblyNamesReferencingObfuscated;
|
|
|
|
|
_obfuscatedAssemblyOutputDir = obfuscatedAssemblyOutputDir;
|
|
|
|
|
|
2025-05-01 12:23:22 +08:00
|
|
|
|
MetadataImporter.Reset();
|
2025-05-03 21:43:50 +08:00
|
|
|
|
_assemblyCache = new AssemblyCache(new PathAssemblyResolver(assemblySearchDirs.ToArray()));
|
|
|
|
|
foreach (var pass in obfuscationPasses)
|
|
|
|
|
{
|
|
|
|
|
_pipeline.AddPass(pass);
|
|
|
|
|
}
|
2025-04-21 09:57:34 +08:00
|
|
|
|
|
2025-05-03 21:43:50 +08:00
|
|
|
|
//_pipeline.AddPass(new MemoryEncryptionPass());
|
|
|
|
|
////_pipeline.AddPass(new ProxyCallPass());
|
|
|
|
|
//_pipeline.AddPass(new ExprObfuscationPass());
|
|
|
|
|
//_pipeline.AddPass(new DataVirtualizationPass());
|
|
|
|
|
//_pipeline.AddPass(new RenameSymbolPass());
|
2025-04-21 21:02:47 +08:00
|
|
|
|
_pipeline.AddPass(new CleanUpInstructionPass());
|
2025-04-21 09:57:34 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_ctx = new ObfuscatorContext
|
|
|
|
|
{
|
|
|
|
|
assemblyCache = _assemblyCache,
|
|
|
|
|
assemblies = _obfuzAssemblies,
|
2025-05-03 21:43:50 +08:00
|
|
|
|
toObfuscatedAssemblyNames = _toObfuscatedAssemblyNames,
|
|
|
|
|
notObfuscatedAssemblyNamesReferencingObfuscated = _notObfuscatedAssemblyNamesReferencingObfuscated,
|
|
|
|
|
obfuscatedAssemblyOutputDir = _obfuscatedAssemblyOutputDir,
|
2025-04-21 09:57:34 +08:00
|
|
|
|
};
|
2025-04-16 13:12:21 +08:00
|
|
|
|
|
2025-04-05 19:02:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-04-16 23:03:41 +08:00
|
|
|
|
public void Run()
|
2025-05-03 21:43:50 +08:00
|
|
|
|
{
|
|
|
|
|
OnPreObfuscation();
|
|
|
|
|
DoObfuscation();
|
|
|
|
|
OnPostObfuscation();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void OnPreObfuscation()
|
2025-04-05 19:02:50 +08:00
|
|
|
|
{
|
|
|
|
|
LoadAssemblies();
|
2025-04-21 09:57:34 +08:00
|
|
|
|
_pipeline.Start(_ctx);
|
2025-04-05 19:02:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void LoadAssemblies()
|
|
|
|
|
{
|
2025-05-03 21:43:50 +08:00
|
|
|
|
foreach (string assName in _toObfuscatedAssemblyNames)
|
2025-04-05 19:02:50 +08:00
|
|
|
|
{
|
2025-04-17 22:02:48 +08:00
|
|
|
|
ModuleDefMD mod = _assemblyCache.TryLoadModule(assName);
|
|
|
|
|
if (mod == null)
|
|
|
|
|
{
|
|
|
|
|
Debug.Log($"assembly: {assName} not found! ignore.");
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2025-04-05 19:02:50 +08:00
|
|
|
|
var obfuzAsm = new ObfuzAssemblyInfo
|
|
|
|
|
{
|
|
|
|
|
name = assName,
|
|
|
|
|
module = mod,
|
|
|
|
|
referenceMeAssemblies = new List<ObfuzAssemblyInfo>(),
|
|
|
|
|
};
|
2025-04-05 21:47:28 +08:00
|
|
|
|
obfuzAsm.referenceMeAssemblies.Add(obfuzAsm);
|
2025-04-05 19:02:50 +08:00
|
|
|
|
_obfuzAssemblies.Add(obfuzAsm);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var assByName = _obfuzAssemblies.ToDictionary(x => x.name);
|
|
|
|
|
foreach (var ass in _obfuzAssemblies)
|
|
|
|
|
{
|
|
|
|
|
foreach (var refAss in ass.module.GetAssemblyRefs())
|
|
|
|
|
{
|
|
|
|
|
string refAssName = refAss.Name.ToString();
|
|
|
|
|
if (assByName.TryGetValue(refAssName, out var refAssembly))
|
|
|
|
|
{
|
2025-05-03 20:42:08 +08:00
|
|
|
|
//UnityEngine.Debug.Log($"assembly:{ass.name} reference to {refAssName}");
|
2025-04-05 19:02:50 +08:00
|
|
|
|
refAssembly.referenceMeAssemblies.Add(ass);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-21 09:57:34 +08:00
|
|
|
|
private void DoObfuscation()
|
2025-04-05 19:02:50 +08:00
|
|
|
|
{
|
2025-05-03 21:43:50 +08:00
|
|
|
|
FileUtil.RecreateDir(_obfuscatedAssemblyOutputDir);
|
2025-04-21 09:57:34 +08:00
|
|
|
|
|
|
|
|
|
_pipeline.Run(_ctx);
|
2025-04-05 19:02:50 +08:00
|
|
|
|
}
|
2025-04-05 21:47:28 +08:00
|
|
|
|
|
2025-05-03 21:43:50 +08:00
|
|
|
|
private void OnPostObfuscation()
|
2025-04-05 21:47:28 +08:00
|
|
|
|
{
|
2025-04-21 09:57:34 +08:00
|
|
|
|
_pipeline.Stop(_ctx);
|
|
|
|
|
|
2025-04-05 21:47:28 +08:00
|
|
|
|
foreach (var ass in _obfuzAssemblies)
|
|
|
|
|
{
|
2025-05-03 21:43:50 +08:00
|
|
|
|
string outputFile = $"{_obfuscatedAssemblyOutputDir}/{ass.module.Name}";
|
2025-04-05 21:47:28 +08:00
|
|
|
|
ass.module.Write(outputFile);
|
|
|
|
|
Debug.Log($"save module. oldName:{ass.name} newName:{ass.module.Name} output:{outputFile}");
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-04-05 19:02:50 +08:00
|
|
|
|
}
|
|
|
|
|
}
|