部分完成 ProxyCall

backup
walon 2025-04-28 11:37:48 +08:00
parent b604810171
commit f513b9f414
21 changed files with 636 additions and 95 deletions

View File

@ -1,14 +0,0 @@
using dnlib.DotNet.Emit;
using dnlib.DotNet;
using System.Collections.Generic;
namespace Obfuz.DynamicProxy
{
public class DefaultDynamicProxyObfuscator : DynamicProxyObfuscatorBase
{
public override void Obfuscate(MethodDef callingMethod, IMethod calledMethod, bool callVir, List<Instruction> obfuscatedInstructions)
{
// Default implementation does nothing
}
}
}

View File

@ -1,69 +0,0 @@
using dnlib.DotNet;
using Obfuz.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Obfuz.Emit
{
public struct DynamicProxyMethodData
{
public MethodDef proxyMethod;
public int methodId;
}
class ModuleDynamicProxyMethodAllocator
{
private readonly ModuleDef _module;
private readonly IRandom _random;
public ModuleDynamicProxyMethodAllocator(ModuleDef module, IRandom random)
{
_module = module;
_random = random;
}
public DynamicProxyMethodData Allocate(IMethod method)
{
return default;
}
public void Done()
{
}
}
public class DynamicProxyMethodAllocator
{
private readonly IRandom _random;
private readonly Dictionary<ModuleDef, ModuleDynamicProxyMethodAllocator> _moduleAllocators = new Dictionary<ModuleDef, ModuleDynamicProxyMethodAllocator>();
public DynamicProxyMethodAllocator(IRandom random)
{
_random = random;
}
public DynamicProxyMethodData Allocate(ModuleDef mod, IMethod method)
{
if (!_moduleAllocators.TryGetValue(mod, out var allocator))
{
allocator = new ModuleDynamicProxyMethodAllocator(mod, _random);
_moduleAllocators.Add(mod, allocator);
}
return allocator.Allocate(method);
}
public void Done()
{
foreach (var allocator in _moduleAllocators.Values)
{
allocator.Done();
}
_moduleAllocators.Clear();
}
}
}

View File

