forked from Evulpes/Remap-Memory-Region
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathProgram.cs
More file actions
130 lines (108 loc) · 4.75 KB
/
Program.cs
File metadata and controls
130 lines (108 loc) · 4.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
using System;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using static Remap_Memory_Region.NativeMethods.Winnt;
using static Remap_Memory_Region.NativeMethods.Winnt.AccessMask;
using static Remap_Memory_Region.NativeMethods.Winnt.MemoryAllocationType;
using static Remap_Memory_Region.NativeMethods.Winnt.MemoryProtectionConstraints;
using static Remap_Memory_Region.NativeMethods.Winnt.SectionProtectionConstraints;
namespace Remap_Memory_Region
{
class Program : NativeMethods
{
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);
}
static void NativeError(string nativeMethod)
{
int lastWin32Error = Marshal.GetLastWin32Error();
Console.Write($"{nativeMethod} failed. Last Error: {lastWin32Error}");
Environment.Exit(lastWin32Error);
}
}
}