Messing around with Unity mono hooks I ran into an issue calling
[MethodImpl(MethodImplOptions.InternalCall)] declared methods.
If you haven’t encountered these before, they are references to unmanaged native (read C/C++ binary) methods.
Similar to how you might use one like this with “DLLImport”:
[DllImport("kernel32.dll", CharSet = CharSet.Auto)] public static extern void OutputDebugString(string message);
Here I can now output to Sysinternals DebugView in C# doing:
OutputDebugString("Hello World!\n");
What’s the point of MethodImplOptions.InternalCall?
https://stackoverflow.com/questions/11161120/whats-the-point-of-methodimploptions-internalcall
Making this post because people seem to think you can’t call these and I spent too much time tracking down how to do it.
You can actually, simply, use the reflection features to grab an instance and then just “Invoke” it like this:
// Call the internal CLR SendTo_internal_real() method directly .. // First grab the method reference to SendTo_internal_real() MethodInfo method = typeof(Socket).GetMethod("SendTo_internal_real", (BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)); if (method != null) { // To manually verify the prototype OutputDebugString(string.Format("SendTo_internal_real: {0}\n", method)); // Invoke it directly (Sends a UDP packet almost directly to "sendto()" inside "mono.dll" int error = 0; int result = (int) method.Invoke(method , new System.Object[] { sock, buffer, offset, count, flags, sa, error }); }
[Edit: I’m struggling with this new WordPress Gutenberg editor..]
How this all works is the code inside “System.Net.Sockets: class Socket” has this reference:
[MethodImpl(MethodImplOptions.InternalCall)] private static extern int SendTo_internal_real(IntPtr sock, byte[] buffer, int offset, int count, SocketFlags flags, SocketAddress sa, out int error);
Somewhere in the .NET internals via mscorlib.dll (didn’t need to dig any deeper), when the system needs to reference the method to call or to JIT it, it calls down a layer or two to mono_lookup_internal_call in mono.dll.
Which in turn will access the “icall_functions” function pointer table, via a matching index string ( in this case “Send_internal(intptr,System.Net.Sockets.Socket/WSABUF[],System.Net.Sockets.SocketFlags,int&)”) in the “icall_type_names” string pointer table.
mono_lookup_internal_call on success returns the actual native function known symbolically as ves_icall_System_Net_Sockets_Socket_SendTo_internal
Note an odd thing, in this case I’m apparently getting a reference to the reference that’s already in System.Net.Sockets:Socket (it got initialized before my assembly ran I’m certain).
Happy game hacking..