支持从rva data中读取常量数据
parent
b19959488f
commit
f1b3bd3329
|
@ -0,0 +1,217 @@
|
||||||
|
using dnlib.DotNet;
|
||||||
|
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 struct RvaData
|
||||||
|
{
|
||||||
|
public readonly FieldDef field;
|
||||||
|
public readonly int offset;
|
||||||
|
public readonly int size;
|
||||||
|
|
||||||
|
public RvaData(FieldDef field, int offset, int size)
|
||||||
|
{
|
||||||
|
this.field = field;
|
||||||
|
this.offset = offset;
|
||||||
|
this.size = size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class RvaDataAllocator
|
||||||
|
{
|
||||||
|
// randomized
|
||||||
|
const int maxRvaDataSize = 0x100;
|
||||||
|
|
||||||
|
private readonly IRandom _random;
|
||||||
|
|
||||||
|
class RvaField
|
||||||
|
{
|
||||||
|
public FieldDef holderDataField;
|
||||||
|
public FieldDef runtimeValueField;
|
||||||
|
public uint size;
|
||||||
|
public List<byte> bytes;
|
||||||
|
|
||||||
|
public void FillPadding()
|
||||||
|
{
|
||||||
|
// fill with random value
|
||||||
|
for (int i = bytes.Count; i < size; i++)
|
||||||
|
{
|
||||||
|
bytes.Add(0xAB);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly List<RvaField> _rvaFields = new List<RvaField>();
|
||||||
|
private RvaField _currentField;
|
||||||
|
|
||||||
|
|
||||||
|
private TypeDef _rvaTypeDef;
|
||||||
|
|
||||||
|
private readonly Dictionary<(ModuleDef, int), TypeDef> _dataHolderTypeBySizes = new Dictionary<(ModuleDef, int), TypeDef>();
|
||||||
|
|
||||||
|
public RvaDataAllocator(IRandom random)
|
||||||
|
{
|
||||||
|
_random = random;
|
||||||
|
}
|
||||||
|
|
||||||
|
private (FieldDef, FieldDef) CreateDataHolderRvaField(ModuleDef mod, TypeDef dataHolderType)
|
||||||
|
{
|
||||||
|
if (_rvaTypeDef == null)
|
||||||
|
{
|
||||||
|
mod.EnableTypeDefFindCache = false;
|
||||||
|
//_rvaTypeDef = mod.Find("$ObfuzRVA$", false);
|
||||||
|
//if (_rvaTypeDef != null)
|
||||||
|
//{
|
||||||
|
// throw new Exception($"can't obfuscate a obfuscated assembly");
|
||||||
|
//}
|
||||||
|
ITypeDefOrRef objectTypeRef = mod.Import(typeof(object));
|
||||||
|
_rvaTypeDef = new TypeDefUser("$Obfuz$RVA$",objectTypeRef);
|
||||||
|
mod.Types.Add(_rvaTypeDef);
|
||||||
|
mod.EnableTypeDefFindCache = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var holderField = new FieldDefUser($"$RVA_Data{_rvaTypeDef.Fields.Count}", new FieldSig(dataHolderType.ToTypeSig()), FieldAttributes.InitOnly | FieldAttributes.Static | FieldAttributes.HasFieldRVA);
|
||||||
|
holderField.DeclaringType = _rvaTypeDef;
|
||||||
|
|
||||||
|
var runtimeValueField = new FieldDefUser($"$RVA_Value{_rvaTypeDef.Fields.Count}", new FieldSig(new SZArraySig(mod.CorLibTypes.Byte)), FieldAttributes.Static);
|
||||||
|
runtimeValueField.DeclaringType = _rvaTypeDef;
|
||||||
|
return (holderField, runtimeValueField);
|
||||||
|
}
|
||||||
|
|
||||||
|
private TypeDef GetDataHolderType(ModuleDef mod, int size)
|
||||||
|
{
|
||||||
|
size = (size + 15) & ~15; // align to 6 bytes
|
||||||
|
if (_dataHolderTypeBySizes.TryGetValue((mod, size), out var type))
|
||||||
|
return type;
|
||||||
|
var dataHolderType = new TypeDefUser($"$ObfuzRVA$DataHolder{size}", mod.Import(typeof(ValueType)));
|
||||||
|
dataHolderType.Layout = TypeAttributes.ExplicitLayout;
|
||||||
|
dataHolderType.PackingSize = 1;
|
||||||
|
dataHolderType.ClassSize = (uint)size;
|
||||||
|
_dataHolderTypeBySizes.Add((mod, size), dataHolderType);
|
||||||
|
mod.Types.Add(dataHolderType);
|
||||||
|
return dataHolderType;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int AlignTo(int size, int alignment)
|
||||||
|
{
|
||||||
|
return (size + alignment - 1) & ~(alignment - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private RvaField CreateRvaField(ModuleDef mod, int size)
|
||||||
|
{
|
||||||
|
TypeDef dataHolderType = GetDataHolderType(mod, size);
|
||||||
|
var (holderDataField, runtimeValueField) = CreateDataHolderRvaField(mod, dataHolderType);
|
||||||
|
var newRvaField = new RvaField
|
||||||
|
{
|
||||||
|
holderDataField = holderDataField,
|
||||||
|
runtimeValueField = runtimeValueField,
|
||||||
|
size = dataHolderType.ClassSize,
|
||||||
|
bytes = new List<byte>((int)dataHolderType.ClassSize),
|
||||||
|
};
|
||||||
|
_rvaFields.Add(newRvaField);
|
||||||
|
return newRvaField;
|
||||||
|
}
|
||||||
|
|
||||||
|
private RvaField GetRvaField(ModuleDef mod, int preservedSize, int alignment)
|
||||||
|
{
|
||||||
|
Assert.IsTrue(preservedSize % alignment == 0);
|
||||||
|
// for big size, create a new field
|
||||||
|
if (preservedSize >= maxRvaDataSize)
|
||||||
|
{
|
||||||
|
return CreateRvaField(mod, preservedSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_currentField != null)
|
||||||
|
{
|
||||||
|
int offset = AlignTo(_currentField.bytes.Count, alignment);
|
||||||
|
|
||||||
|
int expectedSize = offset + preservedSize;
|
||||||
|
if (expectedSize <= _currentField.size)
|
||||||
|
{
|
||||||
|
// insert random padding
|
||||||
|
for (int i = _currentField.bytes.Count; i < offset; i++)
|
||||||
|
{
|
||||||
|
//_currentField.bytes.Add((byte)_random.NextInt(0, 256));
|
||||||
|
// TODO replace with random value
|
||||||
|
_currentField.bytes.Add(0xAB);
|
||||||
|
}
|
||||||
|
return _currentField;
|
||||||
|
}
|
||||||
|
|
||||||
|
_currentField.FillPadding();
|
||||||
|
}
|
||||||
|
_currentField = CreateRvaField(mod, maxRvaDataSize);
|
||||||
|
return _currentField;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RvaData Allocate(ModuleDef mod, int value)
|
||||||
|
{
|
||||||
|
RvaField field = GetRvaField(mod, 4, 4);
|
||||||
|
int offset = field.bytes.Count;
|
||||||
|
Assert.IsTrue(offset % 4 == 0);
|
||||||
|
field.bytes.AddRange(BitConverter.GetBytes(value));
|
||||||
|
return new RvaData(field.runtimeValueField, offset, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RvaData Allocate(ModuleDef mod, long value)
|
||||||
|
{
|
||||||
|
RvaField field = GetRvaField(mod, 8, 8);
|
||||||
|
int offset = field.bytes.Count;
|
||||||
|
Assert.IsTrue(offset % 8 == 0);
|
||||||
|
field.bytes.AddRange(BitConverter.GetBytes(value));
|
||||||
|
return new RvaData(field.runtimeValueField, offset, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RvaData Allocate(ModuleDef mod, float value)
|
||||||
|
{
|
||||||
|
RvaField field = GetRvaField(mod, 4, 4);
|
||||||
|
int offset = field.bytes.Count;
|
||||||
|
Assert.IsTrue(offset % 4 == 0);
|
||||||
|
field.bytes.AddRange(BitConverter.GetBytes(value));
|
||||||
|
return new RvaData(field.runtimeValueField, offset, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RvaData Allocate(ModuleDef mod, double value)
|
||||||
|
{
|
||||||
|
RvaField field = GetRvaField(mod, 8, 8);
|
||||||
|
int offset = field.bytes.Count;
|
||||||
|
Assert.IsTrue(offset % 8 == 0);
|
||||||
|
field.bytes.AddRange(BitConverter.GetBytes(value));
|
||||||
|
return new RvaData(field.runtimeValueField, offset, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RvaData Allocate(ModuleDef mod, string value)
|
||||||
|
{
|
||||||
|
byte[] bytes = Encoding.UTF8.GetBytes(value);
|
||||||
|
return Allocate(mod, bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RvaData Allocate(ModuleDef mod, byte[] value)
|
||||||
|
{
|
||||||
|
RvaField field = GetRvaField(mod, value.Length, 1);
|
||||||
|
int offset = field.bytes.Count;
|
||||||
|
field.bytes.AddRange(value);
|
||||||
|
return new RvaData(field.runtimeValueField, offset, value.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetFieldsRVA()
|
||||||
|
{
|
||||||
|
foreach (var field in _rvaFields)
|
||||||
|
{
|
||||||
|
Assert.IsTrue(field.bytes.Count <= field.size);
|
||||||
|
if (field.bytes.Count < field.size)
|
||||||
|
{
|
||||||
|
field.FillPadding();
|
||||||
|
}
|
||||||
|
field.holderDataField.InitialValue = field.bytes.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,9 @@
|
||||||
{
|
{
|
||||||
"name": "Obfuz",
|
"name": "Obfuz",
|
||||||
"rootNamespace": "",
|
"rootNamespace": "",
|
||||||
"references": [],
|
"references": [
|
||||||
|
"GUID:7e4de3067c2ab5c43a03ac49273dfb68"
|
||||||
|
],
|
||||||
"includePlatforms": [
|
"includePlatforms": [
|
||||||
"Editor"
|
"Editor"
|
||||||
],
|
],
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using dnlib.DotNet;
|
using dnlib.DotNet;
|
||||||
using dnlib.DotNet.Emit;
|
using dnlib.DotNet.Emit;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
using Obfuz.Emit;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Obfuz.Virtualization
|
namespace Obfuz.Virtualization
|
||||||
|
@ -9,5 +10,6 @@ namespace Obfuz.Virtualization
|
||||||
{
|
{
|
||||||
public MethodDef method;
|
public MethodDef method;
|
||||||
public List<Instruction> output;
|
public List<Instruction> output;
|
||||||
|
public RvaDataAllocator rvaDataAllocator;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using Obfuz.Utils;
|
using Obfuz.Emit;
|
||||||
|
using Obfuz.Utils;
|
||||||
|
|
||||||
namespace Obfuz.Virtualization
|
namespace Obfuz.Virtualization
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,130 @@
|
||||||
|
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 ConstFromFieldRvaDataNode : 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_convertInt;
|
||||||
|
private static IMethod s_convertLong;
|
||||||
|
private static IMethod s_convertFloat;
|
||||||
|
private static IMethod s_convertDouble;
|
||||||
|
|
||||||
|
private static IMethod s_convertString;
|
||||||
|
private static IField s_Encoding_Utf8;
|
||||||
|
private static IMethod s_convertBytes;
|
||||||
|
|
||||||
|
private void InitImportMetadatas(ModuleDef mod)
|
||||||
|
{
|
||||||
|
if (s_convertInt != null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
s_convertInt = mod.Import(typeof(BitConverter).GetMethod("ToInt32", new[] { typeof(byte[]), typeof(int) }));
|
||||||
|
s_convertLong = mod.Import(typeof(BitConverter).GetMethod("ToInt64", new[] { typeof(byte[]), typeof(int) }));
|
||||||
|
s_convertFloat = mod.Import(typeof(BitConverter).GetMethod("ToSingle", 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_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) }));
|
||||||
|
}
|
||||||
|
|
||||||
|
IMethod GetConvertMethod(ModuleDef mod)
|
||||||
|
{
|
||||||
|
InitImportMetadatas(mod);
|
||||||
|
switch (Type)
|
||||||
|
{
|
||||||
|
case DataNodeType.Int32: return s_convertInt;
|
||||||
|
case DataNodeType.Int64: return s_convertLong;
|
||||||
|
case DataNodeType.Float32: return s_convertFloat;
|
||||||
|
case DataNodeType.Float64: return s_convertDouble;
|
||||||
|
case DataNodeType.String: return s_convertString;
|
||||||
|
case DataNodeType.Bytes: return s_convertBytes;
|
||||||
|
default: throw new NotSupportedException($"Unsupported type: {Type}.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
switch (Type)
|
||||||
|
{
|
||||||
|
case DataNodeType.Int32:
|
||||||
|
case DataNodeType.Int64:
|
||||||
|
case DataNodeType.Float32:
|
||||||
|
case DataNodeType.Float64:
|
||||||
|
{
|
||||||
|
ctx.output.Add(Instruction.Create(OpCodes.Ldsfld, rvaData.field));
|
||||||
|
output.Add(Instruction.Create(OpCodes.Ldc_I4, rvaData.offset));
|
||||||
|
output.Add(Instruction.Create(OpCodes.Call, convertMethod));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DataNodeType.String:
|
||||||
|
{
|
||||||
|
|
||||||
|
// Encoding.UTF8.GetString(data, offset, length);
|
||||||
|
ctx.output.Add(Instruction.Create(OpCodes.Ldsfld, s_Encoding_Utf8));
|
||||||
|
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.Call, convertMethod));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DataNodeType.Bytes:
|
||||||
|
{
|
||||||
|
// byte[] result = new byte[length];
|
||||||
|
// Array.Copy(data, offset, result, 0, length);
|
||||||
|
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, new SZArraySig(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));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
throw new NotSupportedException($"Unsupported type: {Type}.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,6 @@
|
||||||
namespace Obfuz.Virtualization
|
using dnlib.DotNet;
|
||||||
|
|
||||||
|
namespace Obfuz.Virtualization
|
||||||
{
|
{
|
||||||
public abstract class DataNodeBase : IDataNode
|
public abstract class DataNodeBase : IDataNode
|
||||||
{
|
{
|
||||||
|
@ -18,6 +20,11 @@
|
||||||
|
|
||||||
public byte[] BytesValue => (byte[])Value;
|
public byte[] BytesValue => (byte[])Value;
|
||||||
|
|
||||||
|
public virtual void Init(CreateExpressionOptions options)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public abstract void Compile(CompileContext ctx);
|
public abstract void Compile(CompileContext ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,18 +23,24 @@ namespace Obfuz.Virtualization
|
||||||
|
|
||||||
public override void Stop(ObfuscatorContext ctx)
|
public override void Stop(ObfuscatorContext ctx)
|
||||||
{
|
{
|
||||||
|
_dataObfuscator.Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Process(ObfuscatorContext ctx)
|
public override void Process(ObfuscatorContext ctx)
|
||||||
{
|
{
|
||||||
foreach (var ass in ctx.assemblies)
|
foreach (var ass in ctx.assemblies)
|
||||||
{
|
{
|
||||||
foreach (TypeDef type in ass.module.GetTypes())
|
// ToArray to avoid modify list exception
|
||||||
|
foreach (TypeDef type in ass.module.GetTypes().ToArray())
|
||||||
{
|
{
|
||||||
foreach (MethodDef method in type.Methods)
|
if (type.Name.StartsWith("$Obfuz$"))
|
||||||
{
|
{
|
||||||
if (!method.HasBody || !_dataObfuscatorPolicy.NeedObfuscateMethod(method))
|
continue;
|
||||||
|
}
|
||||||
|
// ToArray to avoid modify list exception
|
||||||
|
foreach (MethodDef method in type.Methods.ToArray())
|
||||||
|
{
|
||||||
|
if (!method.HasBody || method.Name.StartsWith("$Obfuz$") || !_dataObfuscatorPolicy.NeedObfuscateMethod(method))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
@ -7,7 +9,16 @@ namespace Obfuz.Virtualization
|
||||||
{
|
{
|
||||||
public class DefaultDataObfuscator : IDataObfuscator
|
public class DefaultDataObfuscator : IDataObfuscator
|
||||||
{
|
{
|
||||||
private readonly RandomDataNodeCreator _nodeCreator = new RandomDataNodeCreator();
|
private readonly IRandom _random;
|
||||||
|
private readonly RandomDataNodeCreator _nodeCreator;
|
||||||
|
private readonly RvaDataAllocator _rvaDataAllocator;
|
||||||
|
|
||||||
|
public DefaultDataObfuscator()
|
||||||
|
{
|
||||||
|
_random = new RandomWithKey(new byte[] { 0x1, 0x2, 0x3, 0x4 }, 0x5);
|
||||||
|
_nodeCreator = new RandomDataNodeCreator(_random);
|
||||||
|
_rvaDataAllocator = new RvaDataAllocator(_random);
|
||||||
|
}
|
||||||
|
|
||||||
public void ObfuscateInt(MethodDef method, int value, List<Instruction> obfuscatedInstructions)
|
public void ObfuscateInt(MethodDef method, int value, List<Instruction> obfuscatedInstructions)
|
||||||
{
|
{
|
||||||
|
@ -16,6 +27,7 @@ namespace Obfuz.Virtualization
|
||||||
{
|
{
|
||||||
method = method,
|
method = method,
|
||||||
output = obfuscatedInstructions,
|
output = obfuscatedInstructions,
|
||||||
|
rvaDataAllocator = _rvaDataAllocator,
|
||||||
};
|
};
|
||||||
node.Compile(ctx);
|
node.Compile(ctx);
|
||||||
//obfuscatedInstructions.Add(Instruction.Create(OpCodes.Ldc_I4, value));
|
//obfuscatedInstructions.Add(Instruction.Create(OpCodes.Ldc_I4, value));
|
||||||
|
@ -46,5 +58,10 @@ namespace Obfuz.Virtualization
|
||||||
{
|
{
|
||||||
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Ldstr, value));
|
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Ldstr, value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Stop()
|
||||||
|
{
|
||||||
|
_rvaDataAllocator.SetFieldsRVA();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,8 @@ namespace Obfuz.Virtualization
|
||||||
|
|
||||||
object Value { get; }
|
object Value { get; }
|
||||||
|
|
||||||
|
void Init(CreateExpressionOptions options);
|
||||||
|
|
||||||
void Compile(CompileContext ctx);
|
void Compile(CompileContext ctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,5 +19,6 @@ namespace Obfuz.Virtualization
|
||||||
void ObfuscateString(MethodDef method, string value, List<Instruction> obfuscatedInstructions);
|
void ObfuscateString(MethodDef method, string value, List<Instruction> obfuscatedInstructions);
|
||||||
|
|
||||||
void ObfuscateBytes(MethodDef method, Array value, List<Instruction> obfuscatedInstructions);
|
void ObfuscateBytes(MethodDef method, Array value, List<Instruction> obfuscatedInstructions);
|
||||||
|
void Stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,10 +9,11 @@ namespace Obfuz.Virtualization
|
||||||
{
|
{
|
||||||
private readonly Dictionary<DataNodeType, List<IFunction>> _functions = new Dictionary<DataNodeType, List<IFunction>>();
|
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);
|
private readonly IRandom _random;
|
||||||
|
|
||||||
public RandomDataNodeCreator()
|
public RandomDataNodeCreator(IRandom random)
|
||||||
{
|
{
|
||||||
|
_random = random;
|
||||||
var int32Funcs = new List<IFunction>()
|
var int32Funcs = new List<IFunction>()
|
||||||
{
|
{
|
||||||
new Int32FunctionAdd(),
|
new Int32FunctionAdd(),
|
||||||
|
@ -29,7 +30,8 @@ namespace Obfuz.Virtualization
|
||||||
}
|
}
|
||||||
if (options.depth >= 2)
|
if (options.depth >= 2)
|
||||||
{
|
{
|
||||||
return new ConstDataNode() { Type = type, Value = value };
|
//return new ConstDataNode() { Type = type, Value = value };
|
||||||
|
return new ConstFromFieldRvaDataNode() { Type = type, Value = value };
|
||||||
}
|
}
|
||||||
var func = funcs[options.random.NextInt(funcs.Count)];
|
var func = funcs[options.random.NextInt(funcs.Count)];
|
||||||
++options.depth;
|
++options.depth;
|
||||||
|
|
Loading…
Reference in New Issue