@ -0,0 +1,192 @@
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 MethodImplAttributes = dnlib.DotNet.MethodImplAttributes;
using TypeAttributes = dnlib.DotNet.TypeAttributes;
namespace Obfuz.Emit
{
public struct ProxyCallMethodData
{
public MethodDef proxyMethod;
public int secret;
}
class ModuleDynamicProxyMethodAllocator
{
private readonly ModuleDef _module;
private readonly IRandom _random;
class MethodKey : IEquatable<MethodKey>
{
public readonly IMethod _method;
public readonly bool _callVir;
private readonly int _hashCode;
public MethodKey(IMethod method, bool callVir)
{
_method = method;
_callVir = callVir;
_hashCode = HashUtil.CombineHash(MethodEqualityComparer.CompareDeclaringTypes.GetHashCode(method), callVir ? 1 : 0);
}
public override int GetHashCode()
{
return _hashCode;
}
public bool Equals(MethodKey other)
{
return MethodEqualityComparer.CompareDeclaringTypes.Equals(_method, other._method) && _callVir == other._callVir;
}
}
class MethodProxyInfo
{
public MethodDef proxyMethod;
public int secret;
}
private readonly Dictionary<MethodKey, MethodProxyInfo> _methodProxys = new Dictionary<MethodKey, MethodProxyInfo>();
const int maxProxyMethodPerDispatchMethod = 1000;
class DispatchMethodInfo
{
public MethodDef methodDef;
public int secret;
public List<IMethod> methods = new List<IMethod>();
}
private readonly Dictionary<MethodSig, List<DispatchMethodInfo>> _dispatchMethods = new Dictionary<MethodSig, List<DispatchMethodInfo>>(SignatureEqualityComparer.Instance);
private TypeDef _proxyTypeDef;
public ModuleDynamicProxyMethodAllocator(ModuleDef module, IRandom random)
{
_module = module;
_random = random;
}
private TypeDef CreateProxyTypeDef()
{
var typeDef = new TypeDefUser("$Obfuz$ProxyCall", _module.CorLibTypes.Object.ToTypeDefOrRef());
typeDef.Attributes = TypeAttributes.NotPublic | TypeAttributes.Sealed;
_module.EnableTypeDefFindCache = false;
_module.Types.Add(typeDef);
_module.EnableTypeDefFindCache = true;
return typeDef;
}
private MethodDef CreateDispatchMethodInfo(MethodSig methodSig)
{
if (_proxyTypeDef == null)
{
_proxyTypeDef = CreateProxyTypeDef();
}
MethodDef methodDef = new MethodDefUser($"$Obfuz$ProxyCall$Dispatch${_proxyTypeDef.Methods.Count}", methodSig,
MethodImplAttributes.IL | MethodImplAttributes.Managed,
MethodAttributes.Static | MethodAttributes.Private);
methodDef.DeclaringType = _proxyTypeDef;
return methodDef;
}
private MethodSig CreateDispatchMethodSig(IMethod method)
{
MethodSig methodSig = MetaUtil.ToSharedMethodSig(_module.CorLibTypes, MetaUtil.GetInflatedMethodSig(method));
// extra param for secret
methodSig.Params.Add(_module.CorLibTypes.Int32);
return methodSig;
}
private DispatchMethodInfo GetDispatchMethod(IMethod method)
{
MethodSig methodSig = CreateDispatchMethodSig(method);
if (!_dispatchMethods.TryGetValue(methodSig, out var dispatchMethods))
{
dispatchMethods = new List<DispatchMethodInfo>();
_dispatchMethods.Add(methodSig, dispatchMethods);
}
if (dispatchMethods.Count == 0 || dispatchMethods.Last().methods.Count >= maxProxyMethodPerDispatchMethod)
{
var newDispatchMethodInfo = new DispatchMethodInfo
{
methodDef = CreateDispatchMethodInfo(methodSig),
secret = 0,
};
dispatchMethods.Add(newDispatchMethodInfo);
}
return dispatchMethods.Last();
}
public ProxyCallMethodData Allocate(IMethod method, bool callVir)
{
var key = new MethodKey(method, callVir);
if (!_methodProxys.TryGetValue(key, out var proxyInfo))
{
var methodDispatcher = GetDispatchMethod(method);
proxyInfo = new MethodProxyInfo()
{
proxyMethod = methodDispatcher.methodDef,
secret = methodDispatcher.methods.Count,
};
methodDispatcher.methods.Add(method);
_methodProxys.Add(key, proxyInfo);
}
return new ProxyCallMethodData { proxyMethod = proxyInfo.proxyMethod, secret = proxyInfo.secret };
}
public void Done()
{
foreach (DispatchMethodInfo dispatchMethod in _dispatchMethods.Values.SelectMany(ms => ms))
{
var methodDef = dispatchMethod.methodDef;
var secret = dispatchMethod.secret;
var methodSig = methodDef.MethodSig;
var body = new CilBody();
methodDef.Body = body;
var ins = body.Instructions;
ins.Add(Instruction.Create(OpCodes.Ret));
}
}
}
public class ProxyCallAllocator
{
private readonly IRandom _random;
private readonly Dictionary<ModuleDef, ModuleDynamicProxyMethodAllocator> _moduleAllocators = new Dictionary<ModuleDef, ModuleDynamicProxyMethodAllocator>();
public ProxyCallAllocator(IRandom random)
{
_random = random;
}
public ProxyCallMethodData Allocate(ModuleDef mod, IMethod method, bool callVir)
{
if (!_moduleAllocators.TryGetValue(mod, out var allocator))
{
allocator = new ModuleDynamicProxyMethodAllocator(mod, _random);
_moduleAllocators.Add(mod, allocator);
}
return allocator.Allocate(method, callVir);
}
public void Done()
{
foreach (var allocator in _moduleAllocators.Values)
{
allocator.Done();
}
_moduleAllocators.Clear();
}
}
}

View File

