Skip to content
New issue

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

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

Already on GitHub? Sign in 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.

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

No branches or pull requests

1 participant