06 Mar

.Net: Access to internal CLR methods

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 do this, and I spent too much time tracking it down.

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











Leave a Reply

Your email address will not be published. Required fields are marked *