@ -1,5 +1,5 @@
{
"name": "Obfuz",
"name": "Obfuz.Editor",
"rootNamespace": "",
"references": [
"GUID:7e4de3067c2ab5c43a03ac49273dfb68",

View File

@ -16,6 +16,14 @@ namespace Obfuz.DynamicProxy
public override bool NeedDynamicProxyCalledMethod(IMethod method, bool callVir)
{
ITypeDefOrRef declaringType = method.DeclaringType;
TypeDef typeDef = declaringType.ResolveTypeDef();
// doesn't proxy call if the method is a delegate
if (typeDef != null && typeDef.IsDelegate)
{
return false;
}
return true;
}
}

View File

@ -0,0 +1,33 @@
using dnlib.DotNet.Emit;
using dnlib.DotNet;
using System.Collections.Generic;
using Obfuz.Utils;
using Obfuz.Emit;
namespace Obfuz.DynamicProxy
{
public class DefaultDynamicProxyObfuscator : DynamicProxyObfuscatorBase
{
private readonly IRandom _random;
private readonly ProxyCallAllocator _proxyCallAllocator;
public DefaultDynamicProxyObfuscator(IRandom random)
{
_random = random;
_proxyCallAllocator = new ProxyCallAllocator(random);
}
public override void Done()
{
_proxyCallAllocator.Done();
}
public override void Obfuscate(MethodDef callingMethod, IMethod calledMethod, bool callVir, List<Instruction> obfuscatedInstructions)
{
MethodSig sharedMethodSig = MetaUtil.ToSharedMethodSig(calledMethod.Module.CorLibTypes, MetaUtil.GetInflatedMethodSig(calledMethod));
ProxyCallMethodData proxyCallMethodData = _proxyCallAllocator.Allocate(callingMethod.Module, calledMethod, callVir);
obfuscatedInstructions.Add(Instruction.CreateLdcI4(proxyCallMethodData.secret));
obfuscatedInstructions.Add(Instruction.Create(OpCodes.Call, proxyCallMethodData.proxyMethod));
}
}
}

View File

@ -7,5 +7,6 @@ namespace Obfuz.DynamicProxy
public abstract class DynamicProxyObfuscatorBase : IDynamicProxyObfuscator
{
public abstract void Obfuscate(MethodDef callingMethod, IMethod calledMethod, bool callVir, List<Instruction> obfuscatedInstructions);
public abstract void Done();
}
}

View File

