新增const encrypt cache相关配置项

backup
walon 2025-05-09 11:03:05 +08:00
parent f4aa76ca39
commit 50dba09c6a
6 changed files with 129 additions and 46 deletions

View File

@ -43,6 +43,8 @@ namespace Obfuz.ObfusPasses.ConstObfus
protected override bool TryObfuscateInstruction(MethodDef method, Instruction inst, IList<Instruction> instructions, int instructionIndex,
List<Instruction> outputInstructions, List<Instruction> 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;
}
}

View File

@ -40,8 +40,9 @@ namespace Obfuz.ObfusPasses.ConstObfus
return MetadataImporter.Instance.GetDefaultModuleMetadataImporter(method.Module);
}
public void ObfuscateInt(MethodDef method, int value, List<Instruction> obfuscatedInstructions)
public void ObfuscateInt(MethodDef method, bool needCacheValue, int value, List<Instruction> 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<Instruction> obfuscatedInstructions)
public void ObfuscateLong(MethodDef method, bool needCacheValue, long value, List<Instruction> 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<Instruction> obfuscatedInstructions)
public void ObfuscateFloat(MethodDef method, bool needCacheValue, float value, List<Instruction> 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<Instruction> obfuscatedInstructions)
public void ObfuscateDouble(MethodDef method, bool needCacheValue, double value, List<Instruction> 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<Instruction> obfuscatedInstructions)
public void ObfuscateBytes(MethodDef method, bool needCacheValue, byte[] value, List<Instruction> 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<Instruction> obfuscatedInstructions)
public void ObfuscateString(MethodDef method, bool needCacheValue, string value, List<Instruction> obfuscatedInstructions)
{
//int ops = GenerateEncryptionOperations();
//int salt = GenerateSalt();

View File

@ -7,17 +7,17 @@ namespace Obfuz.ObfusPasses.ConstObfus
{
public interface IDataObfuscator
{
void ObfuscateInt(MethodDef method, int value, List<Instruction> obfuscatedInstructions);
void ObfuscateInt(MethodDef method, bool needCacheValue, int value, List<Instruction> obfuscatedInstructions);
void ObfuscateLong(MethodDef method, long value, List<Instruction> obfuscatedInstructions);
void ObfuscateLong(MethodDef method, bool needCacheValue, long value, List<Instruction> obfuscatedInstructions);
void ObfuscateFloat(MethodDef method, float value, List<Instruction> obfuscatedInstructions);
void ObfuscateFloat(MethodDef method, bool needCacheValue, float value, List<Instruction> obfuscatedInstructions);
void ObfuscateDouble(MethodDef method, double value, List<Instruction> obfuscatedInstructions);
void ObfuscateDouble(MethodDef method, bool needCacheValue, double value, List<Instruction> obfuscatedInstructions);
void ObfuscateString(MethodDef method, string value, List<Instruction> obfuscatedInstructions);
void ObfuscateString(MethodDef method, bool needCacheValue, string value, List<Instruction> obfuscatedInstructions);
void ObfuscateBytes(MethodDef method, byte[] value, List<Instruction> obfuscatedInstructions);
void ObfuscateBytes(MethodDef method, bool needCacheValue, byte[] value, List<Instruction> obfuscatedInstructions);
void Done();
}

View File

@ -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);
}
}

View File

@ -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<int> notEncryptInts = new HashSet<int>();
public HashSet<long> notEncryptLongs = new HashSet<long>();
public HashSet<string> notEncryptStrings = new HashSet<string>();
@ -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)

View File

@ -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);
}
}