C# - FatalExecutionEngineError marshaling bye array to struct containing null terminated double byte string

0

I'm trying to convert the content of a byte[] read from a named pipe to a managed c# struct. The over the wire data is a series of 3 UInt32 followed by a null terminated double byte string.

Following many examples that I have seen online, I'm copying the content of the byte buffer to unmanaged memory, before using Marshal.PtrToStructure() to turn or cast the unmanaged memory pointer into a managed object. The call to Marshal.PtrToStructure() yields the following error:

Managed Debugging Assistant 'FatalExecutionEngineError' Message=Managed Debugging Assistant 'FatalExecutionEngineError' : 'The runtime has encountered a fatal error. The address of the error was at 0x7444c38a, on thread 0x25a4. The error code is 0xc0000005. This error may be a bug in the CLR or in the unsafe or non-verifiable portions of user code. Common sources of this bug include user marshaling errors for COM-interop or PInvoke, which may corrupt the stack.'

I've created a simple example that demonstrate the error:

using System;
using System.Runtime.InteropServices;

namespace MarshalingTest
{

    [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Unicode)]
    public struct CommandStruct
    {
        /* Message Header */ 
        public UInt32 signature;
        public UInt32 payloadSize;
        public UInt32 commandType;

        /* Payload */
        [MarshalAs(UnmanagedType.LPWStr)]
        public string payload;
    }

    class Program
    {
        private static byte[] RawData = new byte[] { 0x56, 0x50, 0x46, 0x47,  // 4 bytes Message Signature
                                                     0x0A, 0x00, 0x00, 0x00,  // 4 bytes Payload Size
                                                     0x40, 0x00, 0x00, 0x00,  // 4 bytes Command Type
                                                     // Null Terminated double byte string "Wall"
                                                     0x57, 0x00, 0x61, 0x00, 0x6C, 0x00, 0x6C, 0x00, 0x00, 0x00
        };

        static void Main(string[] args)
        {
            // Allocate unmanaged memory and copy the content of the RawData buffer to it
            int size = RawData.Length;
            IntPtr ptr = Marshal.AllocHGlobal(size);
            Marshal.Copy(RawData, 0, ptr, size);

            //Copy unmanaged object to managed object            
            CommandStruct obj = (CommandStruct)Marshal.PtrToStructure(ptr, typeof(CommandStruct));
            
            // Free the unmanaged memory
            Marshal.FreeHGlobal(ptr);

            Console.WriteLine("Signature: {0}", obj.signature);
            Console.WriteLine("Payload size: {0}", obj.payloadSize);
            Console.WriteLine("Command Type: {0}", obj.commandType);
            Console.WriteLine("Payload: {0}", obj.payload);
        }
    }
}

I've at a loss with this one. I've spent the past couple of days researching the issue and trying out different variations of the same code with no luck. I'll be grateful for any help I can get.

Thank you in advance,

T.

c#
.net
asked on Stack Overflow Jan 28, 2021 by CapTGO

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0