From 50dba09c6a7ab6b3c35661bcf76d2432ba89441d Mon Sep 17 00:00:00 2001 From: walon Date: Fri, 9 May 2025 11:03:05 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9Econst=20encrypt=20cache?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E9=85=8D=E7=BD=AE=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ObfusPasses/ConstObfus/ConstObfusPass.cs | 37 +++++---- .../ConstObfus/DefaultConstObfuscator.cs | 13 ++-- .../ObfusPasses/ConstObfus/IDataObfuscator.cs | 12 +-- .../ConstObfus/IObfuscationPolicy.cs | 22 ++++-- .../Policies/ConfigurableObfuscationPolicy.cs | 78 +++++++++++++++++-- .../Policies/ObfuscationPolicyBase.cs | 13 ++-- 6 files changed, 129 insertions(+), 46 deletions(-) diff --git a/Editor/ObfusPasses/ConstObfus/ConstObfusPass.cs b/Editor/ObfusPasses/ConstObfus/ConstObfusPass.cs index eea90c6..92c2c74 100644 --- a/Editor/ObfusPasses/ConstObfus/ConstObfusPass.cs +++ b/Editor/ObfusPasses/ConstObfus/ConstObfusPass.cs @@ -43,6 +43,8 @@ namespace Obfuz.ObfusPasses.ConstObfus protected override bool TryObfuscateInstruction(MethodDef method, Instruction inst, IList instructions, int instructionIndex, List outputInstructions, List totalFinalInstructions) { + bool currentInLoop = false; + ConstCachePolicy constCachePolicy = _dataObfuscatorPolicy.GetMethodConstCachePolicy(method); switch (inst.OpCode.OperandType) { case OperandType.InlineI: @@ -51,58 +53,59 @@ namespace Obfuz.ObfusPasses.ConstObfus case OperandType.ShortInlineR: case OperandType.InlineR: { + bool needCache = currentInLoop ? constCachePolicy.cacheConstInLoop : constCachePolicy.cacheConstNotInLoop; object operand = inst.Operand; if (operand is int) { int value = (int)operand; - if (_dataObfuscatorPolicy.NeedObfuscateInt(method, value)) + if (_dataObfuscatorPolicy.NeedObfuscateInt(method, currentInLoop, value)) { - _dataObfuscator.ObfuscateInt(method, value, outputInstructions); + _dataObfuscator.ObfuscateInt(method, needCache, value, outputInstructions); return true; } } else if (operand is sbyte) { int value = (sbyte)operand; - if (_dataObfuscatorPolicy.NeedObfuscateInt(method, value)) + if (_dataObfuscatorPolicy.NeedObfuscateInt(method, currentInLoop, value)) { - _dataObfuscator.ObfuscateInt(method, value, outputInstructions); + _dataObfuscator.ObfuscateInt(method, needCache, value, outputInstructions); return true; } } else if (operand is byte) { int value = (byte)operand; - if (_dataObfuscatorPolicy.NeedObfuscateInt(method, value)) + if (_dataObfuscatorPolicy.NeedObfuscateInt(method, currentInLoop, value)) { - _dataObfuscator.ObfuscateInt(method, value, outputInstructions); + _dataObfuscator.ObfuscateInt(method, needCache, value, outputInstructions); return true; } } else if (operand is long) { long value = (long)operand; - if (_dataObfuscatorPolicy.NeedObfuscateLong(method, value)) + if (_dataObfuscatorPolicy.NeedObfuscateLong(method, currentInLoop, value)) { - _dataObfuscator.ObfuscateLong(method, value, outputInstructions); + _dataObfuscator.ObfuscateLong(method, needCache, value, outputInstructions); return true; } } else if (operand is float) { float value = (float)operand; - if (_dataObfuscatorPolicy.NeedObfuscateFloat(method, value)) + if (_dataObfuscatorPolicy.NeedObfuscateFloat(method, currentInLoop, value)) { - _dataObfuscator.ObfuscateFloat(method, value, outputInstructions); + _dataObfuscator.ObfuscateFloat(method, needCache, value, outputInstructions); return true; } } else if (operand is double) { double value = (double)operand; - if (_dataObfuscatorPolicy.NeedObfuscateDouble(method, value)) + if (_dataObfuscatorPolicy.NeedObfuscateDouble(method, currentInLoop, value)) { - _dataObfuscator.ObfuscateDouble(method, value, outputInstructions); + _dataObfuscator.ObfuscateDouble(method, needCache, value, outputInstructions); return true; } } @@ -112,9 +115,10 @@ namespace Obfuz.ObfusPasses.ConstObfus { //RuntimeHelpers.InitializeArray string value = (string)inst.Operand; - if (_dataObfuscatorPolicy.NeedObfuscateString(method, value)) + if (_dataObfuscatorPolicy.NeedObfuscateString(method, currentInLoop, value)) { - _dataObfuscator.ObfuscateString(method, value, outputInstructions); + bool needCache = currentInLoop ? constCachePolicy.cacheStringInLoop : constCachePolicy.cacheStringNotInLoop; + _dataObfuscator.ObfuscateString(method, needCache, value, outputInstructions); return true; } return false; @@ -129,12 +133,13 @@ namespace Obfuz.ObfusPasses.ConstObfus IField rvaField = (IField)prevInst.Operand; FieldDef ravFieldDef = rvaField.ResolveFieldDefThrow(); byte[] data = ravFieldDef.InitialValue; - if (data != null && _dataObfuscatorPolicy.NeedObfuscateArray(method, data)) + if (data != null && _dataObfuscatorPolicy.NeedObfuscateArray(method, currentInLoop, data)) { // remove prev ldtoken instruction Assert.AreEqual(Code.Ldtoken, totalFinalInstructions[totalFinalInstructions.Count - 1].OpCode.Code); totalFinalInstructions.RemoveAt(totalFinalInstructions.Count - 1); - _dataObfuscator.ObfuscateBytes(method, data, outputInstructions); + bool needCache = currentInLoop ? constCachePolicy.cacheStringInLoop : constCachePolicy.cacheStringNotInLoop; + _dataObfuscator.ObfuscateBytes(method, needCache, data, outputInstructions); return true; } } diff --git a/Editor/ObfusPasses/ConstObfus/DefaultConstObfuscator.cs b/Editor/ObfusPasses/ConstObfus/DefaultConstObfuscator.cs index d4fe772..d4d04f7 100644 --- a/Editor/ObfusPasses/ConstObfus/DefaultConstObfuscator.cs +++ b/Editor/ObfusPasses/ConstObfus/DefaultConstObfuscator.cs @@ -40,8 +40,9 @@ namespace Obfuz.ObfusPasses.ConstObfus return MetadataImporter.Instance.GetDefaultModuleMetadataImporter(method.Module); } - public void ObfuscateInt(MethodDef method, int value, List obfuscatedInstructions) + public void ObfuscateInt(MethodDef method, bool needCacheValue, int value, List obfuscatedInstructions) { + int ops = GenerateEncryptionOperations(); int salt = GenerateSalt(); int encryptedValue = _encryptor.Encrypt(value, ops, salt); @@ -55,7 +56,7 @@ namespace Obfuz.ObfusPasses.ConstObfus obfuscatedInstructions.Add(Instruction.Create(OpCodes.Call, importer.DecryptFromRvaInt)); } - public void ObfuscateLong(MethodDef method, long value, List obfuscatedInstructions) + public void ObfuscateLong(MethodDef method, bool needCacheValue, long value, List obfuscatedInstructions) { int ops = GenerateEncryptionOperations(); int salt = GenerateSalt(); @@ -70,7 +71,7 @@ namespace Obfuz.ObfusPasses.ConstObfus obfuscatedInstructions.Add(Instruction.Create(OpCodes.Call, importer.DecryptFromRvaLong)); } - public void ObfuscateFloat(MethodDef method, float value, List obfuscatedInstructions) + public void ObfuscateFloat(MethodDef method, bool needCacheValue, float value, List obfuscatedInstructions) { int ops = GenerateEncryptionOperations(); int salt = GenerateSalt(); @@ -85,7 +86,7 @@ namespace Obfuz.ObfusPasses.ConstObfus obfuscatedInstructions.Add(Instruction.Create(OpCodes.Call, importer.DecryptFromRvaFloat)); } - public void ObfuscateDouble(MethodDef method, double value, List obfuscatedInstructions) + public void ObfuscateDouble(MethodDef method, bool needCacheValue, double value, List obfuscatedInstructions) { int ops = GenerateEncryptionOperations(); int salt = GenerateSalt(); @@ -100,7 +101,7 @@ namespace Obfuz.ObfusPasses.ConstObfus obfuscatedInstructions.Add(Instruction.Create(OpCodes.Call, importer.DecryptFromRvaDouble)); } - public void ObfuscateBytes(MethodDef method, byte[] value, List obfuscatedInstructions) + public void ObfuscateBytes(MethodDef method, bool needCacheValue, byte[] value, List obfuscatedInstructions) { int ops = GenerateEncryptionOperations(); int salt = GenerateSalt(); @@ -118,7 +119,7 @@ namespace Obfuz.ObfusPasses.ConstObfus obfuscatedInstructions.Add(Instruction.Create(OpCodes.Call, importer.DecryptFromRvaBytes)); } - public void ObfuscateString(MethodDef method, string value, List obfuscatedInstructions) + public void ObfuscateString(MethodDef method, bool needCacheValue, string value, List obfuscatedInstructions) { //int ops = GenerateEncryptionOperations(); //int salt = GenerateSalt(); diff --git a/Editor/ObfusPasses/ConstObfus/IDataObfuscator.cs b/Editor/ObfusPasses/ConstObfus/IDataObfuscator.cs index 19ef939..ab5a9f6 100644 --- a/Editor/ObfusPasses/ConstObfus/IDataObfuscator.cs +++ b/Editor/ObfusPasses/ConstObfus/IDataObfuscator.cs @@ -7,17 +7,17 @@ namespace Obfuz.ObfusPasses.ConstObfus { public interface IDataObfuscator { - void ObfuscateInt(MethodDef method, int value, List obfuscatedInstructions); + void ObfuscateInt(MethodDef method, bool needCacheValue, int value, List obfuscatedInstructions); - void ObfuscateLong(MethodDef method, long value, List obfuscatedInstructions); + void ObfuscateLong(MethodDef method, bool needCacheValue, long value, List obfuscatedInstructions); - void ObfuscateFloat(MethodDef method, float value, List obfuscatedInstructions); + void ObfuscateFloat(MethodDef method, bool needCacheValue, float value, List obfuscatedInstructions); - void ObfuscateDouble(MethodDef method, double value, List obfuscatedInstructions); + void ObfuscateDouble(MethodDef method, bool needCacheValue, double value, List obfuscatedInstructions); - void ObfuscateString(MethodDef method, string value, List obfuscatedInstructions); + void ObfuscateString(MethodDef method, bool needCacheValue, string value, List obfuscatedInstructions); - void ObfuscateBytes(MethodDef method, byte[] value, List obfuscatedInstructions); + void ObfuscateBytes(MethodDef method, bool needCacheValue, byte[] value, List obfuscatedInstructions); void Done(); } diff --git a/Editor/ObfusPasses/ConstObfus/IObfuscationPolicy.cs b/Editor/ObfusPasses/ConstObfus/IObfuscationPolicy.cs index 61bba55..9d18bb7 100644 --- a/Editor/ObfusPasses/ConstObfus/IObfuscationPolicy.cs +++ b/Editor/ObfusPasses/ConstObfus/IObfuscationPolicy.cs @@ -7,20 +7,30 @@ using System.Threading.Tasks; namespace Obfuz.ObfusPasses.ConstObfus { + public struct ConstCachePolicy + { + public bool cacheConstInLoop; + public bool cacheConstNotInLoop; + public bool cacheStringInLoop; + public bool cacheStringNotInLoop; + } + public interface IObfuscationPolicy { bool NeedObfuscateMethod(MethodDef method); - bool NeedObfuscateInt(MethodDef method, int value); + ConstCachePolicy GetMethodConstCachePolicy(MethodDef method); - bool NeedObfuscateLong(MethodDef method, long value); + bool NeedObfuscateInt(MethodDef method, bool currentInLoop, int value); - bool NeedObfuscateFloat(MethodDef method, float value); + bool NeedObfuscateLong(MethodDef method, bool currentInLoop, long value); - bool NeedObfuscateDouble(MethodDef method, double value); + bool NeedObfuscateFloat(MethodDef method, bool currentInLoop, float value); - bool NeedObfuscateString(MethodDef method, string value); + bool NeedObfuscateDouble(MethodDef method, bool currentInLoop, double value); - bool NeedObfuscateArray(MethodDef method, byte[] array); + bool NeedObfuscateString(MethodDef method, bool currentInLoop, string value); + + bool NeedObfuscateArray(MethodDef method, bool currentInLoop, byte[] array); } } diff --git a/Editor/ObfusPasses/ConstObfus/Policies/ConfigurableObfuscationPolicy.cs b/Editor/ObfusPasses/ConstObfus/Policies/ConfigurableObfuscationPolicy.cs index 50edd21..9e5185d 100644 --- a/Editor/ObfusPasses/ConstObfus/Policies/ConfigurableObfuscationPolicy.cs +++ b/Editor/ObfusPasses/ConstObfus/Policies/ConfigurableObfuscationPolicy.cs @@ -35,9 +35,15 @@ namespace Obfuz.ObfusPasses.ConstObfus.Policies public bool? encryptDouble; public bool? encryptArray; public bool? encryptString; + + public bool? encryptConstInLoop; + public bool? encryptStringInLoop; + public bool? cacheConstInLoop; public bool? cacheConstNotInLoop; + public bool? cacheStringInLoop; public bool? cacheStringNotInLoop; + public HashSet notEncryptInts = new HashSet(); public HashSet notEncryptLongs = new HashSet(); public HashSet notEncryptStrings = new HashSet(); @@ -64,10 +70,18 @@ namespace Obfuz.ObfusPasses.ConstObfus.Policies encryptArray = parentRule.encryptArray; if (encryptString == null) encryptString = parentRule.encryptString; + + if (encryptConstInLoop == null) + encryptConstInLoop = parentRule.encryptConstInLoop; + if (encryptStringInLoop == null) + encryptStringInLoop = parentRule.encryptStringInLoop; + if (cacheConstInLoop == null) cacheConstInLoop = parentRule.cacheConstInLoop; if (cacheConstNotInLoop == null) cacheConstNotInLoop = parentRule.cacheConstNotInLoop; + if (cacheStringInLoop == null) + cacheStringInLoop = parentRule.cacheStringInLoop; if (cacheStringNotInLoop == null) cacheStringNotInLoop = parentRule.cacheStringNotInLoop; @@ -114,8 +128,11 @@ namespace Obfuz.ObfusPasses.ConstObfus.Policies encryptDouble = true, encryptArray = true, encryptString = true, + encryptConstInLoop = true, + encryptStringInLoop = true, cacheConstInLoop = true, cacheConstNotInLoop = false, + cacheStringInLoop = true, cacheStringNotInLoop = true, }; @@ -276,6 +293,15 @@ namespace Obfuz.ObfusPasses.ConstObfus.Policies { rule.encryptString = ParseBool(ele.GetAttribute("encryptString")); } + + if (ele.HasAttribute("encryptConstInLoop")) + { + rule.encryptConstInLoop = ParseBool(ele.GetAttribute("encryptConstInLoop")); + } + if (ele.HasAttribute("encryptStringInLoop")) + { + rule.encryptStringInLoop = ParseBool(ele.GetAttribute("encryptStringInLoop")); + } if (ele.HasAttribute("cacheConstInLoop")) { rule.cacheConstInLoop = ParseBool(ele.GetAttribute("cacheConstInLoop")); @@ -284,6 +310,10 @@ namespace Obfuz.ObfusPasses.ConstObfus.Policies { rule.cacheConstNotInLoop = ParseBool(ele.GetAttribute("cacheConstNotInLoop")); } + if (ele.HasAttribute("cacheStringInLoop")) + { + rule.cacheStringInLoop = ParseBool(ele.GetAttribute("cacheStringInLoop")); + } if (ele.HasAttribute("cacheStringNotInLoop")) { rule.cacheStringNotInLoop = ParseBool(ele.GetAttribute("cacheStringNotInLoop")); @@ -509,13 +539,29 @@ namespace Obfuz.ObfusPasses.ConstObfus.Policies return rule.disableEncrypt != true; } - public override bool NeedObfuscateInt(MethodDef method, int value) + public override ConstCachePolicy GetMethodConstCachePolicy(MethodDef method) + { + ObfuscationRule rule = GetMethodObfuscationRule(method); + return new ConstCachePolicy + { + cacheConstInLoop = rule.cacheConstInLoop.Value, + cacheConstNotInLoop = rule.cacheConstNotInLoop.Value, + cacheStringInLoop = rule.cacheStringInLoop.Value, + cacheStringNotInLoop = rule.cacheStringNotInLoop.Value, + }; + } + + public override bool NeedObfuscateInt(MethodDef method, bool currentInLoop, int value) { ObfuscationRule rule = GetMethodObfuscationRule(method); if (rule.encryptInt == false) { return false; } + if (currentInLoop && rule.encryptConstInLoop == false) + { + return false; + } if (rule.notEncryptInts.Contains(value)) { return false; @@ -535,13 +581,17 @@ namespace Obfuz.ObfusPasses.ConstObfus.Policies return true; } - public override bool NeedObfuscateLong(MethodDef method, long value) + public override bool NeedObfuscateLong(MethodDef method, bool currentInLoop, long value) { ObfuscationRule rule = GetMethodObfuscationRule(method); if (rule.encryptLong == false) { return false; } + if (currentInLoop && rule.encryptConstInLoop == false) + { + return false; + } if (rule.notEncryptLongs.Contains(value)) { return false; @@ -561,13 +611,17 @@ namespace Obfuz.ObfusPasses.ConstObfus.Policies return true; } - public override bool NeedObfuscateFloat(MethodDef method, float value) + public override bool NeedObfuscateFloat(MethodDef method, bool currentInLoop, float value) { ObfuscationRule rule = GetMethodObfuscationRule(method); if (rule.encryptFloat == false) { return false; } + if (currentInLoop && rule.encryptConstInLoop == false) + { + return false; + } foreach (var range in rule.notEncryptFloatRanges) { if (range.min != null && value < range.min) @@ -583,13 +637,17 @@ namespace Obfuz.ObfusPasses.ConstObfus.Policies return true; } - public override bool NeedObfuscateDouble(MethodDef method, double value) + public override bool NeedObfuscateDouble(MethodDef method, bool currentInLoop, double value) { ObfuscationRule rule = GetMethodObfuscationRule(method); if (rule.encryptDouble == false) { return false; } + if (currentInLoop && rule.encryptConstInLoop == false) + { + return false; + } foreach (var range in rule.notEncryptDoubleRanges) { if (range.min != null && value < range.min) @@ -605,13 +663,17 @@ namespace Obfuz.ObfusPasses.ConstObfus.Policies return true; } - public override bool NeedObfuscateString(MethodDef method, string value) + public override bool NeedObfuscateString(MethodDef method, bool currentInLoop, string value) { ObfuscationRule rule = GetMethodObfuscationRule(method); if (rule.encryptString == false) { return false; } + if (currentInLoop && rule.encryptConstInLoop == false) + { + return false; + } if (rule.notEncryptStrings.Contains(value)) { return false; @@ -631,13 +693,17 @@ namespace Obfuz.ObfusPasses.ConstObfus.Policies return true; } - public override bool NeedObfuscateArray(MethodDef method, byte[] array) + public override bool NeedObfuscateArray(MethodDef method, bool currentInLoop, byte[] array) { ObfuscationRule rule = GetMethodObfuscationRule(method); if (rule.encryptArray == false) { return false; } + if (currentInLoop && rule.encryptConstInLoop == false) + { + return false; + } foreach (var range in rule.notEncryptArrayLengthRanges) { if (range.min != null && array.Length < range.min) diff --git a/Editor/ObfusPasses/ConstObfus/Policies/ObfuscationPolicyBase.cs b/Editor/ObfusPasses/ConstObfus/Policies/ObfuscationPolicyBase.cs index df9637e..a721d4e 100644 --- a/Editor/ObfusPasses/ConstObfus/Policies/ObfuscationPolicyBase.cs +++ b/Editor/ObfusPasses/ConstObfus/Policies/ObfuscationPolicyBase.cs @@ -5,11 +5,12 @@ namespace Obfuz.ObfusPasses.ConstObfus.Policies public abstract class ObfuscationPolicyBase : IObfuscationPolicy { public abstract bool NeedObfuscateMethod(MethodDef method); - public abstract bool NeedObfuscateDouble(MethodDef method, double value); - public abstract bool NeedObfuscateFloat(MethodDef method, float value); - public abstract bool NeedObfuscateInt(MethodDef method, int value); - public abstract bool NeedObfuscateLong(MethodDef method, long value); - public abstract bool NeedObfuscateString(MethodDef method, string value); - public abstract bool NeedObfuscateArray(MethodDef method, byte[] array); + public abstract ConstCachePolicy GetMethodConstCachePolicy(MethodDef method); + public abstract bool NeedObfuscateDouble(MethodDef method, bool currentInLoop, double value); + public abstract bool NeedObfuscateFloat(MethodDef method, bool currentInLoop, float value); + public abstract bool NeedObfuscateInt(MethodDef method, bool currentInLoop, int value); + public abstract bool NeedObfuscateLong(MethodDef method, bool currentInLoop, long value); + public abstract bool NeedObfuscateString(MethodDef method, bool currentInLoop, string value); + public abstract bool NeedObfuscateArray(MethodDef method, bool currentInLoop, byte[] array); } }