修复生成的ProxyCall的this参数的Bug
parent
f513b9f414
commit
bcba063ff5
|
@ -56,11 +56,18 @@ namespace Obfuz.Emit
|
||||||
|
|
||||||
|
|
||||||
const int maxProxyMethodPerDispatchMethod = 1000;
|
const int maxProxyMethodPerDispatchMethod = 1000;
|
||||||
|
|
||||||
|
class CallInfo
|
||||||
|
{
|
||||||
|
public IMethod method;
|
||||||
|
public bool callVir;
|
||||||
|
}
|
||||||
|
|
||||||
class DispatchMethodInfo
|
class DispatchMethodInfo
|
||||||
{
|
{
|
||||||
public MethodDef methodDef;
|
public MethodDef methodDef;
|
||||||
public int secret;
|
public int secret;
|
||||||
public List<IMethod> methods = new List<IMethod>();
|
public List<CallInfo> methods = new List<CallInfo>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly Dictionary<MethodSig, List<DispatchMethodInfo>> _dispatchMethods = new Dictionary<MethodSig, List<DispatchMethodInfo>>(SignatureEqualityComparer.Instance);
|
private readonly Dictionary<MethodSig, List<DispatchMethodInfo>> _dispatchMethods = new Dictionary<MethodSig, List<DispatchMethodInfo>>(SignatureEqualityComparer.Instance);
|
||||||
|
@ -100,9 +107,23 @@ namespace Obfuz.Emit
|
||||||
private MethodSig CreateDispatchMethodSig(IMethod method)
|
private MethodSig CreateDispatchMethodSig(IMethod method)
|
||||||
{
|
{
|
||||||
MethodSig methodSig = MetaUtil.ToSharedMethodSig(_module.CorLibTypes, MetaUtil.GetInflatedMethodSig(method));
|
MethodSig methodSig = MetaUtil.ToSharedMethodSig(_module.CorLibTypes, MetaUtil.GetInflatedMethodSig(method));
|
||||||
|
//methodSig.Params
|
||||||
|
switch(MetaUtil.GetThisArgType(method))
|
||||||
|
{
|
||||||
|
case ThisArgType.Class:
|
||||||
|
{
|
||||||
|
methodSig.Params.Insert(0, _module.CorLibTypes.Object);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ThisArgType.ValueType:
|
||||||
|
{
|
||||||
|
methodSig.Params.Insert(0, _module.CorLibTypes.UIntPtr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
// extra param for secret
|
// extra param for secret
|
||||||
methodSig.Params.Add(_module.CorLibTypes.Int32);
|
methodSig.Params.Add(_module.CorLibTypes.Int32);
|
||||||
return methodSig;
|
return MethodSig.CreateStatic(methodSig.RetType, methodSig.Params.ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
private DispatchMethodInfo GetDispatchMethod(IMethod method)
|
private DispatchMethodInfo GetDispatchMethod(IMethod method)
|
||||||
|
@ -136,7 +157,7 @@ namespace Obfuz.Emit
|
||||||
proxyMethod = methodDispatcher.methodDef,
|
proxyMethod = methodDispatcher.methodDef,
|
||||||
secret = methodDispatcher.methods.Count,
|
secret = methodDispatcher.methods.Count,
|
||||||
};
|
};
|
||||||
methodDispatcher.methods.Add(method);
|
methodDispatcher.methods.Add(new CallInfo { method = method, callVir = callVir});
|
||||||
_methodProxys.Add(key, proxyInfo);
|
_methodProxys.Add(key, proxyInfo);
|
||||||
}
|
}
|
||||||
return new ProxyCallMethodData { proxyMethod = proxyInfo.proxyMethod, secret = proxyInfo.secret };
|
return new ProxyCallMethodData { proxyMethod = proxyInfo.proxyMethod, secret = proxyInfo.secret };
|
||||||
|
@ -154,7 +175,24 @@ namespace Obfuz.Emit
|
||||||
var body = new CilBody();
|
var body = new CilBody();
|
||||||
methodDef.Body = body;
|
methodDef.Body = body;
|
||||||
var ins = body.Instructions;
|
var ins = body.Instructions;
|
||||||
ins.Add(Instruction.Create(OpCodes.Ret));
|
|
||||||
|
foreach (Parameter param in methodDef.Parameters)
|
||||||
|
{
|
||||||
|
ins.Add(Instruction.Create(OpCodes.Ldarg, param));
|
||||||
|
}
|
||||||
|
|
||||||
|
var switchCases = new List<Instruction>();
|
||||||
|
var switchInst = Instruction.Create(OpCodes.Switch, switchCases);
|
||||||
|
ins.Add(switchInst);
|
||||||
|
var ret = Instruction.Create(OpCodes.Ret);
|
||||||
|
foreach (CallInfo ci in dispatchMethod.methods)
|
||||||
|
{
|
||||||
|
var callTargetMethod = Instruction.Create(ci.callVir ? OpCodes.Callvirt : OpCodes.Call, ci.method);
|
||||||
|
switchCases.Add(callTargetMethod);
|
||||||
|
ins.Add(callTargetMethod);
|
||||||
|
ins.Add(Instruction.Create(OpCodes.Br, ret));
|
||||||
|
}
|
||||||
|
ins.Add(ret);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,9 +6,17 @@ using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using UnityEngine.Assertions;
|
using UnityEngine.Assertions;
|
||||||
|
using UnityEngine.UIElements;
|
||||||
|
|
||||||
namespace Obfuz.Utils
|
namespace Obfuz.Utils
|
||||||
{
|
{
|
||||||
|
public enum ThisArgType
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
ValueType,
|
||||||
|
Class,
|
||||||
|
}
|
||||||
|
|
||||||
public static class MetaUtil
|
public static class MetaUtil
|
||||||
{
|
{
|
||||||
public static string GetModuleNameWithoutExt(string moduleName)
|
public static string GetModuleNameWithoutExt(string moduleName)
|
||||||
|
@ -551,6 +559,32 @@ namespace Obfuz.Utils
|
||||||
throw new NotSupportedException($" method: {method}");
|
throw new NotSupportedException($" method: {method}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ThisArgType GetThisArgType(IMethod method)
|
||||||
|
{
|
||||||
|
if (!method.MethodSig.HasThis)
|
||||||
|
{
|
||||||
|
return ThisArgType.None;
|
||||||
|
}
|
||||||
|
if (method is MethodDef methodDef)
|
||||||
|
{
|
||||||
|
return methodDef.DeclaringType.IsValueType ? ThisArgType.ValueType : ThisArgType.Class;
|
||||||
|
}
|
||||||
|
if (method is MemberRef memberRef)
|
||||||
|
{
|
||||||
|
TypeDef typeDef = MetaUtil.GetMemberRefTypeDefParentOrNull(memberRef.Class);
|
||||||
|
if (typeDef == null)
|
||||||
|
{
|
||||||
|
return ThisArgType.Class;
|
||||||
|
}
|
||||||
|
return typeDef.IsValueType ? ThisArgType.ValueType : ThisArgType.Class;
|
||||||
|
}
|
||||||
|
if (method is MethodSpec methodSpec)
|
||||||
|
{
|
||||||
|
return GetThisArgType(methodSpec.Method);
|
||||||
|
}
|
||||||
|
throw new NotSupportedException($" method: {method}");
|
||||||
|
}
|
||||||
|
|
||||||
public static MethodSig ToSharedMethodSig(ICorLibTypes corTypes, MethodSig methodSig)
|
public static MethodSig ToSharedMethodSig(ICorLibTypes corTypes, MethodSig methodSig)
|
||||||
{
|
{
|
||||||
var newReturnType = ToShareTypeSig(corTypes, methodSig.RetType);
|
var newReturnType = ToShareTypeSig(corTypes, methodSig.RetType);
|
||||||
|
|
Loading…
Reference in New Issue