支持变量加密
parent
6b476c7091
commit
b75b87191d
|
@ -0,0 +1,87 @@
|
||||||
|
using dnlib.DotNet;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using UnityEngine.Assertions;
|
||||||
|
|
||||||
|
namespace Obfuz.Emit
|
||||||
|
{
|
||||||
|
public class ModuleMetadataImporter
|
||||||
|
{
|
||||||
|
private readonly ModuleDef _module;
|
||||||
|
public ModuleMetadataImporter(ModuleDef module)
|
||||||
|
{
|
||||||
|
_module = module;
|
||||||
|
_module = module;
|
||||||
|
InitMetadatas(module);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IMethod s_castIntAsFloat;
|
||||||
|
private static IMethod s_castLongAsDouble;
|
||||||
|
private static IMethod s_castFloatAsInt;
|
||||||
|
private static IMethod s_castDoubleAsLong;
|
||||||
|
|
||||||
|
private void InitMetadatas(ModuleDef mod)
|
||||||
|
{
|
||||||
|
if (s_castFloatAsInt != null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var constUtilityType = typeof(ConstUtility);
|
||||||
|
|
||||||
|
s_castIntAsFloat = mod.Import(constUtilityType.GetMethod("CastIntAsFloat"));
|
||||||
|
Assert.IsNotNull(s_castIntAsFloat, "CastIntAsFloat not found");
|
||||||
|
s_castLongAsDouble = mod.Import(constUtilityType.GetMethod("CastLongAsDouble"));
|
||||||
|
Assert.IsNotNull(s_castLongAsDouble, "CastLongAsDouble not found");
|
||||||
|
s_castFloatAsInt = mod.Import(constUtilityType.GetMethod("CastFloatAsInt"));
|
||||||
|
Assert.IsNotNull(s_castFloatAsInt, "CastFloatAsInt not found");
|
||||||
|
s_castDoubleAsLong = mod.Import(constUtilityType.GetMethod("CastDoubleAsLong"));
|
||||||
|
Assert.IsNotNull(s_castDoubleAsLong, "CastDoubleAsLong not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
public IMethod GetCastIntAsFloat()
|
||||||
|
{
|
||||||
|
return s_castIntAsFloat;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IMethod GetCastLongAsDouble()
|
||||||
|
{
|
||||||
|
return s_castLongAsDouble;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IMethod GetCastFloatAsInt()
|
||||||
|
{
|
||||||
|
return s_castFloatAsInt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IMethod GetCastDoubleAsLong()
|
||||||
|
{
|
||||||
|
return s_castDoubleAsLong;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MetadataImporter
|
||||||
|
{
|
||||||
|
|
||||||
|
private readonly Dictionary<ModuleDef, ModuleMetadataImporter> _moduleMetadataImporters = new Dictionary<ModuleDef, ModuleMetadataImporter>();
|
||||||
|
|
||||||
|
public static MetadataImporter Instance { get; private set; }
|
||||||
|
|
||||||
|
public static void Reset()
|
||||||
|
{
|
||||||
|
Instance = new MetadataImporter();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ModuleMetadataImporter GetModuleMetadataImporter(ModuleDef module)
|
||||||
|
{
|
||||||
|
if (!_moduleMetadataImporters.TryGetValue(module, out var importer))
|
||||||
|
{
|
||||||
|
importer = new ModuleMetadataImporter(module);
|
||||||
|
_moduleMetadataImporters[module] = importer;
|
||||||
|
}
|
||||||
|
return importer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,483 @@
|
||||||
|
using dnlib.DotNet;
|
||||||
|
using dnlib.DotNet.Emit;
|
||||||
|
using Obfuz.Utils;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using UnityEngine.Assertions;
|
||||||
|
|
||||||
|
namespace Obfuz.Emit
|
||||||
|
{
|
||||||
|
public class EncryptionCompileContext
|
||||||
|
{
|
||||||
|
public ModuleDef module;
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IVariableTransformer
|
||||||
|
{
|
||||||
|
object Compute(object value);
|
||||||
|
|
||||||
|
object ReverseCompute(object value);
|
||||||
|
|
||||||
|
void EmitTransform(List<Instruction> output, EncryptionCompileContext ctx);
|
||||||
|
|
||||||
|
void EmitRevertTransform(List<Instruction> output, EncryptionCompileContext ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract class VariableTransformerBase : IVariableTransformer
|
||||||
|
{
|
||||||
|
public abstract object Compute(object value);
|
||||||
|
public abstract object ReverseCompute(object value);
|
||||||
|
public abstract void EmitRevertTransform(List<Instruction> output, EncryptionCompileContext ctx);
|
||||||
|
public abstract void EmitTransform(List<Instruction> output, EncryptionCompileContext ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AddVariableTransformer : VariableTransformerBase
|
||||||
|
{
|
||||||
|
private readonly DataNodeType _type;
|
||||||
|
private readonly object _addValue;
|
||||||
|
|
||||||
|
public AddVariableTransformer(DataNodeType type, object addValue)
|
||||||
|
{
|
||||||
|
_type = type;
|
||||||
|
_addValue = addValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override object Compute(object value)
|
||||||
|
{
|
||||||
|
switch (_type)
|
||||||
|
{
|
||||||
|
case DataNodeType.Int32:
|
||||||
|
return (int)value + (int)_addValue;
|
||||||
|
case DataNodeType.Int64:
|
||||||
|
return (long)value + (long)_addValue;
|
||||||
|
default: throw new NotSupportedException($"Unsupported type: {_type}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override object ReverseCompute(object value)
|
||||||
|
{
|
||||||
|
switch (_type)
|
||||||
|
{
|
||||||
|
case DataNodeType.Int32:
|
||||||
|
return (int)value - (int)_addValue;
|
||||||
|
case DataNodeType.Int64:
|
||||||
|
return (long)value - (long)_addValue;
|
||||||
|
default: throw new NotSupportedException($"Unsupported type: {_type}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void EmitTransform(List<Instruction> output, EncryptionCompileContext ctx)
|
||||||
|
{
|
||||||
|
switch (_type)
|
||||||
|
{
|
||||||
|
case DataNodeType.Int32:
|
||||||
|
output.Add(Instruction.Create(OpCodes.Ldc_I4, (int)_addValue));
|
||||||
|
output.Add(Instruction.Create(OpCodes.Add));
|
||||||
|
break;
|
||||||
|
case DataNodeType.Int64:
|
||||||
|
output.Add(Instruction.Create(OpCodes.Ldc_I8, (long)_addValue));
|
||||||
|
output.Add(Instruction.Create(OpCodes.Add));
|
||||||
|
break;
|
||||||
|
default: throw new NotSupportedException($"Unsupported type: {_type}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void EmitRevertTransform(List<Instruction> output, EncryptionCompileContext ctx)
|
||||||
|
{
|
||||||
|
switch (_type)
|
||||||
|
{
|
||||||
|
case DataNodeType.Int32:
|
||||||
|
output.Add(Instruction.Create(OpCodes.Ldc_I4, -(int)_addValue));
|
||||||
|
output.Add(Instruction.Create(OpCodes.Add));
|
||||||
|
break;
|
||||||
|
case DataNodeType.Int64:
|
||||||
|
output.Add(Instruction.Create(OpCodes.Ldc_I8, -(long)_addValue));
|
||||||
|
output.Add(Instruction.Create(OpCodes.Add));
|
||||||
|
break;
|
||||||
|
default: throw new NotSupportedException($"Unsupported type: {_type}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AddVariableTransformer Create(DataNodeType type, IRandom random)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case DataNodeType.Int32: return new AddVariableTransformer(type, random.NextInt());
|
||||||
|
case DataNodeType.Int64: return new AddVariableTransformer(type, random.NextLong());
|
||||||
|
default:
|
||||||
|
throw new NotSupportedException($"Unsupported type: {type}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class XorVariableTransformer : VariableTransformerBase
|
||||||
|
{
|
||||||
|
private readonly DataNodeType _type;
|
||||||
|
private readonly object _xorValue;
|
||||||
|
public XorVariableTransformer(DataNodeType type, object xorValue)
|
||||||
|
{
|
||||||
|
_type = type;
|
||||||
|
_xorValue = xorValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override object Compute(object value)
|
||||||
|
{
|
||||||
|
switch (_type)
|
||||||
|
{
|
||||||
|
case DataNodeType.Int32:
|
||||||
|
return (int)value ^ (int)_xorValue;
|
||||||
|
case DataNodeType.Int64:
|
||||||
|
return (long)value ^ (long)_xorValue;
|
||||||
|
default: throw new NotSupportedException($"Unsupported type: {_type}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override object ReverseCompute(object value)
|
||||||
|
{
|
||||||
|
switch (_type)
|
||||||
|
{
|
||||||
|
case DataNodeType.Int32:
|
||||||
|
return (int)value ^ (int)_xorValue;
|
||||||
|
case DataNodeType.Int64:
|
||||||
|
return (long)value ^ (long)_xorValue;
|
||||||
|
default: throw new NotSupportedException($"Unsupported type: {_type}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void EmitTransform(List<Instruction> output, EncryptionCompileContext ctx)
|
||||||
|
{
|
||||||
|
switch (_type)
|
||||||
|
{
|
||||||
|
case DataNodeType.Int32:
|
||||||
|
output.Add(Instruction.Create(OpCodes.Ldc_I4, (int)_xorValue));
|
||||||
|
output.Add(Instruction.Create(OpCodes.Xor));
|
||||||
|
break;
|
||||||
|
case DataNodeType.Int64:
|
||||||
|
output.Add(Instruction.Create(OpCodes.Ldc_I8, (long)_xorValue));
|
||||||
|
output.Add(Instruction.Create(OpCodes.Xor));
|
||||||
|
break;
|
||||||
|
default: throw new NotSupportedException($"Unsupported type: {_type}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void EmitRevertTransform(List<Instruction> output, EncryptionCompileContext ctx)
|
||||||
|
{
|
||||||
|
switch (_type)
|
||||||
|
{
|
||||||
|
case DataNodeType.Int32:
|
||||||
|
output.Add(Instruction.Create(OpCodes.Ldc_I4, (int)_xorValue));
|
||||||
|
output.Add(Instruction.Create(OpCodes.Xor));
|
||||||
|
break;
|
||||||
|
case DataNodeType.Int64:
|
||||||
|
output.Add(Instruction.Create(OpCodes.Ldc_I8, (long)_xorValue));
|
||||||
|
output.Add(Instruction.Create(OpCodes.Xor));
|
||||||
|
break;
|
||||||
|
default: throw new NotSupportedException($"Unsupported type: {_type}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static XorVariableTransformer Create(DataNodeType type, IRandom random)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case DataNodeType.Int32: return new XorVariableTransformer(type, random.NextInt());
|
||||||
|
case DataNodeType.Int64: return new XorVariableTransformer(type, random.NextLong());
|
||||||
|
default:
|
||||||
|
throw new NotSupportedException($"Unsupported type: {type}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class CastFloatAsIntTransformer : VariableTransformerBase
|
||||||
|
{
|
||||||
|
private readonly DataNodeType _outputType;
|
||||||
|
|
||||||
|
public CastFloatAsIntTransformer(DataNodeType srcType)
|
||||||
|
{
|
||||||
|
switch (srcType)
|
||||||
|
{
|
||||||
|
case DataNodeType.Float32: _outputType = DataNodeType.Int32; break;
|
||||||
|
case DataNodeType.Float64: _outputType = DataNodeType.Int64; break;
|
||||||
|
default: throw new NotSupportedException($"Unsupported type: {srcType}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override object Compute(object value)
|
||||||
|
{
|
||||||
|
switch (_outputType)
|
||||||
|
{
|
||||||
|
case DataNodeType.Int32:
|
||||||
|
return ConstUtility.CastFloatAsInt((float)value);
|
||||||
|
case DataNodeType.Int64:
|
||||||
|
return ConstUtility.CastDoubleAsLong((double)value);
|
||||||
|
default: throw new NotSupportedException($"Unsupported type: {_outputType}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override object ReverseCompute(object value)
|
||||||
|
{
|
||||||
|
switch (_outputType)
|
||||||
|
{
|
||||||
|
case DataNodeType.Int32:
|
||||||
|
return ConstUtility.CastIntAsFloat((int)value);
|
||||||
|
case DataNodeType.Int64:
|
||||||
|
return ConstUtility.CastLongAsDouble((long)value);
|
||||||
|
default: throw new NotSupportedException($"Unsupported type: {_outputType}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void EmitTransform(List<Instruction> output, EncryptionCompileContext ctx)
|
||||||
|
{
|
||||||
|
switch (_outputType)
|
||||||
|
{
|
||||||
|
case DataNodeType.Int32:
|
||||||
|
output.Add(Instruction.Create(OpCodes.Call, MetadataImporter.Instance.GetModuleMetadataImporter(ctx.module).GetCastFloatAsInt()));
|
||||||
|
break;
|
||||||
|
case DataNodeType.Int64:
|
||||||
|
output.Add(Instruction.Create(OpCodes.Call, MetadataImporter.Instance.GetModuleMetadataImporter(ctx.module).GetCastDoubleAsLong()));
|
||||||
|
break;
|
||||||
|
default: throw new NotSupportedException($"Unsupported type: {_outputType}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void EmitRevertTransform(List<Instruction> output, EncryptionCompileContext ctx)
|
||||||
|
{
|
||||||
|
switch (_outputType)
|
||||||
|
{
|
||||||
|
case DataNodeType.Int32:
|
||||||
|
output.Add(Instruction.Create(OpCodes.Call, MetadataImporter.Instance.GetModuleMetadataImporter(ctx.module).GetCastIntAsFloat()));
|
||||||
|
break;
|
||||||
|
case DataNodeType.Int64:
|
||||||
|
output.Add(Instruction.Create(OpCodes.Call, MetadataImporter.Instance.GetModuleMetadataImporter(ctx.module).GetCastLongAsDouble()));
|
||||||
|
break;
|
||||||
|
default: throw new NotSupportedException($"Unsupported type: {_outputType}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CastFloatAsIntTransformer Create(DataNodeType type)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case DataNodeType.Float32:
|
||||||
|
case DataNodeType.Float64: return new CastFloatAsIntTransformer(type);
|
||||||
|
default:
|
||||||
|
throw new NotSupportedException($"Unsupported type: {type}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class CastIntAsFloatTransformer : VariableTransformerBase
|
||||||
|
{
|
||||||
|
private readonly DataNodeType _outputType;
|
||||||
|
|
||||||
|
public CastIntAsFloatTransformer(DataNodeType srcType)
|
||||||
|
{
|
||||||
|
switch (srcType)
|
||||||
|
{
|
||||||
|
case DataNodeType.Int32: _outputType = DataNodeType.Float32; break;
|
||||||
|
case DataNodeType.Int64: _outputType = DataNodeType.Float64; break;
|
||||||
|
default: throw new NotSupportedException($"Unsupported type: {srcType}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override object Compute(object value)
|
||||||
|
{
|
||||||
|
switch (_outputType)
|
||||||
|
{
|
||||||
|
case DataNodeType.Float32:
|
||||||
|
return ConstUtility.CastIntAsFloat((int)value);
|
||||||
|
case DataNodeType.Float64:
|
||||||
|
return ConstUtility.CastLongAsDouble((long)value);
|
||||||
|
default: throw new NotSupportedException($"Unsupported type: {_outputType}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override object ReverseCompute(object value)
|
||||||
|
{
|
||||||
|
switch (_outputType)
|
||||||
|
{
|
||||||
|
case DataNodeType.Float32:
|
||||||
|
return ConstUtility.CastFloatAsInt((float)value);
|
||||||
|
case DataNodeType.Float64:
|
||||||
|
return ConstUtility.CastDoubleAsLong((double)value);
|
||||||
|
default: throw new NotSupportedException($"Unsupported type: {_outputType}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void EmitTransform(List<Instruction> output, EncryptionCompileContext ctx)
|
||||||
|
{
|
||||||
|
switch (_outputType)
|
||||||
|
{
|
||||||
|
case DataNodeType.Float32:
|
||||||
|
output.Add(Instruction.Create(OpCodes.Call, MetadataImporter.Instance.GetModuleMetadataImporter(ctx.module).GetCastIntAsFloat()));
|
||||||
|
break;
|
||||||
|
case DataNodeType.Float64:
|
||||||
|
output.Add(Instruction.Create(OpCodes.Call, MetadataImporter.Instance.GetModuleMetadataImporter(ctx.module).GetCastLongAsDouble()));
|
||||||
|
break;
|
||||||
|
default: throw new NotSupportedException($"Unsupported type: {_outputType}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void EmitRevertTransform(List<Instruction> output, EncryptionCompileContext ctx)
|
||||||
|
{
|
||||||
|
switch (_outputType)
|
||||||
|
{
|
||||||
|
case DataNodeType.Float32:
|
||||||
|
output.Add(Instruction.Create(OpCodes.Call, MetadataImporter.Instance.GetModuleMetadataImporter(ctx.module).GetCastFloatAsInt()));
|
||||||
|
break;
|
||||||
|
case DataNodeType.Float64:
|
||||||
|
output.Add(Instruction.Create(OpCodes.Call, MetadataImporter.Instance.GetModuleMetadataImporter(ctx.module).GetCastDoubleAsLong()));
|
||||||
|
break;
|
||||||
|
default: throw new NotSupportedException($"Unsupported type: {_outputType}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CastIntAsFloatTransformer Create(DataNodeType type)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case DataNodeType.Int32:
|
||||||
|
case DataNodeType.Int64: return new CastIntAsFloatTransformer(type);
|
||||||
|
default:
|
||||||
|
throw new NotSupportedException($"Unsupported type: {type}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class VariableEncryption
|
||||||
|
{
|
||||||
|
private readonly List<IVariableTransformer> _transformers = new List<IVariableTransformer>();
|
||||||
|
|
||||||
|
private readonly DataNodeType _type;
|
||||||
|
|
||||||
|
public VariableEncryption(DataNodeType type, IRandom random)
|
||||||
|
{
|
||||||
|
_type = type;
|
||||||
|
if (type == DataNodeType.Float32)
|
||||||
|
{
|
||||||
|
_transformers.Add(CastFloatAsIntTransformer.Create(type));
|
||||||
|
_transformers.AddRange(CreateTransformers(DataNodeType.Int32, random));
|
||||||
|
_transformers.Add(CastIntAsFloatTransformer.Create(DataNodeType.Int32));
|
||||||
|
|
||||||
|
Assert.AreEqual(1.0f, (float)ComputeValueAfterRevertTransform(ComputeValueAfterTransform(1.0f, _transformers), _transformers));
|
||||||
|
}
|
||||||
|
else if (type == DataNodeType.Float64)
|
||||||
|
{
|
||||||
|
_transformers.Add(CastFloatAsIntTransformer.Create(type));
|
||||||
|
_transformers.AddRange(CreateTransformers(DataNodeType.Int64, random));
|
||||||
|
_transformers.Add(CastIntAsFloatTransformer.Create(DataNodeType.Int64));
|
||||||
|
Assert.AreEqual(1.0, (double)ComputeValueAfterRevertTransform(ComputeValueAfterTransform(1.0, _transformers), _transformers));
|
||||||
|
}
|
||||||
|
else if (type == DataNodeType.Int32)
|
||||||
|
{
|
||||||
|
_transformers.AddRange(CreateTransformers(type, random));
|
||||||
|
Assert.AreEqual(1, (int)ComputeValueAfterRevertTransform(ComputeValueAfterTransform(1, _transformers), _transformers));
|
||||||
|
}
|
||||||
|
else if (type == DataNodeType.Int64)
|
||||||
|
{
|
||||||
|
_transformers.AddRange(CreateTransformers(type, random));
|
||||||
|
Assert.AreEqual(1L, (long)ComputeValueAfterRevertTransform(ComputeValueAfterTransform(1L, _transformers), _transformers));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new NotSupportedException($"Unsupported type: {type} for VariableEncryption");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<IVariableTransformer> CreateTransformers(DataNodeType type, IRandom random)
|
||||||
|
{
|
||||||
|
var output = new List<IVariableTransformer>();
|
||||||
|
output.Add(XorVariableTransformer.Create(type, random));
|
||||||
|
output.Add(AddVariableTransformer.Create(type, random));
|
||||||
|
output.Add(XorVariableTransformer.Create(type, random));
|
||||||
|
//int count = 3;
|
||||||
|
//for (int i = 0; i < count; i++)
|
||||||
|
//{
|
||||||
|
// switch(random.NextInt(2))
|
||||||
|
// {
|
||||||
|
// case 0:
|
||||||
|
// {
|
||||||
|
// var transformer = AddVariableTransformer.Create(type, random);
|
||||||
|
// output.Add(transformer);
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// case 1:
|
||||||
|
// {
|
||||||
|
// var transformer = XorVariableTransformer.Create(type, random);
|
||||||
|
// output.Add(transformer);
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
AddMapZeroToZeroTransform(type, random, output);
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static object ComputeValueAfterTransform(object value, List<IVariableTransformer> transformers)
|
||||||
|
{
|
||||||
|
foreach (var transformer in transformers)
|
||||||
|
{
|
||||||
|
value = transformer.Compute(value);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static object ComputeValueAfterRevertTransform(object value, List<IVariableTransformer> transformers)
|
||||||
|
{
|
||||||
|
for (int i = transformers.Count - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
var transformer = transformers[i];
|
||||||
|
value = transformer.ReverseCompute(value);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void AddMapZeroToZeroTransform(DataNodeType type, IRandom random, List<IVariableTransformer> output)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case DataNodeType.Int32:
|
||||||
|
{
|
||||||
|
int value = (int)ComputeValueAfterTransform(0, output);
|
||||||
|
if (value != 0)
|
||||||
|
{
|
||||||
|
output.Add(new AddVariableTransformer(type, -value));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DataNodeType.Int64:
|
||||||
|
{
|
||||||
|
long value = (long)ComputeValueAfterTransform(0L, output);
|
||||||
|
if (value != 0)
|
||||||
|
{
|
||||||
|
output.Add(new AddVariableTransformer(type, -value));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
throw new NotSupportedException($"Unsupported type: {type}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void EmitTransform(List<Instruction> output, EncryptionCompileContext ctx)
|
||||||
|
{
|
||||||
|
foreach (var transformer in _transformers)
|
||||||
|
{
|
||||||
|
transformer.EmitTransform(output, ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void EmitRevertTransform(List<Instruction> output, EncryptionCompileContext ctx)
|
||||||
|
{
|
||||||
|
for (int i = _transformers.Count - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
var transformer = _transformers[i];
|
||||||
|
transformer.EmitRevertTransform(output, ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,7 @@
|
||||||
using dnlib.DotNet;
|
using dnlib.DotNet;
|
||||||
using dnlib.DotNet.Emit;
|
using dnlib.DotNet.Emit;
|
||||||
|
using Obfuz.Emit;
|
||||||
|
using Obfuz.Utils;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using UnityEngine.Assertions;
|
using UnityEngine.Assertions;
|
||||||
|
@ -42,44 +44,32 @@ namespace Obfuz.MemEncrypt
|
||||||
Assert.IsNotNull(s_castDoubleAsLong, "CastDoubleAsLong not found");
|
Assert.IsNotNull(s_castDoubleAsLong, "CastDoubleAsLong not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private VariableEncryption CreateEncryption(ElementType type)
|
||||||
|
{
|
||||||
|
IRandom random = new RandomWithKey(new byte[16], 1234);
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case ElementType.I4:
|
||||||
|
return new VariableEncryption(DataNodeType.Int32, random);
|
||||||
|
case ElementType.I8:
|
||||||
|
return new VariableEncryption(DataNodeType.Int64, random);
|
||||||
|
case ElementType.R4:
|
||||||
|
return new VariableEncryption(DataNodeType.Float32, random);
|
||||||
|
case ElementType.R8:
|
||||||
|
return new VariableEncryption(DataNodeType.Float64, random);
|
||||||
|
default: throw new Exception($"Unsupported type {type} for MemoryEncryptor");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void Encrypt(FieldDef field, List<Instruction> outputInstructions, MemoryEncryptionContext ctx)
|
public void Encrypt(FieldDef field, List<Instruction> outputInstructions, MemoryEncryptionContext ctx)
|
||||||
{
|
{
|
||||||
ElementType type = field.FieldType.RemovePinnedAndModifiers().ElementType;
|
|
||||||
if (type == ElementType.R4)
|
|
||||||
{
|
|
||||||
outputInstructions.Add(Instruction.Create(OpCodes.Call, s_castFloatAsInt));
|
|
||||||
type = ElementType.I4;
|
|
||||||
}
|
|
||||||
else if (type == ElementType.R8)
|
|
||||||
{
|
|
||||||
outputInstructions.Add(Instruction.Create(OpCodes.Call, s_castDoubleAsLong));
|
|
||||||
type = ElementType.I8;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type == ElementType.I4)
|
ElementType type = field.FieldType.RemovePinnedAndModifiers().ElementType;
|
||||||
{
|
var encryption = CreateEncryption(type);
|
||||||
outputInstructions.Add(Instruction.CreateLdcI4(100));
|
|
||||||
outputInstructions.Add(Instruction.Create(OpCodes.Add));
|
encryption.EmitTransform(outputInstructions, new EncryptionCompileContext { module = _module });
|
||||||
}
|
|
||||||
else if (type == ElementType.I8)
|
|
||||||
{
|
|
||||||
outputInstructions.Add(Instruction.Create(OpCodes.Ldc_I8, 100L));
|
|
||||||
outputInstructions.Add(Instruction.Create(OpCodes.Add));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new NotSupportedException($"Unsupported type {type} for MemoryEncryptor");
|
|
||||||
}
|
|
||||||
if (type == ElementType.R4)
|
|
||||||
{
|
|
||||||
outputInstructions.Add(Instruction.Create(OpCodes.Call, s_castIntAsFloat));
|
|
||||||
type = ElementType.I4;
|
|
||||||
}
|
|
||||||
else if (type == ElementType.R8)
|
|
||||||
{
|
|
||||||
outputInstructions.Add(Instruction.Create(OpCodes.Call, s_castLongAsDouble));
|
|
||||||
type = ElementType.I8;
|
|
||||||
}
|
|
||||||
outputInstructions.Add(ctx.currentInstruction.Clone());
|
outputInstructions.Add(ctx.currentInstruction.Clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,41 +77,9 @@ namespace Obfuz.MemEncrypt
|
||||||
{
|
{
|
||||||
outputInstructions.Add(ctx.currentInstruction.Clone());
|
outputInstructions.Add(ctx.currentInstruction.Clone());
|
||||||
ElementType type = field.FieldType.RemovePinnedAndModifiers().ElementType;
|
ElementType type = field.FieldType.RemovePinnedAndModifiers().ElementType;
|
||||||
if (type == ElementType.R4)
|
var encryption = CreateEncryption(type);
|
||||||
{
|
|
||||||
outputInstructions.Add(Instruction.Create(OpCodes.Call, s_castFloatAsInt));
|
|
||||||
type = ElementType.I4;
|
|
||||||
}
|
|
||||||
else if (type == ElementType.R8)
|
|
||||||
{
|
|
||||||
outputInstructions.Add(Instruction.Create(OpCodes.Call, s_castDoubleAsLong));
|
|
||||||
type = ElementType.I8;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type == ElementType.I4)
|
encryption.EmitRevertTransform(outputInstructions, new EncryptionCompileContext { module = _module });
|
||||||
{
|
|
||||||
outputInstructions.Add(Instruction.CreateLdcI4(100));
|
|
||||||
outputInstructions.Add(Instruction.Create(OpCodes.Sub));
|
|
||||||
}
|
|
||||||
else if (type == ElementType.I8)
|
|
||||||
{
|
|
||||||
outputInstructions.Add(Instruction.Create(OpCodes.Ldc_I8, 100L));
|
|
||||||
outputInstructions.Add(Instruction.Create(OpCodes.Sub));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new NotSupportedException($"Unsupported type {type} for MemoryEncryptor");
|
|
||||||
}
|
|
||||||
if (type == ElementType.R4)
|
|
||||||
{
|
|
||||||
outputInstructions.Add(Instruction.Create(OpCodes.Call, s_castIntAsFloat));
|
|
||||||
type = ElementType.I4;
|
|
||||||
}
|
|
||||||
else if (type == ElementType.R8)
|
|
||||||
{
|
|
||||||
outputInstructions.Add(Instruction.Create(OpCodes.Call, s_castLongAsDouble));
|
|
||||||
type = ElementType.I8;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,12 +46,13 @@ namespace Obfuz
|
||||||
{
|
{
|
||||||
_options = options;
|
_options = options;
|
||||||
_obfuscationAssemblyNames = options.obfuscationAssemblyNames;
|
_obfuscationAssemblyNames = options.obfuscationAssemblyNames;
|
||||||
|
MetadataImporter.Reset();
|
||||||
_assemblyCache = new AssemblyCache(new PathAssemblyResolver(options.assemblySearchDirs.ToArray()));
|
_assemblyCache = new AssemblyCache(new PathAssemblyResolver(options.assemblySearchDirs.ToArray()));
|
||||||
|
|
||||||
_pipeline.AddPass(new MemoryEncryptionPass());
|
_pipeline.AddPass(new MemoryEncryptionPass());
|
||||||
_pipeline.AddPass(new ProxyCallPass());
|
//_pipeline.AddPass(new ProxyCallPass());
|
||||||
_pipeline.AddPass(new ExprObfuscationPass());
|
//_pipeline.AddPass(new ExprObfuscationPass());
|
||||||
_pipeline.AddPass(new DataVirtualizationPass());
|
//_pipeline.AddPass(new DataVirtualizationPass());
|
||||||
_pipeline.AddPass(new RenameSymbolPass());
|
_pipeline.AddPass(new RenameSymbolPass());
|
||||||
_pipeline.AddPass(new CleanUpInstructionPass());
|
_pipeline.AddPass(new CleanUpInstructionPass());
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue