Using C/inline assembly in C#

37,402

It's actually very easy and does not even require reflection.

        [SuppressUnmanagedCodeSecurity]
        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
        private delegate int AssemblyAddFunction(int x, int y);

        [DllImport("kernel32.dll")]
        private static extern bool VirtualProtectEx(IntPtr hProcess, IntPtr lpAddress, UIntPtr dwSize, uint flNewProtect, out uint lpflOldProtect);

        ....................................

        byte[] assembledCode =
        {
            0x55,               // 0 push ebp            
            0x8B, 0x45, 0x08,   // 1 mov  eax, [ebp+8]   
            0x8B, 0x55, 0x0C,   // 4 mov  edx, [ebp+12]  
            0x01, 0xD0,         // 7 add  eax, edx       
            0x5D,               // 9 pop  ebp            
            0xC3                // A ret                 
        };

        int returnValue;
        unsafe
        {
            fixed (byte* ptr = assembledCode)
            {
                var memoryAddress = (IntPtr) ptr;

                // Mark memory as EXECUTE_READWRITE to prevent DEP exceptions
                if (!VirtualProtectEx(Process.GetCurrentProcess().Handle, memoryAddress,
                    (UIntPtr) assembledCode.Length, 0x40 /* EXECUTE_READWRITE */, out uint _))
                {
                    throw new Win32Exception();
                }

                var myAssemblyFunction = Marshal.GetDelegateForFunctionPointer<AssemblyAddFunction>(memoryAddress);
                returnValue = myAssemblyFunction(10, -15);
            }               
        }

        Console.WriteLine($"Return value: {returnValue}"); // Prints -5

I have written a blog post on this: https://esozbek.me/inline-assembly-in-csharp-and-dotnet/

Share:
37,402
Tigress
Author by

Tigress

Updated on December 03, 2020

Comments

  • Tigress
    Tigress over 3 years

    Is there some method of using C source mixed with inline asm (this is not C++ code) in a C# app? I'm not picky about how it gets done, if it requires compiling the C/asm into a DLL alongside the C# app, so be it. I'm aware there's no provision for using assembly inside C#, hence this question.

    Sample code of what I'm trying to incorporate:

    SomeFunc(unsigned char *outputData, unsigned char *inputData, unsigned long inputDataLength)
    {
        _asm
        {
            //Assembly code that processes inputData and stores result in outputData
        }
    }
    

    There are some pointer/variable declarations in the C code before that function is declared, but beyond that it's all inline assembly, the declarations are used in the assembly code if that effects anything.

    Objective is to pass 'inputData' from C# and then have access to 'outputData' in the C# program in some fashion. Normally we'd just rewrite the assembler code in native C# but we're on a tight schedule for getting a prototype together and don't see any reason to reinvent the wheel right away if we can temporarily use the existing C/assembly code in some fashion.