0xd4d/dnlib

How to export managed method?

CreateAndInject opened this issue · 7 comments

        public static void Test()
        {
            var module= ModuleDefMD.Load(@"C:\cl.dll");
            var method = module.Types[1].Methods[0];
            method.ExportInfo = new MethodExportInfo();
            module.Write("cl.dll");
            var handle = LoadLibrary("cl.dll"); //----   handle=0  ---
            var value = Get(); //---  BadImageFormatException ---
        }
        [DllImport("cl.dll")]
        public static extern int Get();
        [DllImport("kernel32")]
        public static extern int LoadLibrary(string name);

cl.dll (x86)

public static class Demo
{
    public static int Get()
    {
        return 7;
    }
}

If remove "method.ExportInfo = new MethodExportInfo();", handle is not 0.

Did you read the documentation? :)

You have to change the calling convention to cdecl or similar.

There's also a missing piece of info in the documentation, you have to clear the COR20 header flag "IL Only".

I have only tested this code by calling from unmanaged code (eg. C++), not calling it from managed code. I tried a quick hack and updated the MethodExportInfo.Options to None (it defaults to FromUnmanaged) but it also didn't work. Is it supposed to work?

... change call conv here...

// clear IL only flag
var options = new ModuleWriterOptions(module);
options.Cor20HeaderOptions.Flags &= ~ComImageFlags.ILOnly;

Also you should update the call conv in the DllImport to match the call conv you changed the method to.

And don't forget to make sure your test EXE targets x86 or x64 (should be the same as cl.dll)

Yes, I have read the documentation. but it still have error after changing calling convention, so I delete it.
When I clear IL only, handle=LoadLibrary(..) is not 0, but when calling Get(), I get: ExecutionEngineException

There's a "jitDumper3.Core.dll" in JitDumper3, it's a C# dll, and export a managed method "Injection" by ilasm, and I can use DllImport to call it from C#.

This fatal execution engine exception is thrown when debugging with VS. I don't get the exception when I use dnSpy or when I run it from the command line.

It seems if cl.dll is debug, vs will throw an exception, but if cl.dll is release, vs is ok.