I'm working on an application that uses shared memory sections between processes on Windows (for an IPC mechanism between processes, where one process generates code that is executed by another process). On ARM64 Windows devices, the x64 shared memory, I believe, doesn't seem to be translated/emulated, causing crashes.
I've read that the MEM_EXTENDED_PARAMETER_EC_CODE flag exists (0x40) to mark memory regions as containing x64 code that requires emulation, I have tried to use this on NtMapViewOfSectionEx and this isn't being recognised as a valid parameter (0xC000000D).
HANDLE hSection;
LARGE_INTEGER sectionSize = {0x8000};
NtCreateSection(&hSection, SECTION_ALL_ACCESS, nullptr,
§ionSize, PAGE_EXECUTE_READWRITE, SEC_COMMIT, nullptr);
MEM_EXTENDED_PARAMETER extParam = {0};
extParam.Type = MemExtendedParameterAttributeFlags; // Value is 5
extParam.ULong64 = MEM_EXTENDED_PARAMETER_EC_CODE; // 0x40
PVOID baseAddress = nullptr;
LARGE_INTEGER sectionOffset = {0};
SIZE_T viewSize = 0x8000;
NTSTATUS status = NtMapViewOfSectionEx(
hSection,
targetProcess,
&baseAddress,
§ionOffset,
&viewSize,
0, // AllocationType
PAGE_EXECUTE_READWRITE,
&extParam,
1 // ExtendedParameterCount
);
The signature in use is:
typedef NTSTATUS(NTAPI* NtMapViewOfSectionEx)(HANDLE SectionHandle, HANDLE ProcessHandle, PVOID* BaseAddress, PLARGE_INTEGER SectionOffset, PSIZE_T ViewSize, ULONG AllocationType, ULONG Win32Protect, PMEM_EXTENDED_PARAMETER ExtendedParameters, ULONG ExtendedParameterCount);
Without the MEM_EXTENDED_PARAMETER_EC_CODE the mapping succeeded but fails on ARM64 Windows devices. I'm aware that VirtualAlloc2 should work, but it is against my use case.
NtMapViewOfSectionEx was tried with EC_CODE flag to mark it as x64 code. The result being 0xC000000D - the API doesn't accept EC_CODE? When using NtMapViewOfSectionEx without EC_CODE, it works. I'm unsure what is needed to make these sections translate.
I also attempted VirtualAlloc2 after mapping the memory, where we could mark the already-mapped memory as EC_CODE, however, this would break the shared memory by converting it to private (copy-on-write) memory.
I was expecting Windows to provide some way to mark section-backed memory with the EC_CODE flag, similar to how VirtualAlloc2 works.