I am translating a native C++ library to C#. The original function allocates some memory of the struct, doing some memory manipulation of the current process and return the manipulated bytes to a byte buffer inside the struct.
The struct is defined as follow:
typedef struct tdMEM_SCATTER_HEADER {
DWORD magic;
WORD version;
WORD Future1;
ULONG64 qwA;
DWORD cbMax;
DWORD cb;
PBYTE pb;
PVOID pvReserved1;
PVOID pvReserved2;
PVOID Future2[8];
} MEM_SCATTER_HEADER, *PMEM_SCATTER_HEADER, **PPMEM_SCATTER_HEADER;
The original function is defined as follow:
DWORD Scatter(_Inout_ PPMEM_SCATTER_HEADER ppMEMs, _In_ DWORD count);
and the allocating sequence is
pbBuffer = LocalAlloc(0, count * (sizeof(PMEM_SCATTER_HEADER) + sizeof(MEM_SCATTER_HEADER) + 0x1000));
ZeroMemory(pbBuffer, count * (sizeof(PMEM_SCATTER_HEADER) + sizeof(MEM_SCATTER_HEADER)));
for(i = 0; i < cMEMs; i++) {
pMEM->pb = pbData + ((QWORD)i << 12); // Allocating return bytes buffer.
}
Here is what I tried:
Struct marshalling:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct MEM_SCATTER_HEADER
{
public uint magic;
public ushort version;
public ushort Future1;
public ulong qwA;
public uint cbMax;
public uint cb;
[MarshalAs(UnmanagedType.ByValArray)]
public byte[] pb;
public IntPtr pvReserved1;
public IntPtr pvReserved2;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public IntPtr[] Future2;
}
Memory allocating:
MEM_SCATTER_HEADER[] header = new MEM_SCATTER_HEADER[count];
for (int i = 0; i < count; i++)
{
header[i].pb = new byte[0x1000];
Array.Clear(header[i].pb, 0, header[i].pb.Length); // Fill array with 0
}
DLLImport:
[DllImport("testC.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern uint Scatter(ref MEM_SCATTER_HEADER ppMems, uint count);
And finally function call:
uint count = Scatter(ref header, count);
I have a had time debugging wether I marshal data wrongly or wether I have to do some manual marshalling to get rid of the exception: "Attempted to read or write protected memory. This is often an indication that other memory is corrupt.'" at function call.
The initial allocation is not zeroing all the memory it's allocating, and it doesn't look right. It's as if the code were doing:
Might this matter?