programing

C#에서 C/inline 어셈블리 사용

yellowcard 2023. 10. 22. 19:59
반응형

C#에서 C/inline 어셈블리 사용

C# 앱에서 인라인 asm (C++ 코드가 아님)과 혼합된 C 소스를 사용하는 방법이 있습니까?C# 앱과 함께 C/asm을 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#에서 '입력 데이터'를 전달한 다음 C# 프로그램에서 '출력 데이터'에 접근하는 것입니다.보통 우리는 그냥 네이티브 C#로 어셈블러 코드를 다시 쓰지만 프로토타입을 함께 구해야 하는 일정이 빠듯하기 때문에 기존 C/어셈블러 코드를 어떤 방식으로든 일시적으로 사용할 수 있다면 휠을 바로 재창조할 이유가 없습니다.

그것은 사실 매우 쉽고 심지어 반성조차 필요하지 않습니다.

        [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

나는 이것에 대한 블로그 포스트를 썼습니다: https://esozbek.me/inline-assembly-in-csharp-and-dotnet/

언급URL : https://stackoverflow.com/questions/18836120/using-c-inline-assembly-in-c-sharp

반응형