- 添加 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", "name": "Obfuz",
"rootNamespace": "", "rootNamespace": "",
"references": [ "references": [
"GUID:7e4de3067c2ab5c43a03ac49273dfb68" "GUID:7e4de3067c2ab5c43a03ac49273dfb68",
"GUID:370c0d0004ef2414cb803d3ffd331dce"
], ],
"includePlatforms": [ "includePlatforms": [
"Editor" "Editor"

View File

@ -1,4 +1,7 @@
namespace Obfuz.Virtualization using System;
using UnityEngine.Assertions;
namespace Obfuz.Virtualization
{ {
public struct ConstValue public struct ConstValue
{ {
@ -7,6 +10,16 @@
public ConstValue(DataNodeType type, object value) 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.type = type;
this.value = value; this.value = value;
} }

View File

@ -47,16 +47,16 @@ namespace Obfuz.Virtualization
public void ObfuscateFloat(MethodDef method, float value, List<Instruction> obfuscatedInstructions) public void ObfuscateFloat(MethodDef method, float value, List<Instruction> obfuscatedInstructions)
{ {
//IDataNode node = _nodeCreator.CreateRandom(DataNodeType.Float32, value); IDataNode node = _nodeCreator.CreateRandom(DataNodeType.Float32, value);
//CompileNode(node, method, obfuscatedInstructions); CompileNode(node, method, obfuscatedInstructions);
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Ldc_R4, value)); //obfuscatedInstructions.Add(Instruction.Create(OpCodes.Ldc_R4, value));
} }
public void ObfuscateDouble(MethodDef method, double value, List<Instruction> obfuscatedInstructions) public void ObfuscateDouble(MethodDef method, double value, List<Instruction> obfuscatedInstructions)
{ {
//IDataNode node = _nodeCreator.CreateRandom(DataNodeType.Float64, value); IDataNode node = _nodeCreator.CreateRandom(DataNodeType.Float64, value);
//CompileNode(node, method, obfuscatedInstructions); CompileNode(node, method, obfuscatedInstructions);
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Ldc_R8, value)); //obfuscatedInstructions.Add(Instruction.Create(OpCodes.Ldc_R8, value));
} }
public void ObfuscateBytes(MethodDef method, Array value, List<Instruction> obfuscatedInstructions) 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 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) public virtual void Compile(CompileContext ctx, List<IDataNode> inputs, ConstValue result)
{ {
@ -19,7 +19,7 @@ namespace Obfuz.Virtualization
{ {
input.Compile(ctx); input.Compile(ctx);
} }
CompileSelf(ctx, ctx.output); CompileSelf(ctx, inputs, ctx.output);
} }
public virtual IDataNode CreateExpr(DataNodeType type, object value, CreateExpressionOptions options) 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)); 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)); 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)); 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.Utils;
using Obfuz.Virtualization.DataNodes;
using Obfuz.Virtualization.Functions; using Obfuz.Virtualization.Functions;
using System.Collections.Generic; using System.Collections.Generic;
@ -14,7 +15,7 @@ namespace Obfuz.Virtualization
public RandomDataNodeCreator(IRandom random) public RandomDataNodeCreator(IRandom random)
{ {
_random = random; _random = random;
var int32Funcs = new List<IFunction>() var intFuncs = new List<IFunction>()
{ {
new IntAdd(), new IntAdd(),
new IntXor(), new IntXor(),
@ -22,8 +23,15 @@ namespace Obfuz.Virtualization
//new ConstFromFieldRvaDataCreator(), //new ConstFromFieldRvaDataCreator(),
//new ConstDataCreator(), //new ConstDataCreator(),
}; };
_functions.Add(DataNodeType.Int32, int32Funcs); _functions.Add(DataNodeType.Int32, intFuncs);
_functions.Add(DataNodeType.Int64, int32Funcs); _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) public override IDataNode CreateRandom(DataNodeType type, object value, CreateExpressionOptions options)
@ -41,7 +49,6 @@ namespace Obfuz.Virtualization
new ConstDataNode() { Type = type, Value = value }; new ConstDataNode() { Type = type, Value = value };
} }
var func = funcs[options.random.NextInt(funcs.Count)]; var func = funcs[options.random.NextInt(funcs.Count)];
++options.depth;
return func.CreateExpr(type, value, options); 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
}