生成稳定的call obfus的Dispatch函数名
parent
ac6ca08d87
commit
10d450c4e3
|
@ -77,6 +77,7 @@ namespace Obfuz.ObfusPasses.CallObfus
|
||||||
|
|
||||||
class CallInfo
|
class CallInfo
|
||||||
{
|
{
|
||||||
|
public string id;
|
||||||
public IMethod method;
|
public IMethod method;
|
||||||
public bool callVir;
|
public bool callVir;
|
||||||
}
|
}
|
||||||
|
@ -114,13 +115,39 @@ namespace Obfuz.ObfusPasses.CallObfus
|
||||||
return typeDef;
|
return typeDef;
|
||||||
}
|
}
|
||||||
|
|
||||||
private MethodDef CreateDispatchMethodInfo(MethodSig methodSig)
|
private readonly HashSet<string> _uniqueMethodNames = new HashSet<string>();
|
||||||
|
|
||||||
|
|
||||||
|
private string ToUniqueMethodName(string originalName)
|
||||||
|
{
|
||||||
|
if (_uniqueMethodNames.Add(originalName))
|
||||||
|
{
|
||||||
|
return originalName;
|
||||||
|
}
|
||||||
|
for (int index = 1; ; index++)
|
||||||
|
{
|
||||||
|
string uniqueName = $"{originalName}${index}";
|
||||||
|
if (_uniqueMethodNames.Add(uniqueName))
|
||||||
|
{
|
||||||
|
return uniqueName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private string CreateDispatchMethodName(MethodSig methodSig, int index)
|
||||||
|
{
|
||||||
|
// use a stable name for the dispatch method, so that we can reuse it across different modules
|
||||||
|
// this is important for cross-module calls
|
||||||
|
return ToUniqueMethodName($"{ConstValues.ObfuzInternalSymbolNamePrefix}Dispatch_{HashUtil.ComputeHash(methodSig.Params) & 0xFFFF}_{HashUtil.ComputeHash(methodSig.RetType) & 0xFFFFFF}");
|
||||||
|
}
|
||||||
|
|
||||||
|
private MethodDef CreateDispatchMethodInfo(MethodSig methodSig, int index)
|
||||||
{
|
{
|
||||||
if (_proxyTypeDef == null)
|
if (_proxyTypeDef == null)
|
||||||
{
|
{
|
||||||
_proxyTypeDef = CreateProxyTypeDef();
|
_proxyTypeDef = CreateProxyTypeDef();
|
||||||
}
|
}
|
||||||
MethodDef methodDef = new MethodDefUser($"{ConstValues.ObfuzInternalSymbolNamePrefix}ProxyCall$Dispatch${_proxyTypeDef.Methods.Count}", methodSig,
|
MethodDef methodDef = new MethodDefUser(CreateDispatchMethodName(methodSig, index), methodSig,
|
||||||
MethodImplAttributes.IL | MethodImplAttributes.Managed,
|
MethodImplAttributes.IL | MethodImplAttributes.Managed,
|
||||||
MethodAttributes.Static | MethodAttributes.Public);
|
MethodAttributes.Static | MethodAttributes.Public);
|
||||||
methodDef.DeclaringType = _proxyTypeDef;
|
methodDef.DeclaringType = _proxyTypeDef;
|
||||||
|
@ -172,7 +199,7 @@ namespace Obfuz.ObfusPasses.CallObfus
|
||||||
{
|
{
|
||||||
var newDispatchMethodInfo = new DispatchMethodInfo
|
var newDispatchMethodInfo = new DispatchMethodInfo
|
||||||
{
|
{
|
||||||
methodDef = CreateDispatchMethodInfo(methodSig),
|
methodDef = CreateDispatchMethodInfo(methodSig, dispatchMethods.Count),
|
||||||
};
|
};
|
||||||
dispatchMethods.Add(newDispatchMethodInfo);
|
dispatchMethods.Add(newDispatchMethodInfo);
|
||||||
}
|
}
|
||||||
|
@ -209,7 +236,7 @@ namespace Obfuz.ObfusPasses.CallObfus
|
||||||
salt = salt,
|
salt = salt,
|
||||||
encryptedIndex = encryptedIndex,
|
encryptedIndex = encryptedIndex,
|
||||||
};
|
};
|
||||||
methodDispatcher.methods.Add(new CallInfo { method = method, callVir = callVir });
|
methodDispatcher.methods.Add(new CallInfo { id = $"{method}{(callVir ? "" : "v")}", method = method, callVir = callVir });
|
||||||
_methodProxys.Add(key, proxyInfo);
|
_methodProxys.Add(key, proxyInfo);
|
||||||
}
|
}
|
||||||
return new ProxyCallMethodData(proxyInfo.proxyMethod, proxyInfo.encryptedOps, proxyInfo.salt, proxyInfo.encryptedIndex, proxyInfo.index);
|
return new ProxyCallMethodData(proxyInfo.proxyMethod, proxyInfo.encryptedOps, proxyInfo.salt, proxyInfo.encryptedIndex, proxyInfo.index);
|
||||||
|
@ -222,6 +249,19 @@ namespace Obfuz.ObfusPasses.CallObfus
|
||||||
throw new Exception("Already done");
|
throw new Exception("Already done");
|
||||||
}
|
}
|
||||||
_done = true;
|
_done = true;
|
||||||
|
if (_proxyTypeDef == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// for stable order, we sort methods by name
|
||||||
|
var methodWithNamePairList = _proxyTypeDef.Methods.Select(m => (m, m.ToString())).ToList();
|
||||||
|
methodWithNamePairList.Sort((a, b) => a.Item2.CompareTo(b.Item2));
|
||||||
|
_proxyTypeDef.Methods.Clear();
|
||||||
|
foreach (var methodPair in methodWithNamePairList)
|
||||||
|
{
|
||||||
|
methodPair.Item1.DeclaringType = _proxyTypeDef;
|
||||||
|
}
|
||||||
|
|
||||||
foreach (DispatchMethodInfo dispatchMethod in _dispatchMethods.Values.SelectMany(ms => ms))
|
foreach (DispatchMethodInfo dispatchMethod in _dispatchMethods.Values.SelectMany(ms => ms))
|
||||||
{
|
{
|
||||||
|
@ -242,6 +282,9 @@ namespace Obfuz.ObfusPasses.CallObfus
|
||||||
var switchInst = Instruction.Create(OpCodes.Switch, switchCases);
|
var switchInst = Instruction.Create(OpCodes.Switch, switchCases);
|
||||||
ins.Add(switchInst);
|
ins.Add(switchInst);
|
||||||
var ret = Instruction.Create(OpCodes.Ret);
|
var ret = Instruction.Create(OpCodes.Ret);
|
||||||
|
|
||||||
|
// sort methods by signature to ensure stable order
|
||||||
|
dispatchMethod.methods.Sort((a, b) => a.id.CompareTo(b.id));
|
||||||
foreach (CallInfo ci in dispatchMethod.methods)
|
foreach (CallInfo ci in dispatchMethod.methods)
|
||||||
{
|
{
|
||||||
var callTargetMethod = Instruction.Create(ci.callVir ? OpCodes.Callvirt : OpCodes.Call, ci.method);
|
var callTargetMethod = Instruction.Create(ci.callVir ? OpCodes.Callvirt : OpCodes.Call, ci.method);
|
||||||
|
|
|
@ -11,7 +11,12 @@ namespace Obfuz.Utils
|
||||||
return hash1 * 1566083941 + hash2;
|
return hash1 * 1566083941 + hash2;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int ComputeHash(List<TypeSig> sigs)
|
public static int ComputeHash(TypeSig sig)
|
||||||
|
{
|
||||||
|
return TypeEqualityComparer.Instance.GetHashCode(sig);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int ComputeHash(IList<TypeSig> sigs)
|
||||||
{
|
{
|
||||||
int hash = 135781321;
|
int hash = 135781321;
|
||||||
TypeEqualityComparer tc = TypeEqualityComparer.Instance;
|
TypeEqualityComparer tc = TypeEqualityComparer.Instance;
|
||||||
|
|
Loading…
Reference in New Issue