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;
|
2025-05-01 10:45:31 +08:00
|
|
|
|
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-03 22:32:18 +08:00
|
|
|
|
|
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
|
2025-05-03 22:32:18 +08:00
|
|
|
|
{
|
|
|
|
|
assemblyCache = _assemblyCache,
|
2025-05-03 23:23:16 +08:00
|
|
|
|
toObfuscatedModules = _toObfuscatedModules,
|
|
|
|
|
obfuscatedAndNotObfuscatedModules = _obfuscatedAndNotObfuscatedModules,
|
2025-05-03 22:32:18 +08:00
|
|
|
|
toObfuscatedAssemblyNames = _toObfuscatedAssemblyNames,
|
|
|
|
|
notObfuscatedAssemblyNamesReferencingObfuscated = _notObfuscatedAssemblyNamesReferencingObfuscated,
|
|
|
|
|
obfuscatedAssemblyOutputDir = _obfuscatedAssemblyOutputDir,
|
2025-05-10 11:25:07 +08:00
|
|
|
|
|
|
|
|
|
random = random,
|
|
|
|
|
encryptor = encryptor,
|
|
|
|
|
rvaDataAllocator = rvaDataAllocator,
|
|
|
|
|
constFieldAllocator = constFieldAllocator,
|
2025-05-03 22:32:18 +08:00
|
|
|
|
};
|
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
|
|
|
|
}
|
|
|
|
|
}
|