public static bool RemapMemoryRegion(IntPtr processHandle, IntPtr baseAddress, int regionSize, Winnt.MemoryProtectionConstraints mapProtection) { IntPtr addr = Memoryapi.VirtualAlloc(IntPtr.Zero, regionSize, Winnt.MemoryAllocationType.MEM_COMMIT | Winnt.MemoryAllocationType.MEM_RESERVE, mapProtection); if (addr == IntPtr.Zero) { return(false); } IntPtr copyBuf = Memoryapi.VirtualAlloc(IntPtr.Zero, regionSize, Winnt.MemoryAllocationType.MEM_COMMIT | Winnt.MemoryAllocationType.MEM_RESERVE, mapProtection); if (!Memoryapi.ReadProcessMemory(processHandle, baseAddress, copyBuf, regionSize, out IntPtr bytes)) { return(false); } IntPtr sectionHandle = default; long sectionMaxSize = regionSize; Ntifs.Ntstatus status = Ntifs.NtCreateSection(ref sectionHandle, Winnt.AccessMask.SECTION_ALL_ACCESS, IntPtr.Zero, ref sectionMaxSize, Winnt.MemoryProtectionConstraints.PAGE_EXECUTE_READWRITE, Winnt.SectionProtectionConstraints.SEC_COMMIT, IntPtr.Zero); if (status != Ntifs.Ntstatus.STATUS_SUCCESS) { return(false); } status = Ntapi.NtUnmapViewOfSection(processHandle, baseAddress); if (status != Ntifs.Ntstatus.STATUS_SUCCESS) { return(false); } IntPtr viewBase = baseAddress; long sectionOffset = default; uint viewSize = 0; status = Ntapi.NtMapViewOfSection ( sectionHandle, processHandle, ref viewBase, UIntPtr.Zero, regionSize, ref sectionOffset, ref viewSize, 2, 0, Winnt.MemoryProtectionConstraints.PAGE_EXECUTE_READWRITE ); if (status != Ntifs.Ntstatus.STATUS_SUCCESS) { return(false); } if (!Memoryapi.WriteProcessMemory(processHandle, viewBase, copyBuf, (int)viewSize, out bytes)) { return(false); } if (!Memoryapi.VirtualFree(copyBuf, 0, Winnt.MemFree.MEM_RELEASE)) { return(false); } return(true); }
static void Main(string[] args) { //Set this bool to true if the region data is not obscured. bool sectioned = true; Process targetProc = Process.GetProcessesByName("notepad").FirstOrDefault(); //Open a handle to the target process IntPtr hProcess = Processthreadsapi.OpenProcess(ProcessAccessFlags.PROCESS_ALL_ACCESS, false, targetProc.Id); if (hProcess == IntPtr.Zero) { NativeError("OpenProcess"); } IntPtr baseAddress; int regionSize; if (sectioned) { //Set the base module address and the size. baseAddress = targetProc.MainModule.BaseAddress; regionSize = targetProc.MainModule.ModuleMemorySize; } else { //Query the process and get the baseInfo structure. /*Very specific practice for very specifc apps. .NET has built in methods for standard apps. * See: Process Class Base Address + ModuleMemorySize*/ if (Memoryapi.VirtualQueryEx ( hProcess, targetProc.MainModule.BaseAddress, out MEMORY_BASIC_INFORMATION basicInfo, Marshal.SizeOf(typeof(MEMORY_BASIC_INFORMATION))) == 0 ) { NativeError("VirtualQueryEx"); } baseAddress = basicInfo.baseAddress; regionSize = (int)basicInfo.regionSize; } Ntpsapi.NtSuspendProcess(hProcess); //Allocate a buffer to read the region to. IntPtr buffer = Memoryapi.VirtualAlloc(IntPtr.Zero, regionSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); if (buffer == IntPtr.Zero) { NativeError("VirtualAlloc"); } //Read the data into the buffer. if (!Memoryapi.ReadProcessMemory(hProcess, baseAddress, buffer, regionSize, out _)) { NativeError("ReadProcessMemory"); } IntPtr hSection = IntPtr.Zero; long sectionMaxSize = (long)regionSize; //Create a section object to share between local and remote process. if (Ntifs.NtCreateSection ( ref hSection, SECTION_ALL_ACCESS, IntPtr.Zero, ref sectionMaxSize, PAGE_EXECUTE_READWRITE, SEC_COMMIT, IntPtr.Zero ) != Ntifs.Ntstatus.STATUS_SUCCESS) { NativeError("NtCreateSection"); } //Unmap the memory at the base of the remote process. if (Ntapi.NtUnmapViewOfSection(hProcess, baseAddress) != Ntifs.Ntstatus.STATUS_SUCCESS) { NativeError("NtUnmapViewOfSection"); } IntPtr viewBase = baseAddress; long sectionOffset = default; uint viewSize = default; //Map a region back to the original region location with new rights. if (Ntapi.NtMapViewOfSection ( hSection, hProcess, ref viewBase, UIntPtr.Zero, regionSize, ref sectionOffset, ref viewSize, 2 /*ViewUnmap*/, 0, PAGE_EXECUTE_READWRITE /*Set to the desired new access rights*/ ) != Ntifs.Ntstatus.STATUS_SUCCESS) { NativeError("NtMapViewOfSection"); } //Write the memory back to the updated region. if (!Memoryapi.WriteProcessMemory(hProcess, viewBase, buffer, (int)viewSize, out IntPtr _)) { NativeError("WriteProcessMemory"); } //Empty the buffer Memoryapi.VirtualFree(buffer, 0, MemFree.MEM_RELEASE); //Close the section handle Handleapi.CloseHandle(hSection); //Resume the process Ntpsapi.NtResumeProcess(hProcess); }