diff --git a/Editor/AssemblyCache.cs b/Editor/AssemblyCache.cs new file mode 100644 index 0000000..4740fd2 --- /dev/null +++ b/Editor/AssemblyCache.cs @@ -0,0 +1,75 @@ +using dnlib.DotNet; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Obfuz +{ + public class AssemblyCache + { + private readonly IAssemblyResolver _assemblyPathResolver; + private readonly ModuleContext _modCtx; + private readonly AssemblyResolver _asmResolver; + + + public ModuleContext ModCtx => _modCtx; + + public Dictionary LoadedModules { get; } = new Dictionary(); + + public AssemblyCache(IAssemblyResolver assemblyResolver) + { + _assemblyPathResolver = assemblyResolver; + _modCtx = ModuleDef.CreateModuleContext(); + _asmResolver = (AssemblyResolver)_modCtx.AssemblyResolver; + _asmResolver.EnableTypeDefCache = true; + _asmResolver.UseGAC = false; + } + + + public ModuleDefMD TryLoadModule(string moduleName) + { + string dllPath = _assemblyPathResolver.ResolveAssembly(moduleName); + if (string.IsNullOrEmpty(dllPath)) + { + return null; + } + return LoadModule(moduleName); + } + + public ModuleDefMD LoadModule(string moduleName) + { + // Debug.Log($"load module:{moduleName}"); + if (LoadedModules.TryGetValue(moduleName, out var mod)) + { + return mod; + } + string assemblyPath = _assemblyPathResolver.ResolveAssembly(moduleName); + if (string.IsNullOrEmpty(assemblyPath)) + { + throw new FileNotFoundException($"Assembly {moduleName} not found"); + } + mod = DoLoadModule(assemblyPath); + LoadedModules.Add(moduleName, mod); + + + foreach (var refAsm in mod.GetAssemblyRefs()) + { + LoadModule(refAsm.Name); + } + + return mod; + } + + private ModuleDefMD DoLoadModule(string dllPath) + { + //Debug.Log($"do load module:{dllPath}"); + ModuleDefMD mod = ModuleDefMD.Load(File.ReadAllBytes(dllPath), _modCtx); + mod.EnableTypeDefFindCache = true; + _asmResolver.AddToCache(mod); + return mod; + } + } +} diff --git a/Editor/AssemblyResolverBase.cs b/Editor/AssemblyResolverBase.cs new file mode 100644 index 0000000..108d5d5 --- /dev/null +++ b/Editor/AssemblyResolverBase.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Obfuz +{ + public abstract class AssemblyResolverBase : IAssemblyResolver + { + public abstract string ResolveAssembly(string assemblyName); + } +} diff --git a/Editor/IAssemblyResolver.cs b/Editor/IAssemblyResolver.cs new file mode 100644 index 0000000..0bf1d4f --- /dev/null +++ b/Editor/IAssemblyResolver.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Obfuz +{ + public interface IAssemblyResolver + { + string ResolveAssembly(string assemblyName); + } +} diff --git a/Editor/Obfuscator.cs b/Editor/Obfuscator.cs new file mode 100644 index 0000000..5c245c9 --- /dev/null +++ b/Editor/Obfuscator.cs @@ -0,0 +1,77 @@ +using dnlib.DotNet; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Obfuz +{ + + + public class Obfuscator + { + public class Options + { + public List AssemblySearchDirs; + public List ObfusAssemblyNames; + public string outputDir; + } + + private readonly Options _options; + private readonly AssemblyCache _assemblyCache; + + private readonly List _obfuzAssemblies = new List(); + + public Obfuscator(Options options) + { + _options = options; + _assemblyCache = new AssemblyCache(new PathAssemblyResolver(options.AssemblySearchDirs.ToArray())); + } + + public void DoIt() + { + LoadAssemblies(); + Rename(); + } + + private void LoadAssemblies() + { + foreach (string assName in _options.ObfusAssemblyNames) + { + ModuleDefMD mod = _assemblyCache.LoadModule(assName); + var obfuzAsm = new ObfuzAssemblyInfo + { + name = assName, + module = mod, + referenceMeAssemblies = new List(), + }; + _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)) + { + UnityEngine.Debug.Log($"assembly:{ass.name} reference to {refAssName}"); + refAssembly.referenceMeAssemblies.Add(ass); + } + } + } + } + + private void Rename() + { + var ctx = new ObfuscatorContext + { + assemblies = _obfuzAssemblies, + }; + var sr = new SymbolRename(ctx); + sr.Process(); + } + } +} diff --git a/Editor/ObfuscatorContext.cs b/Editor/ObfuscatorContext.cs new file mode 100644 index 0000000..7541bf0 --- /dev/null +++ b/Editor/ObfuscatorContext.cs @@ -0,0 +1,23 @@ +using dnlib.DotNet; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Obfuz +{ + public class ObfuzAssemblyInfo + { + public string name; + + public ModuleDefMD module; + + public List referenceMeAssemblies; + } + + public class ObfuscatorContext + { + public List assemblies; + } +} diff --git a/Editor/Obfuz.Editor.asmdef b/Editor/Obfuz.Editor.asmdef new file mode 100644 index 0000000..8d5031e --- /dev/null +++ b/Editor/Obfuz.Editor.asmdef @@ -0,0 +1,16 @@ +{ + "name": "Obfuz.Editor", + "rootNamespace": "", + "references": [], + "includePlatforms": [ + "Editor" + ], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Editor/ObfuzPipeline.cs b/Editor/ObfuzPipeline.cs new file mode 100644 index 0000000..2f36d57 --- /dev/null +++ b/Editor/ObfuzPipeline.cs @@ -0,0 +1,7 @@ +namespace Obfuz +{ + public class ObfuzPipeline + { + + } +} diff --git a/Editor/PathAssemblyResolver.cs b/Editor/PathAssemblyResolver.cs new file mode 100644 index 0000000..2ec6593 --- /dev/null +++ b/Editor/PathAssemblyResolver.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; + +namespace Obfuz +{ + public class PathAssemblyResolver : AssemblyResolverBase + { + private readonly string[] _searchPaths; + + public PathAssemblyResolver(params string[] searchPaths) + { + _searchPaths = searchPaths; + } + + public override string ResolveAssembly(string assemblyName) + { + foreach(var path in _searchPaths) + { + string assPath = Path.Combine(path, assemblyName + ".dll"); + if (File.Exists(assPath)) + { + Debug.Log($"resolve {assemblyName} at {assPath}"); + return assPath; + } + } + return null; + } + } +} diff --git a/Editor/Rename/RenamePolicy.cs b/Editor/Rename/RenamePolicy.cs new file mode 100644 index 0000000..105d0fc --- /dev/null +++ b/Editor/Rename/RenamePolicy.cs @@ -0,0 +1,102 @@ +using dnlib.DotNet; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Obfuz.Rename +{ + public interface IRenamePolicy + { + bool NeedKeepName(ModuleDefMD mod); + + bool NeedKeepName(TypeDef typeDef); + + bool NeedKeepName(MethodDef methodDef); + + bool NeedKeepName(FieldDef fieldDef); + + bool NeedKeepName(PropertyDef propertyDef); + + bool NeedKeepName(EventDef eventDef); + + + string GetNewName(ModuleDefMD mod, string originalName); + + string GetNewName(TypeDef typeDef, string originalName); + + string GetNewName(MethodDef methodDef, string originalName); + + string GetNewName(FieldDef fieldDef, string originalName); + + string GetNewName(PropertyDef propertyDef, string originalName); + + string GetNewName(EventDef eventDef, string originalName); + + + } + + public class RenamePolicy : IRenamePolicy + { + public bool NeedKeepName(ModuleDefMD mod) + { + return false; + } + public bool NeedKeepName(TypeDef typeDef) + { + return false; + } + + public bool NeedKeepName(MethodDef methodDef) + { + return false; + } + + public bool NeedKeepName(FieldDef fieldDef) + { + return false; + } + + public bool NeedKeepName(PropertyDef propertyDef) + { + return false; + } + + public bool NeedKeepName(EventDef eventDef) + { + return false; + } + + + public string GetNewName(ModuleDefMD mod, string originalName) + { + return originalName + "_obfuz_generated__"; + } + + public string GetNewName(TypeDef typeDef, string originalName) + { + return originalName + "_obfuz_generated__"; + } + + public string GetNewName(MethodDef methodDef, string originalName) + { + return originalName + "_obfuz_generated__"; + } + + public string GetNewName(FieldDef fieldDef, string originalName) + { + return originalName + "_obfuz_generated__"; + } + + public string GetNewName(PropertyDef propertyDef, string originalName) + { + return originalName + "_obfuz_generated__"; + } + + public string GetNewName(EventDef eventDef, string originalName) + { + return originalName + "_obfuz_generated__"; + } + } +} diff --git a/Editor/Rename/SymbolRename.cs b/Editor/Rename/SymbolRename.cs new file mode 100644 index 0000000..0cf0160 --- /dev/null +++ b/Editor/Rename/SymbolRename.cs @@ -0,0 +1,26 @@ +using Obfuz.Rename; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace Obfuz +{ + + public class SymbolRename + { + private readonly ObfuscatorContext _ctx; + + private readonly IRenamePolicy _renamePolicy; + + public SymbolRename(ObfuscatorContext ctx) + { + _ctx = ctx; + _renamePolicy = new RenamePolicy(); + } + + public void Process() + { + + } + } +} diff --git a/Plugins/dnlib.dll b/Plugins/dnlib.dll new file mode 100644 index 0000000..ba1f36d Binary files /dev/null and b/Plugins/dnlib.dll differ diff --git a/README.md b/README.md index f06bd68..a225568 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,3 @@ # Obfuz + Obfuz is a powerful code obfuscation tool designed specifically for Unity projects. diff --git a/package.json b/package.json new file mode 100644 index 0000000..3dd1a6f --- /dev/null +++ b/package.json @@ -0,0 +1,20 @@ +{ + "name": "com.code-philosophy.obfuz", + "version": "7.9.0", + "displayName": "Obfuz", + "description": "Obfuz is a powerful code obfuscation tool designed specifically for Unity projects.", + "category": "Editor", + "documentationUrl": "https://obfuz.doc.code-philosophy.com/#/", + "changelogUrl": "https://obfuz.doc.code-philosophy.com/RELEASELOG.MD", + "licensesUrl": "https://github.com/focus-creative-games/obfuz/blob/main/LICENSE", + "keywords": [ + "obfuscation", + "obfuscator", + "code-philosophy" + ], + "author": { + "name": "Code Philosophy", + "email": "obfuz@code-philosophy.com", + "url": "https://code-philosophy.com" + } +} \ No newline at end of file