Skip to content

Commit 70c9e1f

Browse files
krulcijs6pak
authored andcommitted
Implemented memory region protection validation
1 parent 45e22c2 commit 70c9e1f

1 file changed

Lines changed: 64 additions & 1 deletion

File tree

Il2CppInterop.Runtime/MemoryUtils.cs

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,37 @@
1-
using System.Diagnostics;
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Diagnostics;
24
using System.Linq;
5+
using System.Runtime.InteropServices;
6+
using Il2CppInterop.Common;
37
using Il2CppInterop.Common.XrefScans;
8+
using Microsoft.Extensions.Logging;
49

510
namespace Il2CppInterop.Runtime;
611

712
internal class MemoryUtils
813
{
14+
[DllImport("kernel32.dll", SetLastError = true)]
15+
internal static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [Out] byte[] lpBuffer, int dwSize, out IntPtr lpNumberOfBytesRead);
16+
17+
[DllImport("kernel32.dll", SetLastError = true)]
18+
internal static extern bool VirtualProtect(IntPtr lpAddress, uint dwSize, uint flNewProtect, out uint lpflOldProtect);
19+
20+
[DllImport("kernel32.dll", SetLastError = true)]
21+
internal static extern int VirtualQuery(IntPtr lpAddress, out MEMORY_BASIC_INFORMATION lpBuffer, uint dwLength);
22+
923
public static nint FindSignatureInModule(ProcessModule module, SignatureDefinition sigDef)
1024
{
25+
GetModuleRegions(module, out var protectedRegions);
26+
SetModuleRegions(protectedRegions, PAGE_EXECUTE_READWRITE);
1127
var ptr = FindSignatureInBlock(
1228
module.BaseAddress,
1329
module.ModuleMemorySize,
1430
sigDef.pattern,
1531
sigDef.mask,
1632
sigDef.offset
1733
);
34+
SetModuleRegions(protectedRegions);
1835
if (ptr != 0 && sigDef.xref)
1936
ptr = XrefScannerLowLevel.JumpTargets(ptr).FirstOrDefault();
2037
return ptr;
@@ -45,11 +62,57 @@ public static unsafe nint FindSignatureInBlock(nint block, long blockSize, char[
4562
return 0;
4663
}
4764

65+
public static void GetModuleRegions(ProcessModule module, out List<MEMORY_BASIC_INFORMATION> protectedRegions)
66+
{
67+
protectedRegions = [];
68+
IntPtr moduleEndAddress = (IntPtr)((long)module.BaseAddress + module.ModuleMemorySize);
69+
var currentAddress = module.BaseAddress;
70+
while (currentAddress.ToInt64() < moduleEndAddress.ToInt64())
71+
{
72+
var result = VirtualQuery(currentAddress, out var memoryInfo, (uint)Marshal.SizeOf(typeof(MEMORY_BASIC_INFORMATION)));
73+
if (result == 0)
74+
// Error occurred or reached the end of the module's memory space
75+
break;
76+
else
77+
protectedRegions.Add(memoryInfo);
78+
79+
// Move to the next memory region
80+
currentAddress = (IntPtr)((long)memoryInfo.BaseAddress + (long)memoryInfo.RegionSize);
81+
}
82+
}
83+
84+
public static void SetModuleRegions(List<MEMORY_BASIC_INFORMATION> protectedRegions, uint? newProtection = null)
85+
{
86+
foreach (var region in protectedRegions)
87+
{
88+
var result = VirtualProtect(region.BaseAddress, (uint)region.RegionSize, newProtection ?? region.Protect, out _);
89+
if (!result)
90+
{
91+
var error = Marshal.GetLastWin32Error();
92+
Logger.Instance.LogError("VirtualProtect failed with error code {error}", error);
93+
}
94+
}
95+
}
96+
97+
public const uint PAGE_EXECUTE_READWRITE = 0x40;
98+
4899
public struct SignatureDefinition
49100
{
50101
public string pattern;
51102
public string mask;
52103
public int offset;
53104
public bool xref;
54105
}
106+
107+
[StructLayout(LayoutKind.Sequential)]
108+
public struct MEMORY_BASIC_INFORMATION
109+
{
110+
public IntPtr BaseAddress;
111+
public IntPtr AllocationBase;
112+
public uint AllocationProtect;
113+
public IntPtr RegionSize;
114+
public uint State;
115+
public uint Protect;
116+
public uint Type;
117+
}
55118
}

0 commit comments

Comments
 (0)