在C#中使用C/内联汇编

vybvopom  于 9个月前  发布在  C#
关注(0)|答案(1)|浏览(119)

在C#应用程序中,是否有一些方法可以将C源代码与内联asm(这不是 * C++代码)混合使用?我对如何完成并不挑剔,如果它需要将C/asm编译成C#应用程序旁边的DLL,那就这样吧。我知道没有规定在C#中使用汇编,因此这个问题。
我尝试合并的示例代码:

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

字符串
在声明函数之前,C代码中有一些指针/变量声明,但除此之外,它都是内联汇编,如果有任何影响,则在汇编代码中使用声明。
目标是从C#传递'inputData',然后以某种方式访问C#程序中的'outputData'。通常我们只是用原生C#重写汇编代码,但我们的原型时间很紧,如果我们可以以某种方式暂时使用现有的C/汇编代码,我们没有理由立即重新发明轮子。

vjhs03f7

vjhs03f71#

这实际上非常简单,甚至不需要反思。

[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

字符串
我写了blog post on this

相关问题