生成稳定的call obfus的Dispatch函数名
parent
ac6ca08d87
commit
10d450c4e3
|
@ -77,6 +77,7 @@ namespace Obfuz.ObfusPasses.CallObfus
|
|||
|
||||
class CallInfo
|
||||
{
|
||||
public string id;
|
||||
public IMethod method;
|
||||
public bool callVir;
|
||||
}
|
||||
|
@ -114,13 +115,39 @@ namespace Obfuz.ObfusPasses.CallObfus
|
|||
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)
|
||||
{
|
||||
_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,
|
||||
MethodAttributes.Static | MethodAttributes.Public);
|
||||
methodDef.DeclaringType = _proxyTypeDef;
|
||||
|
@ -172,7 +199,7 @@ namespace Obfuz.ObfusPasses.CallObfus
|
|||
{
|
||||
var newDispatchMethodInfo = new DispatchMethodInfo
|
||||
{
|
||||
methodDef = CreateDispatchMethodInfo(methodSig),
|
||||
methodDef = CreateDispatchMethodInfo(methodSig, dispatchMethods.Count),
|
||||
};
|
||||
dispatchMethods.Add(newDispatchMethodInfo);
|
||||
}
|
||||
|
@ -209,7 +236,7 @@ namespace Obfuz.ObfusPasses.CallObfus
|
|||
salt = salt,
|
||||
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);
|
||||
}
|
||||
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");
|
||||
}
|
||||
_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))
|
||||
{
|
||||
|
@ -242,6 +282,9 @@ namespace Obfuz.ObfusPasses.CallObfus
|
|||
var switchInst = Instruction.Create(OpCodes.Switch, switchCases);
|
||||
ins.Add(switchInst);
|
||||
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)
|
||||
{
|
||||
var callTargetMethod = Instruction.Create(ci.callVir ? OpCodes.Callvirt : OpCodes.Call, ci.method);
|
||||
|
|
|
@ -11,7 +11,12 @@ namespace Obfuz.Utils
|
|||
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;
|
||||
TypeEqualityComparer tc = TypeEqualityComparer.Instance;
|
||||
|
|
Loading…
Reference in New Issue