diff --git a/Editor/Emit/EvalStackCalculator.cs b/Editor/Emit/EvalStackCalculator.cs index 8ab3c87..788cb8e 100644 --- a/Editor/Emit/EvalStackCalculator.cs +++ b/Editor/Emit/EvalStackCalculator.cs @@ -651,7 +651,7 @@ namespace Obfuz.Emit } case Code.Isinst: { - PushStack(newPushedDatas, EvalDataType.Int32); + PushStack(newPushedDatas, EvalDataType.Ref); break; } case Code.Unbox: diff --git a/Editor/ObfusPasses/EvalStackObfus.meta b/Editor/ObfusPasses/EvalStackObfus.meta new file mode 100644 index 0000000..a52d43d --- /dev/null +++ b/Editor/ObfusPasses/EvalStackObfus.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4e82ef0b94e10314cbba0daabfdefe32 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/ObfusPasses/EvalStackObfus/ConfigurableObfuscationPolicy.cs b/Editor/ObfusPasses/EvalStackObfus/ConfigurableObfuscationPolicy.cs new file mode 100644 index 0000000..34feb5a --- /dev/null +++ b/Editor/ObfusPasses/EvalStackObfus/ConfigurableObfuscationPolicy.cs @@ -0,0 +1,150 @@ +using dnlib.DotNet; +using Obfuz.Conf; +using Obfuz.Settings; +using Obfuz.Utils; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Xml; +using UnityEditor.VersionControl; + +namespace Obfuz.ObfusPasses.EvalStackObfus +{ + struct ObfuscationRuleData + { + public readonly ObfuscationLevel obfuscationLevel; + public readonly float obfuscationPercentage; + public ObfuscationRuleData(ObfuscationLevel level, float percentage) + { + obfuscationLevel = level; + obfuscationPercentage = percentage; + } + } + + interface IObfuscationPolicy + { + bool NeedObfuscate(MethodDef method); + + ObfuscationRuleData GetObfuscationRuleData(MethodDef method); + } + + abstract class ObfuscationPolicyBase : IObfuscationPolicy + { + public abstract bool NeedObfuscate(MethodDef method); + + public abstract ObfuscationRuleData GetObfuscationRuleData(MethodDef method); + } + + class ConfigurableObfuscationPolicy : ObfuscationPolicyBase + { + class ObfuscationRule : IRule + { + public ObfuscationLevel? obfuscationLevel; + public float? obfuscationPercentage; + + public void InheritParent(ObfuscationRule parentRule) + { + if (obfuscationLevel == null) + obfuscationLevel = parentRule.obfuscationLevel; + if (obfuscationPercentage == null) + obfuscationPercentage = parentRule.obfuscationPercentage; + } + } + + class MethodSpec : MethodRuleBase + { + } + + class TypeSpec : TypeRuleBase + { + } + + class AssemblySpec : AssemblyRuleBase + { + } + + private static readonly ObfuscationRule s_default = new ObfuscationRule() + { + obfuscationLevel = ObfuscationLevel.Basic, + obfuscationPercentage = 0.5f, + }; + + private ObfuscationRule _global; + + private readonly XmlAssemblyTypeMethodRuleParser _xmlParser; + + private readonly Dictionary _methodRuleCache = new Dictionary(); + + public ConfigurableObfuscationPolicy(List toObfuscatedAssemblyNames, List xmlConfigFiles) + { + _xmlParser = new XmlAssemblyTypeMethodRuleParser( + toObfuscatedAssemblyNames, ParseObfuscationRule, ParseGlobal); + LoadConfigs(xmlConfigFiles); + } + + private void LoadConfigs(List configFiles) + { + _xmlParser.LoadConfigs(configFiles); + + if (_global == null) + { + _global = s_default; + } + else + { + _global.InheritParent(s_default); + } + _xmlParser.InheritParentRules(_global); + } + + private void ParseGlobal(string configFile, XmlElement ele) + { + switch (ele.Name) + { + case "global": _global = ParseObfuscationRule(configFile, ele); break; + default: throw new Exception($"Invalid xml file {configFile}, unknown node {ele.Name}"); + } + } + + private ObfuscationLevel ParseObfuscationLevel(string str) + { + return (ObfuscationLevel)Enum.Parse(typeof(ObfuscationLevel), str); + } + + private ObfuscationRule ParseObfuscationRule(string configFile, XmlElement ele) + { + var rule = new ObfuscationRule(); + if (ele.HasAttribute("obfuscationLevel")) + { + rule.obfuscationLevel = ParseObfuscationLevel(ele.GetAttribute("obfuscationLevel")); + } + if (ele.HasAttribute("obfuscationPercentage")) + { + rule.obfuscationPercentage = float.Parse(ele.GetAttribute("obfuscationPercentage")); + } + return rule; + } + + private ObfuscationRule GetMethodObfuscationRule(MethodDef method) + { + if (!_methodRuleCache.TryGetValue(method, out var rule)) + { + rule = _xmlParser.GetMethodRule(method, s_default); + _methodRuleCache[method] = rule; + } + return rule; + } + + public override bool NeedObfuscate(MethodDef method) + { + ObfuscationRule rule = GetMethodObfuscationRule(method); + return rule.obfuscationLevel.Value > ObfuscationLevel.None; + } + + public override ObfuscationRuleData GetObfuscationRuleData(MethodDef method) + { + var rule = GetMethodObfuscationRule(method); + return new ObfuscationRuleData(rule.obfuscationLevel.Value, rule.obfuscationPercentage.Value); + } + } +} diff --git a/Editor/ObfusPasses/EvalStackObfus/ConfigurableObfuscationPolicy.cs.meta b/Editor/ObfusPasses/EvalStackObfus/ConfigurableObfuscationPolicy.cs.meta new file mode 100644 index 0000000..e9520c4 --- /dev/null +++ b/Editor/ObfusPasses/EvalStackObfus/ConfigurableObfuscationPolicy.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8a2603d51f31a134d90599d33664f6c7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/ObfusPasses/EvalStackObfus/DefaultObfuscator.cs b/Editor/ObfusPasses/EvalStackObfus/DefaultObfuscator.cs new file mode 100644 index 0000000..d9b9183 --- /dev/null +++ b/Editor/ObfusPasses/EvalStackObfus/DefaultObfuscator.cs @@ -0,0 +1,225 @@ +using dnlib.DotNet.Emit; +using Obfuz.Utils; +using System.Collections.Generic; + +namespace Obfuz.ObfusPasses.EvalStackObfus +{ + class DefaultObfuscator : ObfuscatorBase + { + public override bool ObfuscateInt(Instruction inst, List outputInsts, ObfusMethodContext ctx) + { + IRandom random = ctx.localRandom; + switch (random.NextInt(4)) + { + case 0: + { + // x = x + a + int a = 0; + float constProbability = 0f; + ConstObfusUtil.LoadConstInt(a, random, constProbability, ctx.constFieldAllocator, outputInsts); + outputInsts.Add(Instruction.Create(OpCodes.Add)); + return true; + } + case 1: + { + // x = x * a * ra + int a = random.NextInt() | 0x1; // Ensure a is not zero + int ra = MathUtil.ModInverse32(a); + float constProbability = 0.5f; + ConstObfusUtil.LoadConstInt(a, random, constProbability, ctx.constFieldAllocator, outputInsts); + outputInsts.Add(Instruction.Create(OpCodes.Mul)); + ConstObfusUtil.LoadConstInt(ra, random, constProbability, ctx.constFieldAllocator, outputInsts); + outputInsts.Add(Instruction.Create(OpCodes.Mul)); + return true; + } + case 2: + { + // x = (x * a + b) * ra - (b * ra) + int a = random.NextInt() | 0x1; // Ensure a is not zero + int ra = MathUtil.ModInverse32(a); + int b = random.NextInt(); + int b_ra = -b * ra; + float constProbability = 0.5f; + ConstObfusUtil.LoadConstInt(a, random, constProbability, ctx.constFieldAllocator, outputInsts); + outputInsts.Add(Instruction.Create(OpCodes.Mul)); + ConstObfusUtil.LoadConstInt(b, random, constProbability, ctx.constFieldAllocator, outputInsts); + outputInsts.Add(Instruction.Create(OpCodes.Add)); + ConstObfusUtil.LoadConstInt(ra, random, constProbability, ctx.constFieldAllocator, outputInsts); + outputInsts.Add(Instruction.Create(OpCodes.Mul)); + ConstObfusUtil.LoadConstInt(b_ra, random, constProbability, ctx.constFieldAllocator, outputInsts); + outputInsts.Add(Instruction.Create(OpCodes.Add)); + return true; + } + case 3: + { + // x = ((x + a) * b + c) * rb - (a*b + c) * rb + int a = random.NextInt(); + int b = random.NextInt() | 0x1; // Ensure b is not zero + int rb = MathUtil.ModInverse32(b); + int c = random.NextInt(); + int r = -(a * b + c) * rb; + float constProbability = 0.5f; + ConstObfusUtil.LoadConstInt(a, random, constProbability, ctx.constFieldAllocator, outputInsts); + outputInsts.Add(Instruction.Create(OpCodes.Add)); + ConstObfusUtil.LoadConstInt(b, random, constProbability, ctx.constFieldAllocator, outputInsts); + outputInsts.Add(Instruction.Create(OpCodes.Mul)); + ConstObfusUtil.LoadConstInt(c, random, constProbability, ctx.constFieldAllocator, outputInsts); + outputInsts.Add(Instruction.Create(OpCodes.Add)); + ConstObfusUtil.LoadConstInt(rb, random, constProbability, ctx.constFieldAllocator, outputInsts); + outputInsts.Add(Instruction.Create(OpCodes.Mul)); + ConstObfusUtil.LoadConstInt(r, random, constProbability, ctx.constFieldAllocator, outputInsts); + outputInsts.Add(Instruction.Create(OpCodes.Add)); + return true; + } + default: return false; + } + } + + public override bool ObfuscateLong(Instruction inst, List outputInsts, ObfusMethodContext ctx) + { + IRandom random = ctx.localRandom; + switch (random.NextInt(4)) + { + case 0: + { + // x = x + a + long a = 0; + float constProbability = 0f; + ConstObfusUtil.LoadConstLong(a, random, constProbability, ctx.constFieldAllocator, outputInsts); + outputInsts.Add(Instruction.Create(OpCodes.Add)); + return true; + } + case 1: + { + // x = x * a * ra + long a = random.NextLong() | 0x1L; // Ensure a is not zero + long ra = MathUtil.ModInverse64(a); + float constProbability = 0.5f; + ConstObfusUtil.LoadConstLong(a, random, constProbability, ctx.constFieldAllocator, outputInsts); + outputInsts.Add(Instruction.Create(OpCodes.Mul)); + ConstObfusUtil.LoadConstLong(ra, random, constProbability, ctx.constFieldAllocator, outputInsts); + outputInsts.Add(Instruction.Create(OpCodes.Mul)); + return true; + } + case 2: + { + // x = (x * a + b) * ra - (b * ra) + long a = random.NextLong() | 0x1L; // Ensure a is not zero + long ra = MathUtil.ModInverse64(a); + long b = random.NextLong(); + long b_ra = -b * ra; + float constProbability = 0.5f; + ConstObfusUtil.LoadConstLong(a, random, constProbability, ctx.constFieldAllocator, outputInsts); + outputInsts.Add(Instruction.Create(OpCodes.Mul)); + ConstObfusUtil.LoadConstLong(b, random, constProbability, ctx.constFieldAllocator, outputInsts); + outputInsts.Add(Instruction.Create(OpCodes.Add)); + ConstObfusUtil.LoadConstLong(ra, random, constProbability, ctx.constFieldAllocator, outputInsts); + outputInsts.Add(Instruction.Create(OpCodes.Mul)); + ConstObfusUtil.LoadConstLong(b_ra, random, constProbability, ctx.constFieldAllocator, outputInsts); + outputInsts.Add(Instruction.Create(OpCodes.Add)); + return true; + } + case 3: + { + // x = ((x + a) * b + c) * rb - (a*b + c) * rb + long a = random.NextLong(); + long b = random.NextLong() | 0x1L; // Ensure b is not zero + long rb = MathUtil.ModInverse64(b); + long c = random.NextLong(); + long r = -(a * b + c) * rb; + float constProbability = 0.5f; + ConstObfusUtil.LoadConstLong(a, random, constProbability, ctx.constFieldAllocator, outputInsts); + outputInsts.Add(Instruction.Create(OpCodes.Add)); + ConstObfusUtil.LoadConstLong(b, random, constProbability, ctx.constFieldAllocator, outputInsts); + outputInsts.Add(Instruction.Create(OpCodes.Mul)); + ConstObfusUtil.LoadConstLong(c, random, constProbability, ctx.constFieldAllocator, outputInsts); + outputInsts.Add(Instruction.Create(OpCodes.Add)); + ConstObfusUtil.LoadConstLong(rb, random, constProbability, ctx.constFieldAllocator, outputInsts); + outputInsts.Add(Instruction.Create(OpCodes.Mul)); + ConstObfusUtil.LoadConstLong(r, random, constProbability, ctx.constFieldAllocator, outputInsts); + outputInsts.Add(Instruction.Create(OpCodes.Add)); + return true; + } + default: return false; + } + } + + public override bool ObfuscateFloat(Instruction inst, List outputInsts, ObfusMethodContext ctx) + { + IRandom random = ctx.localRandom; + switch (random.NextInt(3)) + { + case 0: + { + // x = x + 0f + float a = 0.0f; + float constProbability = 0f; + ConstObfusUtil.LoadConstFloat(a, random, constProbability, ctx.constFieldAllocator, outputInsts); + outputInsts.Add(Instruction.Create(OpCodes.Add)); + return true; + } + case 1: + { + // x = x * 1f; + float a = 1.0f; + float constProbability = 0f; + ConstObfusUtil.LoadConstFloat(a, random, constProbability, ctx.constFieldAllocator, outputInsts); + outputInsts.Add(Instruction.Create(OpCodes.Mul)); + return true; + } + case 2: + { + // x = (x + a) * b; a = 0.0f, b = 1.0f + float a = 0.0f; + float b = 1.0f; + float constProbability = 0f; + ConstObfusUtil.LoadConstFloat(a, random, constProbability, ctx.constFieldAllocator, outputInsts); + outputInsts.Add(Instruction.Create(OpCodes.Add)); + ConstObfusUtil.LoadConstFloat(b, random, constProbability, ctx.constFieldAllocator, outputInsts); + outputInsts.Add(Instruction.Create(OpCodes.Mul)); + return true; + } + default: return false; + } + } + + public override bool ObfuscateDouble(Instruction inst, List outputInsts, ObfusMethodContext ctx) + { + IRandom random = ctx.localRandom; + switch (random.NextInt(3)) + { + case 0: + { + // x = x + 0.0 + double a = 0.0; + float constProbability = 0f; + ConstObfusUtil.LoadConstDouble(a, random, constProbability, ctx.constFieldAllocator, outputInsts); + outputInsts.Add(Instruction.Create(OpCodes.Add)); + return true; + } + case 1: + { + // x = x * 1.0; + double a = 1.0; + float constProbability = 0f; + ConstObfusUtil.LoadConstDouble(a, random, constProbability, ctx.constFieldAllocator, outputInsts); + outputInsts.Add(Instruction.Create(OpCodes.Mul)); + return true; + } + case 2: + { + // x = (x + a) * b; a = 0.0, b = 1.0 + double a = 0.0; + double b = 1.0; + float constProbability = 0f; + ConstObfusUtil.LoadConstDouble(a, random, constProbability, ctx.constFieldAllocator, outputInsts); + outputInsts.Add(Instruction.Create(OpCodes.Add)); + ConstObfusUtil.LoadConstDouble(b, random, constProbability, ctx.constFieldAllocator, outputInsts); + outputInsts.Add(Instruction.Create(OpCodes.Mul)); + return true; + } + default: return false; + } + } + } +} diff --git a/Editor/ObfusPasses/EvalStackObfus/DefaultObfuscator.cs.meta b/Editor/ObfusPasses/EvalStackObfus/DefaultObfuscator.cs.meta new file mode 100644 index 0000000..d6a01e4 --- /dev/null +++ b/Editor/ObfusPasses/EvalStackObfus/DefaultObfuscator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5200244f403139c40b578b2e845508f2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/ObfusPasses/EvalStackObfus/EvalStackObfusPass.cs b/Editor/ObfusPasses/EvalStackObfus/EvalStackObfusPass.cs new file mode 100644 index 0000000..4d102d0 --- /dev/null +++ b/Editor/ObfusPasses/EvalStackObfus/EvalStackObfusPass.cs @@ -0,0 +1,117 @@ +using dnlib.DotNet; +using dnlib.DotNet.Emit; +using Obfuz.Data; +using Obfuz.Emit; +using Obfuz.Settings; +using Obfuz.Utils; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; + +namespace Obfuz.ObfusPasses.EvalStackObfus +{ + class ObfusMethodContext + { + public MethodDef method; + public EvalStackCalculator evalStackCalculator; + public LocalVariableAllocator localVariableAllocator; + public IRandom localRandom; + public EncryptionScopeInfo encryptionScope; + public DefaultMetadataImporter importer; + public ModuleConstFieldAllocator constFieldAllocator; + public float obfuscationPercentage; + } + + internal class EvalStackObfusPass : ObfuscationMethodPassBase + { + private readonly EvalStackObfuscationSettingsFacade _settings; + + private IObfuscationPolicy _obfuscationPolicy; + private IObfuscator _obfuscator; + + public EvalStackObfusPass(EvalStackObfuscationSettingsFacade settings) + { + _settings = settings; + _obfuscator = new DefaultObfuscator(); + } + + public override ObfuscationPassType Type => ObfuscationPassType.EvalStackObfus; + + public override void Start() + { + ObfuscationPassContext ctx = ObfuscationPassContext.Current; + _obfuscationPolicy = new ConfigurableObfuscationPolicy( + ctx.coreSettings.assembliesToObfuscate, + _settings.ruleFiles); + } + + public override void Stop() + { + + } + + protected override bool NeedObfuscateMethod(MethodDef method) + { + return _obfuscationPolicy.NeedObfuscate(method); + } + + protected bool TryObfuscateInstruction(Instruction inst, EvalDataType dataType, List outputInstructions, ObfusMethodContext ctx) + { + switch (dataType) + { + case EvalDataType.Int32: return _obfuscator.ObfuscateInt(inst, outputInstructions, ctx); + case EvalDataType.Int64: return _obfuscator.ObfuscateLong(inst, outputInstructions, ctx); + case EvalDataType.Float: return _obfuscator.ObfuscateFloat(inst, outputInstructions, ctx); + case EvalDataType.Double: return _obfuscator.ObfuscateDouble(inst, outputInstructions, ctx); + default: return false; + } + } + + protected override void ObfuscateData(MethodDef method) + { + Debug.Log($"Obfuscating method: {method.FullName} with EvalStackObfusPass"); + IList instructions = method.Body.Instructions; + var outputInstructions = new List(); + var totalFinalInstructions = new List(); + + ObfuscationPassContext ctx = ObfuscationPassContext.Current; + var calc = new EvalStackCalculator(method); + var encryptionScope = ctx.encryptionScopeProvider.GetScope(method.Module); + var ruleData = _obfuscationPolicy.GetObfuscationRuleData(method); + var localRandom = encryptionScope.localRandomCreator(MethodEqualityComparer.CompareDeclaringTypes.GetHashCode(method)); + var obfusMethodCtx = new ObfusMethodContext + { + method = method, + evalStackCalculator = calc, + localVariableAllocator = new LocalVariableAllocator(method), + encryptionScope = encryptionScope, + constFieldAllocator = ctx.constFieldAllocator.GetModuleAllocator(method.Module), + localRandom = localRandom, + importer = ctx.moduleEntityManager.GetDefaultModuleMetadataImporter(method.Module, ctx.encryptionScopeProvider), + obfuscationPercentage = ruleData.obfuscationPercentage, + }; + for (int i = 0; i < instructions.Count; i++) + { + Instruction inst = instructions[i]; + totalFinalInstructions.Add(inst); + if (calc.TryGetPushResult(inst, out EvalDataType dataType) && localRandom.NextInPercentage(ruleData.obfuscationPercentage)) + { + outputInstructions.Clear(); + if (TryObfuscateInstruction(inst, dataType, outputInstructions, obfusMethodCtx)) + { + totalFinalInstructions.AddRange(outputInstructions); + } + } + } + + instructions.Clear(); + foreach (var obInst in totalFinalInstructions) + { + instructions.Add(obInst); + } + } + } +} diff --git a/Editor/ObfusPasses/EvalStackObfus/EvalStackObfusPass.cs.meta b/Editor/ObfusPasses/EvalStackObfus/EvalStackObfusPass.cs.meta new file mode 100644 index 0000000..63a3a0c --- /dev/null +++ b/Editor/ObfusPasses/EvalStackObfus/EvalStackObfusPass.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9fa7d3313f260794da2cc36dadaf4fb4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/ObfusPasses/EvalStackObfus/IObfuscator.cs b/Editor/ObfusPasses/EvalStackObfus/IObfuscator.cs new file mode 100644 index 0000000..02bed58 --- /dev/null +++ b/Editor/ObfusPasses/EvalStackObfus/IObfuscator.cs @@ -0,0 +1,26 @@ +using dnlib.DotNet; +using dnlib.DotNet.Emit; +using Obfuz.Emit; +using System.Collections.Generic; + +namespace Obfuz.ObfusPasses.EvalStackObfus +{ + interface IObfuscator + { + bool ObfuscateInt(Instruction inst, List outputInsts, ObfusMethodContext ctx); + + bool ObfuscateLong(Instruction inst, List outputInsts, ObfusMethodContext ctx); + + bool ObfuscateFloat(Instruction inst, List outputInsts, ObfusMethodContext ctx); + + bool ObfuscateDouble(Instruction inst, List outputInsts, ObfusMethodContext ctx); + } + + abstract class ObfuscatorBase : IObfuscator + { + public abstract bool ObfuscateInt(Instruction inst, List outputInsts, ObfusMethodContext ctx); + public abstract bool ObfuscateLong(Instruction inst, List outputInsts, ObfusMethodContext ctx); + public abstract bool ObfuscateFloat(Instruction inst, List outputInsts, ObfusMethodContext ctx); + public abstract bool ObfuscateDouble(Instruction inst, List outputInsts, ObfusMethodContext ctx); + } +} diff --git a/Editor/ObfusPasses/EvalStackObfus/IObfuscator.cs.meta b/Editor/ObfusPasses/EvalStackObfus/IObfuscator.cs.meta new file mode 100644 index 0000000..a782f11 --- /dev/null +++ b/Editor/ObfusPasses/EvalStackObfus/IObfuscator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 17a9f3181d9711f4ca1d0cfb9e813bb0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/ObfusPasses/ExprObfus/ExprObfusPass.cs b/Editor/ObfusPasses/ExprObfus/ExprObfusPass.cs index f638468..661fb9a 100644 --- a/Editor/ObfusPasses/ExprObfus/ExprObfusPass.cs +++ b/Editor/ObfusPasses/ExprObfus/ExprObfusPass.cs @@ -115,7 +115,7 @@ namespace Obfuz.ObfusPasses.ExprObfus protected override void ObfuscateData(MethodDef method) { - Debug.Log($"Obfuscating method: {method.FullName} with ExprObfusPass"); + //Debug.Log($"Obfuscating method: {method.FullName} with ExprObfusPass"); IList instructions = method.Body.Instructions; var outputInstructions = new List(); var totalFinalInstructions = new List(); diff --git a/Editor/ObfusPasses/ObfuscationPassType.cs b/Editor/ObfusPasses/ObfuscationPassType.cs index ec28ad3..b5deb96 100644 --- a/Editor/ObfusPasses/ObfuscationPassType.cs +++ b/Editor/ObfusPasses/ObfuscationPassType.cs @@ -14,11 +14,12 @@ namespace Obfuz.ObfusPasses CallObfus = 0x200, ExprObfus = 0x400, ControlFlowObfus = 0x800, + EvalStackObfus = 0x1000, - AllObfus = SymbolObfus | CallObfus | ExprObfus | ControlFlowObfus, + AllObfus = SymbolObfus | CallObfus | ExprObfus | ControlFlowObfus | EvalStackObfus, AllEncrypt = ConstEncrypt | FieldEncrypt, - MethodBodyObfusOrEncrypt = ConstEncrypt | CallObfus | ExprObfus | ControlFlowObfus, + MethodBodyObfusOrEncrypt = ConstEncrypt | CallObfus | ExprObfus | ControlFlowObfus | EvalStackObfus, All = ~0, } diff --git a/Editor/ObfuscatorBuilder.cs b/Editor/ObfuscatorBuilder.cs index 87b39b3..6da2038 100644 --- a/Editor/ObfuscatorBuilder.cs +++ b/Editor/ObfuscatorBuilder.cs @@ -2,6 +2,7 @@ using Obfuz.ObfusPasses; using Obfuz.ObfusPasses.CallObfus; using Obfuz.ObfusPasses.ConstEncrypt; +using Obfuz.ObfusPasses.EvalStackObfus; using Obfuz.ObfusPasses.ExprObfus; using Obfuz.ObfusPasses.FieldEncrypt; using Obfuz.ObfusPasses.SymbolObfus; @@ -169,6 +170,10 @@ namespace Obfuz { builder.AddPass(new ConstEncryptPass(settings.constEncryptSettings.ToFacade())); } + if (obfuscationPasses.HasFlag(ObfuscationPassType.EvalStackObfus)) + { + builder.AddPass(new EvalStackObfusPass(settings.evalStackObfusSettings.ToFacade())); + } if (obfuscationPasses.HasFlag(ObfuscationPassType.FieldEncrypt)) { builder.AddPass(new FieldEncryptPass(settings.fieldEncryptSettings.ToFacade())); diff --git a/Editor/Settings/EvalStackObfuscationSettings.cs b/Editor/Settings/EvalStackObfuscationSettings.cs new file mode 100644 index 0000000..b880f53 --- /dev/null +++ b/Editor/Settings/EvalStackObfuscationSettings.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace Obfuz.Settings +{ + + public class EvalStackObfuscationSettingsFacade + { + public List ruleFiles; + } + + [Serializable] + public class EvalStackObfuscationSettings + { + [Tooltip("rule config xml files")] + public string[] ruleFiles; + + public EvalStackObfuscationSettingsFacade ToFacade() + { + return new EvalStackObfuscationSettingsFacade + { + ruleFiles = new List(ruleFiles ?? Array.Empty()), + }; + } + } +} diff --git a/Editor/Settings/EvalStackObfuscationSettings.cs.meta b/Editor/Settings/EvalStackObfuscationSettings.cs.meta new file mode 100644 index 0000000..8e4d8d5 --- /dev/null +++ b/Editor/Settings/EvalStackObfuscationSettings.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3c985896b3a4ef84292cb0cfbc79dc10 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Settings/ObfuzSettings.cs b/Editor/Settings/ObfuzSettings.cs index ba3e3fb..d81c0eb 100644 --- a/Editor/Settings/ObfuzSettings.cs +++ b/Editor/Settings/ObfuzSettings.cs @@ -28,6 +28,9 @@ namespace Obfuz.Settings [Tooltip("const encryption settings")] public ConstEncryptionSettings constEncryptSettings; + [Tooltip("eval stack obfuscation settings")] + public EvalStackObfuscationSettings evalStackObfusSettings; + [Tooltip("field encryption settings")] public FieldEncryptionSettings fieldEncryptSettings; diff --git a/Editor/Settings/ObfuzSettingsProvider.cs b/Editor/Settings/ObfuzSettingsProvider.cs index 470bc14..f487032 100644 --- a/Editor/Settings/ObfuzSettingsProvider.cs +++ b/Editor/Settings/ObfuzSettingsProvider.cs @@ -32,6 +32,7 @@ namespace Obfuz.Settings private SerializedProperty _symbolObfusSettings; private SerializedProperty _constEncryptSettings; + private SerializedProperty _evalStackObfusSettings; private SerializedProperty _fieldEncryptSettings; private SerializedProperty _callObfusSettings; private SerializedProperty _exprObfusSettings; @@ -65,6 +66,7 @@ namespace Obfuz.Settings _symbolObfusSettings = _serializedObject.FindProperty("symbolObfusSettings"); _constEncryptSettings = _serializedObject.FindProperty("constEncryptSettings"); + _evalStackObfusSettings = _serializedObject.FindProperty("evalStackObfusSettings"); _exprObfusSettings = _serializedObject.FindProperty("exprObfusSettings"); _fieldEncryptSettings = _serializedObject.FindProperty("fieldEncryptSettings"); _callObfusSettings = _serializedObject.FindProperty("callObfusSettings"); @@ -88,6 +90,7 @@ namespace Obfuz.Settings EditorGUILayout.PropertyField(_symbolObfusSettings); EditorGUILayout.PropertyField(_constEncryptSettings); + EditorGUILayout.PropertyField(_evalStackObfusSettings); EditorGUILayout.PropertyField(_exprObfusSettings); EditorGUILayout.PropertyField(_fieldEncryptSettings); EditorGUILayout.PropertyField(_callObfusSettings);