Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

How to export managed method? #172

Closed
CreateAndInject opened this issue Mar 30, 2018 · 7 comments
Closed

How to export managed method? #172

CreateAndInject opened this issue Mar 30, 2018 · 7 comments

Comments

@CreateAndInject
Copy link
Contributor

CreateAndInject commented Mar 30, 2018

        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.

@0xd4d
Copy link
Collaborator

0xd4d commented Mar 30, 2018

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;

@0xd4d
Copy link
Collaborator

0xd4d commented Mar 30, 2018

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

@0xd4d
Copy link
Collaborator

0xd4d commented Mar 30, 2018

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

@CreateAndInject
Copy link
Contributor Author

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

@CreateAndInject
Copy link
Contributor Author

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#.

@0xd4d
Copy link
Collaborator

0xd4d commented Mar 30, 2018

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.

@CreateAndInject
Copy link
Contributor Author

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

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant