obfuz/Editor/Obfuscator.cs

138 lines
5.0 KiB
C#
Raw Normal View History

2025-04-05 19:02:50 +08:00
using dnlib.DotNet;
2025-05-10 11:25:07 +08:00
using dnlib.Protection;
using Obfuz.Data;
using Obfuz.Emit;
2025-05-11 12:53:24 +08:00
using Obfuz.EncryptionVM;
2025-05-04 19:55:10 +08:00
using Obfuz.ObfusPasses;
2025-05-10 18:25:43 +08:00
using Obfuz.ObfusPasses.CleanUp;
2025-05-04 19:24:14 +08:00
using Obfuz.Utils;
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-05-10 18:25:43 +08:00
using static UnityEditor.ObjectChangeEventStream;
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;
2025-05-03 21:43:50 +08:00
private readonly List<string> _toObfuscatedAssemblyNames;
private readonly List<string> _notObfuscatedAssemblyNamesReferencingObfuscated;
2025-05-03 23:23:16 +08:00
private readonly List<ModuleDef> _toObfuscatedModules = new List<ModuleDef>();
private readonly List<ModuleDef> _obfuscatedAndNotObfuscatedModules = new List<ModuleDef>();
2025-04-21 09:57:34 +08:00
2025-05-04 19:24:14 +08:00
private readonly Pipeline _pipeline = new Pipeline();
2025-05-11 09:17:04 +08:00
private readonly byte[] _secretKey;
private readonly int _globalRandomSeed;
2025-05-11 17:36:58 +08:00
private readonly string _encryptionVmGenerationSecretKey;
private readonly int _encryptionVmOpCodeCount;
2025-04-21 09:57:34 +08:00
2025-05-04 19:24:14 +08:00
private ObfuscationPassContext _ctx;
2025-04-17 22:02:48 +08:00
2025-05-11 17:36:58 +08:00
public Obfuscator(ObfuscatorBuilder builder)
2025-04-05 19:02:50 +08:00
{
2025-05-11 17:36:58 +08:00
_secretKey = KeyGenerator.GenerateKey(builder.SecretKey, VirtualMachine.SecretKeyLength);
_globalRandomSeed = builder.GlobalRandomSeed;
_encryptionVmGenerationSecretKey = builder.EncryptionVmGenerationSecretKey;
_encryptionVmOpCodeCount = builder.EncryptionVmOpCodeCount;
2025-05-11 09:17:04 +08:00
2025-05-11 17:36:58 +08:00
_toObfuscatedAssemblyNames = builder.ToObfuscatedAssemblyNames;
_notObfuscatedAssemblyNamesReferencingObfuscated = builder.NotObfuscatedAssemblyNamesReferencingObfuscated;
_obfuscatedAssemblyOutputDir = builder.ObfuscatedAssemblyOutputDir;
2025-05-03 21:43:50 +08:00
2025-05-11 08:53:48 +08:00
GroupByModuleEntityManager.Reset();
2025-05-11 17:36:58 +08:00
_assemblyCache = new AssemblyCache(new PathAssemblyResolver(builder.AssemblySearchDirs.ToArray()));
foreach (var pass in builder.ObfuscationPasses)
2025-05-03 21:43:50 +08:00
{
_pipeline.AddPass(pass);
}
2025-05-10 18:25:43 +08:00
_pipeline.AddPass(new CleanUpInstructionPass());
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();
}
2025-05-11 12:48:53 +08:00
private IEncryptor CreateEncryptionVirtualMachine()
{
2025-05-11 17:36:58 +08:00
var vmCreator = new VirtualMachineCreator(_encryptionVmGenerationSecretKey);
var vm = vmCreator.CreateVirtualMachine(_encryptionVmOpCodeCount);
return new VirtualMachineSimulator(vm, _secretKey);
2025-05-11 12:48:53 +08:00
}
2025-05-03 21:43:50 +08:00
private void OnPreObfuscation()
2025-04-05 19:02:50 +08:00
{
LoadAssemblies();
2025-05-10 11:25:07 +08:00
2025-05-11 09:17:04 +08:00
var random = new RandomWithKey(_secretKey, _globalRandomSeed);
2025-05-11 12:48:53 +08:00
var encryptor = CreateEncryptionVirtualMachine();
2025-05-10 11:25:07 +08:00
var rvaDataAllocator = new RvaDataAllocator(random, encryptor);
var constFieldAllocator = new ConstFieldAllocator(encryptor, random, rvaDataAllocator);
2025-05-04 19:24:14 +08:00
_ctx = new ObfuscationPassContext
{
assemblyCache = _assemblyCache,
2025-05-03 23:23:16 +08:00
toObfuscatedModules = _toObfuscatedModules,
obfuscatedAndNotObfuscatedModules = _obfuscatedAndNotObfuscatedModules,
toObfuscatedAssemblyNames = _toObfuscatedAssemblyNames,
notObfuscatedAssemblyNamesReferencingObfuscated = _notObfuscatedAssemblyNamesReferencingObfuscated,
obfuscatedAssemblyOutputDir = _obfuscatedAssemblyOutputDir,
2025-05-10 11:25:07 +08:00
random = random,
encryptor = encryptor,
rvaDataAllocator = rvaDataAllocator,
constFieldAllocator = constFieldAllocator,
};
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 23:23:16 +08:00
foreach (string assName in _toObfuscatedAssemblyNames.Concat(_notObfuscatedAssemblyNamesReferencingObfuscated))
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-05-03 23:23:16 +08:00
if (_toObfuscatedAssemblyNames.Contains(assName))
2025-04-05 19:02:50 +08:00
{
2025-05-03 23:23:16 +08:00
_toObfuscatedModules.Add(mod);
2025-04-05 19:02:50 +08:00
}
2025-05-03 23:23:16 +08:00
_obfuscatedAndNotObfuscatedModules.Add(mod);
2025-04-05 19:02:50 +08:00
}
}
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-05-03 23:23:16 +08:00
foreach (ModuleDef mod in _obfuscatedAndNotObfuscatedModules)
2025-04-05 21:47:28 +08:00
{
2025-05-03 23:23:16 +08:00
string assNameWithExt = mod.Name;
string outputFile = $"{_obfuscatedAssemblyOutputDir}/{assNameWithExt}";
mod.Write(outputFile);
Debug.Log($"save module. name:{mod.Assembly.Name} output:{outputFile}");
2025-04-05 21:47:28 +08:00
}
}
2025-04-05 19:02:50 +08:00
}
}