@ -1,5 +1,6 @@
using dnlib.DotNet;
using dnlib.DotNet.Emit;
using Obfuz.Utils;
using Obfuz.Virtualization;
using System;
using System.Collections.Generic;
@ -13,18 +14,20 @@ namespace Obfuz.DynamicProxy
{
public class DynamicProxyPass : MethodBodyObfuscationPassBase
{
private readonly IRandom _random;
private readonly IDynamicProxyPolicy _dynamicProxyPolicy;
private readonly IDynamicProxyObfuscator _dynamicProxyObfuscator;
public DynamicProxyPass()
{
_random = new RandomWithKey(new byte[] { 0x1, 0x2, 0x3, 0x4 }, 0x5);
_dynamicProxyPolicy = new ConfigDynamicProxyPolicy();
_dynamicProxyObfuscator = new DefaultDynamicProxyObfuscator();
_dynamicProxyObfuscator = new DefaultDynamicProxyObfuscator(_random);
}
public override void Stop(ObfuscatorContext ctx)
{
_dynamicProxyObfuscator.Done();
}
public override void Start(ObfuscatorContext ctx)
@ -39,13 +42,21 @@ namespace Obfuz.DynamicProxy
protected override bool TryObfuscateInstruction(MethodDef method, Instruction inst, IList<Instruction> instructions, int instructionIndex,
List<Instruction> outputInstructions, List<Instruction> totalFinalInstructions)
{
IMethod calledMethod = inst.Operand as IMethod;
if (calledMethod == null || !calledMethod.IsMethod)
{
return false;
}
if (MetaUtil.ContainsContainsGenericParameter(calledMethod))
{
return false;
}
switch (inst.OpCode.Code)
{
case Code.Call:
{
IMethod calledMethod = (IMethod)inst.Operand;
if (!_dynamicProxyPolicy.NeedDynamicProxyCalledMethod(calledMethod, false))
{
return false;
@ -59,7 +70,6 @@ namespace Obfuz.DynamicProxy
{
return false;
}
IMethod calledMethod = (IMethod)inst.Operand;
if (!_dynamicProxyPolicy.NeedDynamicProxyCalledMethod(calledMethod, true))
{
return false;

View File

@ -11,5 +11,7 @@ namespace Obfuz.DynamicProxy
public interface IDynamicProxyObfuscator
{
void Obfuscate(MethodDef callingMethod, IMethod calledMethod, bool callVir, List<Instruction> obfuscatedInstructions);
void Done();
}
}

View File

@ -1,5 +1,6 @@
using dnlib.DotNet;
using Obfuz.Rename;
using Obfuz.Utils;
using System.Collections.Generic;
using System.IO;
using System.Linq;

View File

@ -1,5 +1,6 @@
using dnlib.DotNet;
using Obfuz.Rename;
using Obfuz.Utils;
using System;
using System.Collections;
using System.Collections.Generic;

View File

@ -1,4 +1,5 @@
using dnlib.DotNet;
using Obfuz.Utils;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;

View File

@ -1,4 +1,5 @@
using dnlib.DotNet;
using Obfuz.Utils;
using System;
using System.Collections.Generic;
using System.Linq;

View File

@ -0,0 +1,126 @@
using dnlib.DotNet;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Obfuz.Utils
{
/// <summary>
/// Replaces generic type/method var with its generic argument
/// </summary>
public sealed class GenericArgumentContext
{
List<TypeSig> typeArgsStack;
List<TypeSig> methodArgsStack;
public GenericArgumentContext(IList<TypeSig> typeArgsStack, IList<TypeSig> methodArgsStack)
{
this.typeArgsStack = typeArgsStack?.ToList();
this.methodArgsStack = methodArgsStack?.ToList();
}
/// <summary>
/// Replaces a generic type/method var with its generic argument (if any). If
/// <paramref name="typeSig"/> isn't a generic type/method var or if it can't
/// be resolved, it itself is returned. Else the resolved type is returned.
/// </summary>
/// <param name="typeSig">Type signature</param>
/// <returns>New <see cref="TypeSig"/> which is never <c>null</c> unless
/// <paramref name="typeSig"/> is <c>null</c></returns>
public TypeSig Resolve(TypeSig typeSig)
{
if (!typeSig.ContainsGenericParameter)
{
return typeSig;
}
typeSig = typeSig.RemovePinnedAndModifiers();
switch (typeSig.ElementType)
{
case ElementType.Ptr: return new PtrSig(Resolve(typeSig.Next));
case ElementType.ByRef: return new PtrSig(Resolve(typeSig.Next));
case ElementType.SZArray: return new PtrSig(Resolve(typeSig.Next));
case ElementType.Array:
{
var ara = (ArraySig)typeSig;
return new ArraySig(Resolve(typeSig.Next), ara.Rank, ara.Sizes, ara.LowerBounds);
}
case ElementType.Var:
{
GenericVar genericVar = (GenericVar)typeSig;
var newSig = Resolve(typeArgsStack, genericVar.Number, true);
if (newSig == null)
{
throw new Exception();
}
return newSig;
}
case ElementType.MVar:
{
GenericMVar genericVar = (GenericMVar)typeSig;
var newSig = Resolve(methodArgsStack, genericVar.Number, true);
if (newSig == null)
{
throw new Exception();
}
return newSig;
}
case ElementType.GenericInst:
{
var gia = (GenericInstSig)typeSig;
return new GenericInstSig(gia.GenericType, gia.GenericArguments.Select(ga => Resolve(ga)).ToList());
}
case ElementType.FnPtr:
{
var fptr = (FnPtrSig)typeSig;
var cs = fptr.Signature;
CallingConventionSig ccs;
switch (cs)
{
case MethodSig ms:
{
ccs = new MethodSig(ms.GetCallingConvention(), ms.GenParamCount, Resolve(ms.RetType), ms.Params.Select(p => Resolve(p)).ToList());
break;
}
case PropertySig ps:
{
ccs = new PropertySig(ps.HasThis, Resolve(ps.RetType));
break;
}
case GenericInstMethodSig gims:
{
ccs = new GenericInstMethodSig(gims.GenericArguments.Select(ga => Resolve(ga)).ToArray());
break;
}
default: throw new NotSupportedException(cs.ToString());
}
return new FnPtrSig(ccs);
}
case ElementType.ValueArray:
{
var vas = (ValueArraySig)typeSig;
return new ValueArraySig(Resolve(vas.Next), vas.Size);
}
default: return typeSig;
}
}
private TypeSig Resolve(List<TypeSig> args, uint number, bool isTypeVar)
{
var typeSig = args[(int)number];
var gvar = typeSig as GenericSig;
if (gvar is null || gvar.IsTypeVar != isTypeVar)
return typeSig;
return gvar;
}
}
}

28
Editor/Utils/HashUtil.cs Normal file
View File

@ -0,0 +1,28 @@
using dnlib.DotNet;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Obfuz
{
public static class HashUtil
{
public static int CombineHash(int hash1, int hash2)
{
return hash1 * 1566083941 + hash2;
}
public static int ComputeHash(List<TypeSig> sigs)
{
int hash = 135781321;
TypeEqualityComparer tc = TypeEqualityComparer.Instance;
foreach (var sig in sigs)
{
hash = hash * 1566083941 + tc.GetHashCode(sig);
}
return hash;
}
}
}

View File

@ -5,8 +5,9 @@ using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine.Assertions;
namespace Obfuz
namespace Obfuz.Utils
{
public static class MetaUtil
{
@ -420,5 +421,223 @@ namespace Obfuz
}
return anyChange;
}
//public static bool ContainsContainsGenericParameter1(MethodDef method)
//{
// Assert.IsTrue(!(method.DeclaringType.ContainsGenericParameter || method.MethodSig.ContainsGenericParameter));
// return false;
//}
public static bool ContainsContainsGenericParameter1(MethodSpec methodSpec)
{
if (methodSpec.GenericInstMethodSig.ContainsGenericParameter)
{
return true;
}
IMethodDefOrRef method = methodSpec.Method;
if (method.IsMethodDef)
{
return false;// ContainsContainsGenericParameter1((MethodDef)method);
}
if (method.IsMemberRef)
{
return ContainsContainsGenericParameter1((MemberRef)method);
}
throw new Exception($"unknown method: {method}");
}
public static bool ContainsContainsGenericParameter1(MemberRef memberRef)
{
IMemberRefParent parent = memberRef.Class;
if (parent is TypeSpec typeSpec)
{
return typeSpec.ContainsGenericParameter;
}
return false;
}
public static bool ContainsContainsGenericParameter(IMethod method)
{
Assert.IsTrue(method.IsMethod);
if (method is MethodDef methodDef)
{
return false;
}
if (method is MethodSpec methodSpec)
{
return ContainsContainsGenericParameter1(methodSpec);
}
if (method is MemberRef memberRef)
{
return ContainsContainsGenericParameter1(memberRef);
}
throw new Exception($"unknown method: {method}");
}
public static TypeSig Inflate(TypeSig sig, GenericArgumentContext ctx)
{
if (!sig.ContainsGenericParameter)
{
return sig;
}
return ctx.Resolve(sig);
}
public static MethodSig InflateMethodSig(MethodSig methodSig, GenericArgumentContext genericArgumentContext)
{
var newReturnType = Inflate(methodSig.RetType, genericArgumentContext);
var newParams = new List<TypeSig>();
foreach (var param in methodSig.Params)
{
newParams.Add(Inflate(param, genericArgumentContext));
}
var newParamsAfterSentinel = new List<TypeSig>();
if (methodSig.ParamsAfterSentinel != null)
{
throw new NotSupportedException($"methodSig.ParamsAfterSentinel is not supported: {methodSig}");
//foreach (var param in methodSig.ParamsAfterSentinel)
//{
// newParamsAfterSentinel.Add(Inflate(param, genericArgumentContext));
//}
}
return new MethodSig(methodSig.CallingConvention, methodSig.GenParamCount, newReturnType, newParams, null);
}
public static IList<TypeSig> GetGenericArguments(IMemberRefParent type)
{
if (type is TypeDef typeDef)
{
return null;
}
if (type is TypeRef typeRef)
{
return null;
}
if (type is TypeSpec typeSpec)
{
GenericInstSig genericInstSig = typeSpec.TypeSig.ToGenericInstSig();
return genericInstSig?.GenericArguments;
}
throw new NotSupportedException($"type:{type}");
}
public static MethodSig GetInflatedMethodSig(IMethod method)
{
if (method is MethodDef methodDef)
{
return methodDef.MethodSig;
}
if (method is MemberRef memberRef)
{
return InflateMethodSig(memberRef.MethodSig, new GenericArgumentContext(GetGenericArguments(memberRef.Class), null));
}
if (method is MethodSpec methodSpec)
{
var genericInstMethodSig = methodSpec.GenericInstMethodSig;
if (methodSpec.Method is MethodDef methodDef2)
{
return InflateMethodSig(methodDef2.MethodSig, new GenericArgumentContext(null, genericInstMethodSig.GenericArguments));
}
if (methodSpec.Method is MemberRef memberRef2)
{
return InflateMethodSig(memberRef2.MethodSig, new GenericArgumentContext(GetGenericArguments(memberRef2.Class), genericInstMethodSig.GenericArguments));
}
}
throw new NotSupportedException($" method: {method}");
}
public static MethodSig ToSharedMethodSig(ICorLibTypes corTypes, MethodSig methodSig)
{
var newReturnType = ToShareTypeSig(corTypes, methodSig.RetType);
var newParams = new List<TypeSig>();
foreach (var param in methodSig.Params)
{
newParams.Add(ToShareTypeSig(corTypes, param));
}
if (methodSig.ParamsAfterSentinel != null)
{
//foreach (var param in methodSig.ParamsAfterSentinel)
//{
// newParamsAfterSentinel.Add(ToShareTypeSig(corTypes, param));
//}
throw new NotSupportedException($"methodSig.ParamsAfterSentinel is not supported: {methodSig}");
}
return new MethodSig(methodSig.CallingConvention, methodSig.GenParamCount, newReturnType, newParams, null);
}
public static TypeSig ToShareTypeSig(ICorLibTypes corTypes, TypeSig typeSig)
{
var a = typeSig.RemovePinnedAndModifiers();
switch (a.ElementType)
{
case ElementType.Void: return corTypes.Void;
case ElementType.Boolean: return corTypes.Byte;
case ElementType.Char: return corTypes.UInt16;
case ElementType.I1: return corTypes.SByte;
case ElementType.U1: return corTypes.Byte;
case ElementType.I2: return corTypes.Int16;
case ElementType.U2: return corTypes.UInt16;
case ElementType.I4: return corTypes.Int32;
case ElementType.U4: return corTypes.UInt32;
case ElementType.I8: return corTypes.Int64;
case ElementType.U8: return corTypes.UInt64;
case ElementType.R4: return corTypes.Single;
case ElementType.R8: return corTypes.Double;
case ElementType.String: return corTypes.Object;
case ElementType.TypedByRef: return corTypes.TypedReference;
case ElementType.I: return corTypes.IntPtr;
case ElementType.U: return corTypes.UIntPtr;
case ElementType.Object: return corTypes.Object;
case ElementType.Sentinel: return typeSig;
case ElementType.Ptr: return corTypes.UIntPtr;
case ElementType.ByRef: return corTypes.UIntPtr;
case ElementType.SZArray: return corTypes.Object;
case ElementType.Array: return corTypes.Object;
case ElementType.ValueType:
{
TypeDef typeDef = a.ToTypeDefOrRef().ResolveTypeDef();
if (typeDef == null)
{
throw new Exception($"type:{a} definition could not be found");
}
if (typeDef.IsEnum)
{
return ToShareTypeSig(corTypes, typeDef.GetEnumUnderlyingType());
}
return typeSig;
}
case ElementType.Var:
case ElementType.MVar:
case ElementType.Class: return corTypes.Object;
case ElementType.GenericInst:
{
var gia = (GenericInstSig)a;
TypeDef typeDef = gia.GenericType.ToTypeDefOrRef().ResolveTypeDef();
if (typeDef == null)
{
throw new Exception($"type:{a} definition could not be found");
}
if (typeDef.IsEnum)
{
return ToShareTypeSig(corTypes, typeDef.GetEnumUnderlyingType());
}
if (!typeDef.IsValueType)
{
return corTypes.Object;
}
return new GenericInstSig(gia.GenericType, gia.GenericArguments.Select(ga => ToShareTypeSig(corTypes, ga)).ToList());
}
case ElementType.FnPtr: return corTypes.UIntPtr;
case ElementType.ValueArray: return typeSig;
case ElementType.Module: return typeSig;
default:
throw new NotSupportedException(typeSig.ToString());
}
}
}
}

View File

@ -24,7 +24,7 @@ namespace Obfuz.Virtualization
public override void Stop(ObfuscatorContext ctx)
{
_dataObfuscator.Stop();
_dataObfuscator.Done();
}
protected override bool NeedObfuscateMethod(MethodDef method)

View File

@ -79,7 +79,7 @@ namespace Obfuz.Virtualization
//obfuscatedInstructions.Add(Instruction.Create(OpCodes.Ldstr, value));
}
public void Stop()
public void Done()
{
_rvaDataAllocator.Done();
_constFieldAllocator.Done();

View File

@ -19,6 +19,7 @@ namespace Obfuz.Virtualization
void ObfuscateString(MethodDef method, string value, List<Instruction> obfuscatedInstructions);
void ObfuscateBytes(MethodDef method, Array value, List<Instruction> obfuscatedInstructions);
void Stop();
void Done();
}
}