Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can Someone Explain This Code To Me?

Tags:

c#

.net

I was looking at this question: How to implement multiplication without using multiplication operator in .NET and actually had a lot of fun trying to think of ways to multiply without using *.

But I was left scratching my head at this answer. I have no idea what is going on in this code.

Can someone explain it to me?

using System;
using System.Runtime.InteropServices;

delegate uint BinaryOp(uint a, uint b);

static class Program
{
    [DllImport("kernel32.dll", SetLastError = true)]
    static extern bool VirtualProtect(
        IntPtr address, IntPtr size, uint protect, out uint oldProtect);

    static void Main()
    {
        var bytes = IntPtr.Size == sizeof(int) ? //32-bit? It's slower BTW
          new byte[] {0x8B, 0x44, 0x24, 0x04, 0x0F, 0xAF, 0x44, 0x24, 0x08, 0xC3}
        : new byte[] {0x0F, 0xAF, 0xCA, 0x8B, 0xC1, 0xC3};
        var handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
        try
        {
            uint old;
            VirtualProtect(handle.AddrOfPinnedObject(),
                (IntPtr)bytes.Length, 0x40, out old);
            var action = (BinaryOp)Marshal.GetDelegateForFunctionPointer(
                handle.AddrOfPinnedObject(), typeof(BinaryOp));
            var temp = action(3, 2); //6!
        }
        finally { handle.Free(); }
    }
}

Credit for this code goes to Mehrdad.

like image 813
Rob P. Avatar asked May 06 '11 20:05

Rob P.


2 Answers

It's basically creating a delegate from the native code for multiplication, and then invoking it. The byte arrays are the raw instructions, which are then pinned in memory, set to be executable, and then Marshal.GetDelegateForFunctionPointer is creating the delegate itself.

The conditional operator is to use different native code for x86 and x64. I suspect this would fail when running on Mono on an ARM processor, for example :)

like image 162
Jon Skeet Avatar answered Oct 01 '22 13:10

Jon Skeet


This code contains the binary of CPU instructions. It finds the address of the binary and executes it. Pretty awful except as a negative example or a joke.

like image 45
Jay Avatar answered Oct 01 '22 13:10

Jay