g_m
g_m

Reputation: 536

How to use GetMethod in my own class obfuscated by ConfuserEx?

I have my own DLL which I secure with ConfuserEx. In the ConfuserEx I'm using the "rename" protection:

<protection id="rename">
    <argument name="mode" value="unicode" />
    <argument name="renEnum" value="true" />        
</protection>    

This of course secures the DLL from viewing the code, but my class (which I have secured as part of a DLL), uses:

MethodInfo mi = typeof(MyClass).GetMethod(nameof(MyStaticMethod), BindingFlags.Static | BindingFlags.NonPublic);

Here the problem starts, because even my own code cannot find and use my (protected by ConfuserEx) method. I use GetMethod to call: Delegate.CreateDelegate. What can I do to solve this problem?

Upvotes: 0

Views: 792

Answers (2)

g_m
g_m

Reputation: 536

I solved this problem by applying an additional "bridge delegate" between GetMethod and the target method. Then, instead of nameof (MyStaticMethod), I use BridgeDelegate.Method.Name. I checked and works correctly.

Example solution:

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
    }
}

Upvotes: 1

Damien_The_Unbeliever
Damien_The_Unbeliever

Reputation: 239764

I'm still not sure why you can't just create the delegate you need directly without reflection, but if you really need to get the MethodInfo, try doing something like this:

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)
    {

    }
}

That is, use your own locally defined delegate that matches the other delegate definition, create an instance of it directly in your code and then extract the MethodInfo from that instance.

This code will be using a method token to identify DoStuff rather than its name so should survive obfuscation without issue.

Upvotes: 2

Related Questions