- 添加 Obfuz.Runtime

- 添加float和double混淆
backup
walon 2025-04-23 11:55:42 +08:00
parent 49520abcae
commit f3762f05ce
11 changed files with 192 additions and 17 deletions

View File

@ -2,7 +2,8 @@
"name": "Obfuz",
"rootNamespace": "",
"references": [
"GUID:7e4de3067c2ab5c43a03ac49273dfb68"
"GUID:7e4de3067c2ab5c43a03ac49273dfb68",
"GUID:370c0d0004ef2414cb803d3ffd331dce"
],
"includePlatforms": [
"Editor"

View File

@ -1,4 +1,7 @@
namespace Obfuz.Virtualization
using System;
using UnityEngine.Assertions;
namespace Obfuz.Virtualization
{
public struct ConstValue
{
@ -7,6 +10,16 @@
public ConstValue(DataNodeType type, object value)
{
switch (type)
{
case DataNodeType.Int32: Assert.IsTrue(value is int); break;
case DataNodeType.Int64: Assert.IsTrue(value is long); break;
case DataNodeType.Float32: Assert.IsTrue(value is float); break;
case DataNodeType.Float64: Assert.IsTrue(value is double); break;
case DataNodeType.String: Assert.IsTrue(value is string); break;
case DataNodeType.Bytes: Assert.IsTrue(value is byte[]); break;
default: throw new NotSupportedException($"Unsupported type {type} for ConstValue");
}
this.type = type;
this.value = value;
}

View File

@ -47,16 +47,16 @@ namespace Obfuz.Virtualization
public void ObfuscateFloat(MethodDef method, float value, List<Instruction> obfuscatedInstructions)
{
//IDataNode node = _nodeCreator.CreateRandom(DataNodeType.Float32, value);
//CompileNode(node, method, obfuscatedInstructions);
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Ldc_R4, value));
IDataNode node = _nodeCreator.CreateRandom(DataNodeType.Float32, value);
CompileNode(node, method, obfuscatedInstructions);
//obfuscatedInstructions.Add(Instruction.Create(OpCodes.Ldc_R4, value));
}
public void ObfuscateDouble(MethodDef method, double value, List<Instruction> obfuscatedInstructions)
{
//IDataNode node = _nodeCreator.CreateRandom(DataNodeType.Float64, value);
//CompileNode(node, method, obfuscatedInstructions);
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Ldc_R8, value));
IDataNode node = _nodeCreator.CreateRandom(DataNodeType.Float64, value);
CompileNode(node, method, obfuscatedInstructions);
//obfuscatedInstructions.Add(Instruction.Create(OpCodes.Ldc_R8, value));
}
public void ObfuscateBytes(MethodDef method, Array value, List<Instruction> obfuscatedInstructions)

View File

@ -11,7 +11,7 @@ namespace Obfuz.Virtualization
public abstract void CreateArguments(DataNodeType type, object value, CreateExpressionOptions options, List<ConstValue> args);
public abstract void CompileSelf(CompileContext ctx, List<Instruction> output);
public abstract void CompileSelf(CompileContext ctx, List<IDataNode> inputs, List<Instruction> output);
public virtual void Compile(CompileContext ctx, List<IDataNode> inputs, ConstValue result)
{
@ -19,7 +19,7 @@ namespace Obfuz.Virtualization
{
input.Compile(ctx);
}
CompileSelf(ctx, ctx.output);
CompileSelf(ctx, inputs, ctx.output);
}
public virtual IDataNode CreateExpr(DataNodeType type, object value, CreateExpressionOptions options)

View File

@ -42,7 +42,7 @@ namespace Obfuz.Virtualization.Functions
}
}
public override void CompileSelf(CompileContext ctx, List<Instruction> output)
public override void CompileSelf(CompileContext ctx, List<IDataNode> inputs, List<Instruction> output)
{
output.Add(Instruction.Create(OpCodes.Add));
}

View File

@ -53,7 +53,7 @@ namespace Obfuz.Virtualization.Functions
}
}
public override void CompileSelf(CompileContext ctx, List<Instruction> output)
public override void CompileSelf(CompileContext ctx, List<IDataNode> inputs, List<Instruction> output)
{
output.Add(Instruction.Create(OpCodes.Xor));
}

View File

@ -38,7 +38,7 @@ namespace Obfuz.Virtualization.Functions
}
}
public override void CompileSelf(CompileContext ctx, List<Instruction> output)
public override void CompileSelf(CompileContext ctx, List<IDataNode> inputs, List<Instruction> output)
{
output.Add(Instruction.Create(OpCodes.Xor));
}

View File

