Skip to content

Commit 3febd6a

Browse files
committed
WindowsPageAllocator: Fix allocation issues on macOS
On macOS (if using e.g. Crossover), VirtualQuery can report a memory address as free but still fail to reserve the memory with VirtualAlloc (fails with error code 0x170C240 for some reason). To fix this, memory is now reserved directly in the loop to ensure it can be reserved. If reservation fails, the next address is tried.
1 parent fbb8567 commit 3febd6a

File tree

1 file changed

+12
-5
lines changed

1 file changed

+12
-5
lines changed

BepInEx.IL2CPP/Hook/Allocator/WindowsPageAllocator.cs

+12-5
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ namespace BepInEx.IL2CPP.Hook.Allocator;
1212
internal class WindowsPageAllocator : PageAllocator
1313
{
1414
[MethodImpl(MethodImplOptions.AggressiveInlining)]
15-
private static nint RoundUp(nint num, nint unit) => (num + unit - 1) & ~ (unit - 1);
15+
private static nint RoundUp(nint num, nint unit) => (num + unit - 1) & ~(unit - 1);
1616

1717
private static Win32Exception Win32Error(string message = null, int code = -1)
1818
{
@@ -23,6 +23,7 @@ private static Win32Exception Win32Error(string message = null, int code = -1)
2323

2424
protected override nint AllocateChunk(nint hint)
2525
{
26+
nint chunk;
2627
while (true)
2728
{
2829
if (WinApi.VirtualQuery(hint, out var mbi) == 0)
@@ -38,7 +39,17 @@ protected override nint AllocateChunk(nint hint)
3839
var d = nextAddress - mbi.BaseAddress;
3940
if (d >= 0 && mbi.RegionSize - d >= ALLOCATION_UNIT)
4041
{
42+
Logger.Log(LogLevel.Debug, $"Found free chunk at 0x{(long) nextAddress:X8}");
4143
hint = nextAddress;
44+
45+
chunk = WinApi.VirtualAlloc(hint, ALLOCATION_UNIT, WinApi.AllocationType.MEM_RESERVE,
46+
WinApi.ProtectConstant.PAGE_NOACCESS);
47+
if (chunk == 0)
48+
{
49+
Logger.Log(LogLevel.Debug, $"Failed to reserve address: 0x{(long) hint:X8}: {Win32Error()}");
50+
goto next;
51+
}
52+
4253
break;
4354
}
4455
}
@@ -47,10 +58,6 @@ protected override nint AllocateChunk(nint hint)
4758
hint = mbi.BaseAddress + mbi.RegionSize;
4859
}
4960

50-
var chunk = WinApi.VirtualAlloc(hint, ALLOCATION_UNIT, WinApi.AllocationType.MEM_RESERVE,
51-
WinApi.ProtectConstant.PAGE_NOACCESS);
52-
if (chunk == 0)
53-
throw Win32Error($"Failed to reserve address: 0x{(long) hint:X8}");
5461
var addr = WinApi.VirtualAlloc(chunk, PAGE_SIZE, WinApi.AllocationType.MEM_COMMIT,
5562
WinApi.ProtectConstant.PAGE_READWRITE);
5663
if (addr == 0)

0 commit comments

Comments
 (0)