支持 Bytes混淆
parent
db26f5d3ce
commit
09a6b6f6af
|
@ -38,5 +38,10 @@ namespace Obfuz.Virtualization
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override bool NeedObfuscateArray(MethodDef method, byte[] array)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
using dnlib.DotNet;
|
||||||
|
using dnlib.DotNet.Emit;
|
||||||
|
using Obfuz.Emit;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using static UnityEngine.Networking.UnityWebRequest;
|
||||||
|
using UnityEngine.UIElements;
|
||||||
|
|
||||||
|
namespace Obfuz.Virtualization
|
||||||
|
{
|
||||||
|
[NodeOutput(DataNodeType.Int32)]
|
||||||
|
[NodeOutput(DataNodeType.Int64)]
|
||||||
|
[NodeOutput(DataNodeType.Float32)]
|
||||||
|
[NodeOutput(DataNodeType.Float64)]
|
||||||
|
[NodeOutput(DataNodeType.Bytes)]
|
||||||
|
[NodeOutput(DataNodeType.String)]
|
||||||
|
public class BytesInitializeFromFieldRvaDataNode : DataNodeAny
|
||||||
|
{
|
||||||
|
|
||||||
|
private RvaData AllocateRvaData(CompileContext ctx)
|
||||||
|
{
|
||||||
|
ModuleDef mod = ctx.method.Module;
|
||||||
|
RvaDataAllocator allocator = ctx.rvaDataAllocator;
|
||||||
|
switch (Type)
|
||||||
|
{
|
||||||
|
//case DataNodeType.Int32: return allocator.Allocate(mod, IntValue);
|
||||||
|
//case DataNodeType.Int64: return allocator.Allocate(mod, LongValue);
|
||||||
|
//case DataNodeType.Float32: return allocator.Allocate(mod, FloatValue);
|
||||||
|
//case DataNodeType.Float64: return allocator.Allocate(mod, DoubleValue);
|
||||||
|
case DataNodeType.Bytes: return allocator.Allocate(mod, BytesValue);
|
||||||
|
//case DataNodeType.String: return allocator.Allocate(mod, StringValue);
|
||||||
|
default:
|
||||||
|
throw new NotSupportedException($"Unsupported type: {Type}.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IMethod s_convertBytes;
|
||||||
|
|
||||||
|
private void InitImportMetadatas(ModuleDef mod)
|
||||||
|
{
|
||||||
|
if (s_convertBytes != null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
s_convertBytes = mod.Import(typeof(ConstUtility).GetMethod("InitializeArray", new[] { typeof(Array), typeof(byte[]), typeof(int), typeof(int) }));
|
||||||
|
}
|
||||||
|
|
||||||
|
IMethod GetConvertMethod(ModuleDef mod)
|
||||||
|
{
|
||||||
|
InitImportMetadatas(mod);
|
||||||
|
return s_convertBytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Compile(CompileContext ctx)
|
||||||
|
{
|
||||||
|
// only support Int32, int64, bytes.
|
||||||
|
// string can only create from StringFromBytesNode
|
||||||
|
// x = memcpy array.GetRange(index, length);
|
||||||
|
var output = ctx.output;
|
||||||
|
RvaData rvaData = AllocateRvaData(ctx);
|
||||||
|
ModuleDef mod = ctx.method.Module;
|
||||||
|
IMethod convertMethod = GetConvertMethod(mod);
|
||||||
|
|
||||||
|
ctx.output.Add(Instruction.Create(OpCodes.Ldsfld, rvaData.field));
|
||||||
|
output.Add(Instruction.Create(OpCodes.Ldc_I4, rvaData.offset));
|
||||||
|
output.Add(Instruction.Create(OpCodes.Ldc_I4, rvaData.size));
|
||||||
|
//output.Add(Instruction.Create(OpCodes.Newarr, mod.CorLibTypes.Byte.ToTypeDefOrRef()));
|
||||||
|
//output.Add(Instruction.Create(OpCodes.Ldc_I4, 0));
|
||||||
|
//output.Add(Instruction.Create(OpCodes.Ldc_I4, rvaData.size));
|
||||||
|
output.Add(Instruction.Create(OpCodes.Call, convertMethod));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -59,7 +59,7 @@ namespace Obfuz.Virtualization
|
||||||
s_convertDouble = mod.Import(typeof(BitConverter).GetMethod("ToDouble", new[] { typeof(byte[]), typeof(int) }));
|
s_convertDouble = mod.Import(typeof(BitConverter).GetMethod("ToDouble", new[] { typeof(byte[]), typeof(int) }));
|
||||||
s_convertString = mod.Import(typeof(Encoding).GetMethod("GetString", new[] { typeof(byte[]), typeof(int), typeof(int) }));
|
s_convertString = mod.Import(typeof(Encoding).GetMethod("GetString", new[] { typeof(byte[]), typeof(int), typeof(int) }));
|
||||||
s_Encoding_Utf8 = mod.Import(typeof(Encoding).GetField("UTF8"));
|
s_Encoding_Utf8 = mod.Import(typeof(Encoding).GetField("UTF8"));
|
||||||
s_convertBytes = mod.Import(typeof(Array).GetMethod("Copy", new[] { typeof(Array), typeof(int), typeof(Array), typeof(int), typeof(int) }));
|
s_convertBytes = mod.Import(typeof(ConstUtility).GetMethod("GetBytes", new[] { typeof(byte[]), typeof(int), typeof(int) }));
|
||||||
}
|
}
|
||||||
|
|
||||||
IMethod GetConvertMethod(ModuleDef mod)
|
IMethod GetConvertMethod(ModuleDef mod)
|
||||||
|
@ -116,9 +116,9 @@ namespace Obfuz.Virtualization
|
||||||
ctx.output.Add(Instruction.Create(OpCodes.Ldsfld, rvaData.field));
|
ctx.output.Add(Instruction.Create(OpCodes.Ldsfld, rvaData.field));
|
||||||
output.Add(Instruction.Create(OpCodes.Ldc_I4, rvaData.offset));
|
output.Add(Instruction.Create(OpCodes.Ldc_I4, rvaData.offset));
|
||||||
output.Add(Instruction.Create(OpCodes.Ldc_I4, rvaData.size));
|
output.Add(Instruction.Create(OpCodes.Ldc_I4, rvaData.size));
|
||||||
output.Add(Instruction.Create(OpCodes.Newarr, mod.CorLibTypes.Byte.ToTypeDefOrRef()));
|
//output.Add(Instruction.Create(OpCodes.Newarr, mod.CorLibTypes.Byte.ToTypeDefOrRef()));
|
||||||
output.Add(Instruction.Create(OpCodes.Ldc_I4, 0));
|
//output.Add(Instruction.Create(OpCodes.Ldc_I4, 0));
|
||||||
output.Add(Instruction.Create(OpCodes.Ldc_I4, rvaData.size));
|
//output.Add(Instruction.Create(OpCodes.Ldc_I4, rvaData.size));
|
||||||
output.Add(Instruction.Create(OpCodes.Call, convertMethod));
|
output.Add(Instruction.Create(OpCodes.Call, convertMethod));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,5 +33,10 @@ namespace Obfuz.Virtualization
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual bool NeedObfuscateArray(MethodDef method, byte[] array)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ using System.Linq;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using UnityEngine.Assertions;
|
||||||
|
|
||||||
namespace Obfuz.Virtualization
|
namespace Obfuz.Virtualization
|
||||||
{
|
{
|
||||||
|
@ -138,6 +139,28 @@ namespace Obfuz.Virtualization
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case OperandType.InlineMethod:
|
||||||
|
{
|
||||||
|
if (((IMethod)inst.Operand).FullName == "System.Void System.Runtime.CompilerServices.RuntimeHelpers::InitializeArray(System.Array,System.RuntimeFieldHandle)")
|
||||||
|
{
|
||||||
|
Instruction prevInst = instructions[i - 1];
|
||||||
|
if (prevInst.OpCode.Code == Code.Ldtoken)
|
||||||
|
{
|
||||||
|
IField rvaField = (IField)prevInst.Operand;
|
||||||
|
FieldDef ravFieldDef = rvaField.ResolveFieldDefThrow();
|
||||||
|
byte[] data = ravFieldDef.InitialValue;
|
||||||
|
if (data != null && _dataObfuscatorPolicy.NeedObfuscateArray(method, data))
|
||||||
|
{
|
||||||
|
// remove prev ldtoken instruction
|
||||||
|
Assert.AreEqual(Code.Ldtoken, resultInstructions[resultInstructions.Count - 1].OpCode.Code);
|
||||||
|
resultInstructions.RemoveAt(resultInstructions.Count - 1);
|
||||||
|
_dataObfuscator.ObfuscateBytes(method, data, obfuscatedInstructions);
|
||||||
|
obfuscated = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
resultInstructions.Add(inst);
|
resultInstructions.Add(inst);
|
||||||
if (obfuscated)
|
if (obfuscated)
|
||||||
|
|
|
@ -64,7 +64,9 @@ namespace Obfuz.Virtualization
|
||||||
|
|
||||||
public void ObfuscateBytes(MethodDef method, Array value, List<Instruction> obfuscatedInstructions)
|
public void ObfuscateBytes(MethodDef method, Array value, List<Instruction> obfuscatedInstructions)
|
||||||
{
|
{
|
||||||
throw new NotSupportedException();
|
IDataNode node = _nodeCreator.CreateRandom(DataNodeType.Bytes, value);
|
||||||
|
CompileNode(node, method, obfuscatedInstructions);
|
||||||
|
//throw new NotSupportedException();
|
||||||
//obfuscatedInstructions.Add(Instruction.Create(OpCodes.Ldc_I4, value.Length));
|
//obfuscatedInstructions.Add(Instruction.Create(OpCodes.Ldc_I4, value.Length));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
using dnlib.DotNet.Emit;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Obfuz.Virtualization.Functions
|
||||||
|
{
|
||||||
|
public class BytesInitializeFromFieldRvaDataCreator : NodeCreatorBase
|
||||||
|
{
|
||||||
|
public override IDataNode CreateExpr(DataNodeType type, object value, CreateExpressionOptions options)
|
||||||
|
{
|
||||||
|
return new BytesInitializeFromFieldRvaDataNode { Type = type, Value = value };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,5 +20,7 @@ namespace Obfuz.Virtualization
|
||||||
bool NeedObfuscateDouble(MethodDef method, double value);
|
bool NeedObfuscateDouble(MethodDef method, double value);
|
||||||
|
|
||||||
bool NeedObfuscateString(MethodDef method, string value);
|
bool NeedObfuscateString(MethodDef method, string value);
|
||||||
|
|
||||||
|
bool NeedObfuscateArray(MethodDef method, byte[] array);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,11 @@ namespace Obfuz.Virtualization
|
||||||
new ConstFieldDataCreator(),
|
new ConstFieldDataCreator(),
|
||||||
};
|
};
|
||||||
_functions.Add(DataNodeType.String, stringFuncs);
|
_functions.Add(DataNodeType.String, stringFuncs);
|
||||||
|
var bytesFuncs = new List<IFunction>()
|
||||||
|
{
|
||||||
|
new BytesInitializeFromFieldRvaDataCreator(),
|
||||||
|
};
|
||||||
|
_functions.Add(DataNodeType.Bytes, bytesFuncs);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IDataNode CreateRandom(DataNodeType type, object value, CreateExpressionOptions options)
|
public override IDataNode CreateRandom(DataNodeType type, object value, CreateExpressionOptions options)
|
||||||
|
|
|
@ -41,6 +41,11 @@ namespace Obfuz
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void InitializeArray(Array array, byte[] data, int offset, int length)
|
||||||
|
{
|
||||||
|
Buffer.BlockCopy(data, offset, array, 0, length);
|
||||||
|
}
|
||||||
|
|
||||||
public static int CastFloatAsInt(float value)
|
public static int CastFloatAsInt(float value)
|
||||||
{
|
{
|
||||||
return UnsafeUtility.As<float, int>(ref value);
|
return UnsafeUtility.As<float, int>(ref value);
|
||||||
|
|
Loading…
Reference in New Issue