Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using C/inline assembly in C#

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.

like image 280
Tigress Avatar asked Sep 16 '13 19:09

Tigress


People also ask

Does C support inline assembly?

Inline assembly (typically introduced by the asm keyword) gives the ability to embed assembly language source code within a C program. Unlike in C++, inline assembly is treated as an extension in C.

What is asm () in C?

The asm keyword allows you to embed assembler instructions within C code. GCC provides two forms of inline asm statements. A basic asm statement is one with no operands (see Basic Asm), while an extended asm statement (see Extended Asm) includes one or more operands.

What is inline assembly example?

Example 1: The following example illustrates the usage of the volatile keyword. In this example, %0 refers to the first operand "+r"(lockval) , %1 refers to the second operand "+r"(returnvalue) , and %2 refers to the third operand "r"(lock) .


1 Answers

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/

like image 184
Enes Sadık Özbek Avatar answered Sep 21 '22 07:09

Enes Sadık Özbek