@ -0,0 +1,76 @@
using dnlib.DotNet;
using dnlib.DotNet.Emit;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Unity.Collections.LowLevel.Unsafe;
using UnityEngine.Assertions;
namespace Obfuz.Virtualization.DataNodes
{
public class MemoryCastIntAsFloat : FunctionBase
{
private static IMethod s_castIntAsFloat;
private static IMethod s_castLongAsDouble;
private void InitMetadatas(ModuleDef mod)
{
if (s_castIntAsFloat != 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");
}
public override void CompileSelf(CompileContext ctx, List<IDataNode> inputs, List<Instruction> output)
{
Assert.AreEqual(1, inputs.Count);
InitMetadatas(ctx.method.Module);
switch (inputs[0].Type)
{
case DataNodeType.Int32:
{
output.Add(Instruction.Create(OpCodes.Call, s_castIntAsFloat));
break;
}
case DataNodeType.Int64:
{
output.Add(Instruction.Create(OpCodes.Call, s_castLongAsDouble));
break;
}
default: throw new NotSupportedException($"Unsupported type {inputs[0].Type} for MemoryCastIntAsFloat");
}
}
public override void CreateArguments(DataNodeType type, object v, CreateExpressionOptions options, List<ConstValue> args)
{
switch (type)
{
case DataNodeType.Float32:
{
float value = (float)v;
int intValue = ConstUtility.CastFloatAsInt(value);
args.Add(new ConstValue(DataNodeType.Int32, intValue));
break;
}
case DataNodeType.Float64:
{
double value = (double)v;
long longValue = ConstUtility.CastDoubleAsLong(value);
args.Add(new ConstValue(DataNodeType.Int64, longValue));
break;
}
default:
{
throw new NotImplementedException($"Type:{type} not implemented");
}
}
}
}
}

View File

@ -1,5 +1,6 @@

using Obfuz.Utils;
using Obfuz.Virtualization.DataNodes;
using Obfuz.Virtualization.Functions;
using System.Collections.Generic;
@ -14,7 +15,7 @@ namespace Obfuz.Virtualization
public RandomDataNodeCreator(IRandom random)
{
_random = random;
var int32Funcs = new List<IFunction>()
var intFuncs = new List<IFunction>()
{
new IntAdd(),
new IntXor(),
@ -22,8 +23,15 @@ namespace Obfuz.Virtualization
//new ConstFromFieldRvaDataCreator(),
//new ConstDataCreator(),
};
_functions.Add(DataNodeType.Int32, int32Funcs);
_functions.Add(DataNodeType.Int64, int32Funcs);
_functions.Add(DataNodeType.Int32, intFuncs);
_functions.Add(DataNodeType.Int64, intFuncs);
var floatFuncs = new List<IFunction>()
{
new MemoryCastIntAsFloat(),
};
_functions.Add(DataNodeType.Float32, floatFuncs);
_functions.Add(DataNodeType.Float64, floatFuncs);
}
public override IDataNode CreateRandom(DataNodeType type, object value, CreateExpressionOptions options)
@ -41,7 +49,6 @@ namespace Obfuz.Virtualization
new ConstDataNode() { Type = type, Value = value };
}
var func = funcs[options.random.NextInt(funcs.Count)];
++options.depth;
return func.CreateExpr(type, value, options);
}

64
Runtime/ConstUtility.cs Normal file
View File

@ -0,0 +1,64 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using Unity.Collections.LowLevel.Unsafe;
using UnityEngine;
namespace Obfuz
{
public static class ConstUtility
{
public static int GetInt(byte[] data, int offset)
{
return BitConverter.ToInt32(data, offset);
}
public static long GetLong(byte[] data, int offset)
{
return BitConverter.ToInt64(data, offset);
}
public static float GetFloat(byte[] data, int offset)
{
return BitConverter.ToSingle(data, offset);
}
public static double GetDouble(byte[] data, int offset)
{
return BitConverter.ToDouble(data, offset);
}
public static string GetString(byte[] data, int offset, int length)
{
return Encoding.UTF8.GetString(data, offset, length);
}
public static byte[] GetBytes(byte[] data, int offset, int length)
{
byte[] result = new byte[length];
Array.Copy(data, offset, result, 0, length);
return result;
}
public static int CastFloatAsInt(float value)
{
return UnsafeUtility.As<float, int>(ref value);
}
public static float CastIntAsFloat(int value)
{
return UnsafeUtility.As<int, float>(ref value);
}
public static long CastDoubleAsLong(double value)
{
return UnsafeUtility.As<double, long>(ref value);
}
public static double CastLongAsDouble(long value)
{
return UnsafeUtility.As<long, double>(ref value);
}
}
}

View File

@ -0,0 +1,14 @@
{
"name": "Obfuz.Runtime",
"rootNamespace": "",
"references": [],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": true,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}