添加int相关混淆算法
parent
35df6e520d
commit
e10a42f8dd
|
@ -1,9 +1,11 @@
|
|||
namespace Obfuz.Virtualization
|
||||
namespace Obfuz.Utils
|
||||
{
|
||||
public interface IRandom
|
||||
{
|
||||
int NextInt(int min, int max);
|
||||
|
||||
int NextInt(int max);
|
||||
|
||||
int NextInt();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
using Obfuz.Virtualization;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Obfuz.Utils
|
||||
{
|
||||
public class RandomWithKey : IRandom
|
||||
{
|
||||
private readonly byte[] _key;
|
||||
|
||||
private readonly Random _random;
|
||||
|
||||
private int _nextIndex;
|
||||
|
||||
public RandomWithKey(byte[] key, int seed)
|
||||
{
|
||||
_key = key;
|
||||
// TODO use key and seed to generate a random number
|
||||
_random = new Random(GenerateSeed(key, seed));
|
||||
}
|
||||
|
||||
private int GenerateSeed(byte[] key, int seed)
|
||||
{
|
||||
foreach (var b in key)
|
||||
{
|
||||
seed = seed * 31 + b;
|
||||
}
|
||||
return seed;
|
||||
}
|
||||
|
||||
public int NextInt(int min, int max)
|
||||
{
|
||||
return min + NextInt(max - min);
|
||||
}
|
||||
|
||||
public int NextInt(int max)
|
||||
{
|
||||
return (int)((uint)NextInt() % (uint)max);
|
||||
}
|
||||
|
||||
private int GetNextKeyByte()
|
||||
{
|
||||
if (_nextIndex >= _key.Length)
|
||||
{
|
||||
_nextIndex = 0;
|
||||
}
|
||||
return _key[_nextIndex++];
|
||||
}
|
||||
|
||||
public int NextInt()
|
||||
{
|
||||
return _random.Next() ^ GetNextKeyByte();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using dnlib.DotNet;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
@ -8,5 +9,34 @@ namespace Obfuz.Virtualization
|
|||
{
|
||||
public class ConfigDataObfuscationPolicy : DataObfuscationPolicyBase
|
||||
{
|
||||
public override bool NeedObfuscateMethod(MethodDef method)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool NeedObfuscateInt(MethodDef method, int value)
|
||||
{
|
||||
return value > 10000;
|
||||
}
|
||||
|
||||
public override bool NeedObfuscateLong(MethodDef method, long value)
|
||||
{
|
||||
return value > 10000;
|
||||
}
|
||||
|
||||
public override bool NeedObfuscateFloat(MethodDef method, float value)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool NeedObfuscateDouble(MethodDef method, double value)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool NeedObfuscateString(MethodDef method, string value)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
namespace Obfuz.Virtualization
|
||||
using Obfuz.Utils;
|
||||
|
||||
namespace Obfuz.Virtualization
|
||||
{
|
||||
public struct CreateExpressionOptions
|
||||
{
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
namespace Obfuz.Virtualization
|
||||
{
|
||||
public abstract class DataNodeCreatorBase : IDataNodeCreator
|
||||
{
|
||||
public abstract IDataNode CreateRandom(DataNodeType type, object value, CreateExpressionOptions options);
|
||||
}
|
||||
}
|
|
@ -2,11 +2,9 @@
|
|||
{
|
||||
public abstract class DataNodeBase : IDataNode
|
||||
{
|
||||
public DataNodeType Type { get; protected set; }
|
||||
public DataNodeType Type { get; set; }
|
||||
|
||||
public IDataNode Expr { get; protected set; }
|
||||
|
||||
public abstract object Value { get; protected set; }
|
||||
public abstract object Value { get; set; }
|
||||
|
||||
public abstract void Compile(CompileContext ctx);
|
||||
}
|
||||
|
@ -14,12 +12,12 @@
|
|||
|
||||
public abstract class DataNodeBase<T> : DataNodeBase
|
||||
{
|
||||
public T Value2 { get; protected set; }
|
||||
public T Value2 { get; set; }
|
||||
|
||||
public override object Value
|
||||
{
|
||||
get => Value2;
|
||||
protected set => Value2 = (T)value;
|
||||
set => Value2 = (T)value;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -31,7 +29,7 @@
|
|||
public override object Value
|
||||
{
|
||||
get => _value;
|
||||
protected set => _value = value;
|
||||
set => _value = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ namespace Obfuz.Virtualization
|
|||
{
|
||||
foreach (MethodDef method in type.Methods)
|
||||
{
|
||||
if (!method.HasBody && !_dataObfuscatorPolicy.NeedObfuscateMethod(method))
|
||||
if (!method.HasBody || !_dataObfuscatorPolicy.NeedObfuscateMethod(method))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ namespace Obfuz.Virtualization
|
|||
IList<Instruction> instructions = method.Body.Instructions;
|
||||
var obfuscatedInstructions = new List<Instruction>();
|
||||
var resultInstructions = new List<Instruction>();
|
||||
for (int i = 0; i < instructions.Count; )
|
||||
for (int i = 0; i < instructions.Count; i++)
|
||||
{
|
||||
Instruction inst = instructions[i];
|
||||
bool obfuscated = false;
|
||||
|
@ -130,10 +130,8 @@ namespace Obfuz.Virtualization
|
|||
}
|
||||
break;
|
||||
}
|
||||
default: throw new NotSupportedException($"Unsupported operand type: {inst.OpCode.OperandType} for instruction: {inst}");
|
||||
}
|
||||
resultInstructions.Add(inst);
|
||||
i++;
|
||||
if (obfuscated)
|
||||
{
|
||||
// current instruction may be the target of control flow instruction, so we can't remove it directly.
|
||||
|
@ -141,9 +139,14 @@ namespace Obfuz.Virtualization
|
|||
inst.OpCode = OpCodes.Nop;
|
||||
inst.Operand = null;
|
||||
resultInstructions.AddRange(obfuscatedInstructions);
|
||||
i += obfuscatedInstructions.Count + 1;
|
||||
}
|
||||
}
|
||||
|
||||
instructions.Clear();
|
||||
foreach (var obInst in obfuscatedInstructions)
|
||||
{
|
||||
instructions.Add(obInst);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,34 +7,38 @@ namespace Obfuz.Virtualization
|
|||
{
|
||||
public class DefaultDataObfuscator : IDataObfuscator
|
||||
{
|
||||
public bool ObfuscateInt(MethodDef method, int value, List<Instruction> obfuscatedInstructions)
|
||||
private readonly RandomDataNodeCreator _nodeCreator = new RandomDataNodeCreator();
|
||||
|
||||
public void ObfuscateInt(MethodDef method, int value, List<Instruction> obfuscatedInstructions)
|
||||
{
|
||||
return false;
|
||||
IDataNode node = _nodeCreator.CreateRandom(DataNodeType.Int32, value);
|
||||
obfuscatedInstructions.Add(Instruction.CreateLdcI4(value));
|
||||
}
|
||||
|
||||
public bool TryObfuscateLong(MethodDef method, long value, List<Instruction> obfuscatedInstructions)
|
||||
public void ObfuscateLong(MethodDef method, long value, List<Instruction> obfuscatedInstructions)
|
||||
{
|
||||
return false;
|
||||
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Ldc_I8, value));
|
||||
}
|
||||
|
||||
public bool TryObfuscateFloat(MethodDef method, float value, List<Instruction> obfuscatedInstructions)
|
||||
public void ObfuscateFloat(MethodDef method, float value, List<Instruction> obfuscatedInstructions)
|
||||
{
|
||||
return false;
|
||||
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Ldc_R4, value));
|
||||
}
|
||||
|
||||
public bool TryObfuscateDouble(MethodDef method, double value, List<Instruction> obfuscatedInstructions)
|
||||
public void ObfuscateDouble(MethodDef method, double value, List<Instruction> obfuscatedInstructions)
|
||||
{
|
||||
return false;
|
||||
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Ldc_R8, value));
|
||||
}
|
||||
|
||||
public bool TryObfuscateBytes(MethodDef method, Array value, List<Instruction> obfuscatedInstructions)
|
||||
public void ObfuscateBytes(MethodDef method, Array value, List<Instruction> obfuscatedInstructions)
|
||||
{
|
||||
return false;
|
||||
throw new NotSupportedException();
|
||||
//obfuscatedInstructions.Add(Instruction.Create(OpCodes.Ldc_I4, value.Length));
|
||||
}
|
||||
|
||||
public bool TryObfuscateString(MethodDef method, string value, List<Instruction> obfuscatedInstructions)
|
||||
public void ObfuscateString(MethodDef method, string value, List<Instruction> obfuscatedInstructions)
|
||||
{
|
||||
return false;
|
||||
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Ldstr, value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,10 +11,10 @@ namespace Obfuz.Virtualization
|
|||
|
||||
public abstract void CreateArguments(DataNodeType type, object value, CreateExpressionOptions options, List<ConstValue> args);
|
||||
|
||||
public ConstExpression CreateCallable(IDataNode result, CreateExpressionOptions options)
|
||||
public ConstExpression CreateCallable(DataNodeType type, object value, CreateExpressionOptions options)
|
||||
{
|
||||
var args = new List<ConstValue>();
|
||||
CreateArguments(result.Type, result.Value, options, args);
|
||||
CreateArguments(type, value, options, args);
|
||||
|
||||
options.depth += 1;
|
||||
var argNodes = new List<IDataNode>();
|
||||
|
@ -24,7 +24,7 @@ namespace Obfuz.Virtualization
|
|||
argNodes.Add(argNode);
|
||||
}
|
||||
|
||||
return new ConstExpression(this, args.Select(a => options.expressionCreator.CreateRandom(a.type, a.value, options)).ToList(), new ConstValue(result.Type, result.Value));
|
||||
return new ConstExpression(this, args.Select(a => options.expressionCreator.CreateRandom(a.type, a.value, options)).ToList(), new ConstValue(type, value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ namespace Obfuz.Virtualization.Functions
|
|||
{
|
||||
int value = (int)v;
|
||||
|
||||
int op1 = value >= 0 ? options.random.NextInt(value) : -options.random.NextInt(-value);
|
||||
int op1 = options.random.NextInt();
|
||||
int op2 = value - op1;
|
||||
args.Add(new ConstValue(DataNodeType.Int32, op1));
|
||||
args.Add(new ConstValue(DataNodeType.Int32, op2));
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using static UnityEngine.Networking.UnityWebRequest;
|
||||
|
||||
namespace Obfuz.Virtualization.Functions
|
||||
{
|
||||
public class Int32FunctionXor : Int32FunctionBase
|
||||
{
|
||||
public override DataNodeType ReturnType => DataNodeType.Int32;
|
||||
|
||||
public override void CreateArguments(DataNodeType type, object v, CreateExpressionOptions options, List<ConstValue> args)
|
||||
{
|
||||
int value = (int)v;
|
||||
|
||||
int op1 = options.random.NextInt();
|
||||
int op2 = value ^ op1;
|
||||
args.Add(new ConstValue(DataNodeType.Int32, op1));
|
||||
args.Add(new ConstValue(DataNodeType.Int32, op2));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -13,8 +13,6 @@ namespace Obfuz.Virtualization
|
|||
|
||||
object Value { get; }
|
||||
|
||||
IDataNode Expr { get; }
|
||||
|
||||
void Compile(CompileContext ctx);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,6 @@
|
|||
{
|
||||
DataNodeType ReturnType { get; }
|
||||
|
||||
ConstExpression CreateCallable(IDataNode result, CreateExpressionOptions options);
|
||||
ConstExpression CreateCallable(DataNodeType type, object value, CreateExpressionOptions options);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
|
||||
using Obfuz.Utils;
|
||||
using Obfuz.Virtualization.Functions;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Obfuz.Virtualization
|
||||
{
|
||||
public class RandomDataNodeCreator : DataNodeCreatorBase
|
||||
{
|
||||
private readonly Dictionary<DataNodeType, List<IFunction>> _functions = new Dictionary<DataNodeType, List<IFunction>>();
|
||||
|
||||
private readonly IRandom _random = new RandomWithKey(new byte[] { 0x1, 0x2, 0x3, 0x4 }, 0x5);
|
||||
|
||||
public RandomDataNodeCreator()
|
||||
{
|
||||
var int32Funcs = new List<IFunction>()
|
||||
{
|
||||
new Int32FunctionAdd(),
|
||||
new Int32FunctionXor(),
|
||||
};
|
||||
_functions.Add(DataNodeType.Int32, int32Funcs);
|
||||
}
|
||||
|
||||
public override IDataNode CreateRandom(DataNodeType type, object value, CreateExpressionOptions options)
|
||||
{
|
||||
if (!_functions.TryGetValue(type, out var funcs))
|
||||
{
|
||||
throw new System.Exception($"No functions available for type {type}");
|
||||
}
|
||||
if (options.depth >= 2)
|
||||
{
|
||||
return new ConstDataNode() { Type = type, Value = value };
|
||||
}
|
||||
var func = funcs[options.random.NextInt(funcs.Count)];
|
||||
++options.depth;
|
||||
return func.CreateCallable(type, value, options);
|
||||
}
|
||||
|
||||
public IDataNode CreateRandom(DataNodeType type, object value)
|
||||
{
|
||||
var options = new CreateExpressionOptions
|
||||
{
|
||||
depth = 0,
|
||||
random = _random,
|
||||
expressionCreator = this,
|
||||
};
|
||||
return CreateRandom(type, value, options);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue