Как использовать GetMethod в моем собственном классе, скрытом ConfuserEx?
У меня есть собственная библиотека DLL, которую я защищаю с помощью ConfuserEx. В ConfuserEx я использую защиту "переименовать":
<protection id="rename">
<argument name="mode" value="unicode" />
<argument name="renEnum" value="true" />
</protection>
Это, конечно, защищает DLL от просмотра кода, но мой класс (который я закрепил как часть DLL) использует:
MethodInfo mi = typeof(MyClass).GetMethod(nameof(MyStaticMethod), BindingFlags.Static | BindingFlags.NonPublic);
Здесь начинается проблема, потому что даже мой собственный код не может найти и использовать мой (защищенный ConfuserEx) метод. Я использую GetMethod для вызова: Delegate.CreateDelegate. Что я могу сделать, чтобы решить эту проблему?
2 ответа
Я до сих пор не уверен, почему вы не можете просто создать нужный делегат напрямую, без размышлений, но если вам действительно нужно получить MethodInfo
попробуйте сделать что-то вроде этого:
using System;
using System.IO;
class Program
{
static void Main(string[] args)
{
Thingy t = DoStuff;
var mi = t.Method;
}
private delegate void Thingy(object sender, EventArgs e);
private static void DoStuff(object sender, EventArgs e)
{
}
}
То есть используйте свой собственный локально определенный делегат, который соответствует другому определению делегата, создайте его экземпляр непосредственно в своем коде и затем извлеките MethodInfo
из этого экземпляра.
Этот код будет использовать маркер метода для идентификации DoStuff
а не его имя, поэтому должно пережить запутывание без проблем.
Я решил эту проблему, применив дополнительный "делегат моста" между GetMethod и целевым методом. Затем вместо nameof (MyStaticMethod) я использую BridgeDelegate.Method.Name. Я проверил и работает правильно.
Пример решения:
internal static class MyClass
{
private delegate void ExecuteObfuscatedMethod(string value);
private static ExecuteObfuscatedMethod Bridge; //This is my "bridge"
internal static void CaptureExternalDelegate(object source)
{
//Using a "bridge" instead of the direct method name
MethodInfo mi = typeof(MyClass).GetMethod(Bridge.Method.Name, BindingFlags.Static | BindingFlags.NonPublic);
//Less interesting code
PropertyInfo p = source.GetType().GetProperty("SomePrivateDelegate", BindingFlags.NonPublic | BindingFlags.Instance);
Delegate del = Delegate.CreateDelegate(p.PropertyType, mi) as Delegate;
Delegate original = p.GetValue(source) as Delegate;
Delegate combined = Delegate.Combine(original, del);
p.SetValue(property, combined);
}
static MyClass()
{
Bridge += MyStaticMethod;
}
//This is the method whose name can not be retrieved by nameof () after applying ConfuserEx
private static void MyStaticMethod(string value)
{
//I am testing the method's name after calling it.
var st = new StackTrace();
var sf = st.GetFrame(0);
var currentMethodName = sf.GetMethod();
throw new Exception("The method name is: " + currentMethodName); //You can see that the method has evoked and you can even see its new name
}
}