1 NTSTATUS
2 NTAPI
3 NtProtectVirtualMemory(IN HANDLE ProcessHandle,
4 IN OUT PVOID *UnsafeBaseAddress,
5 IN OUT SIZE_T *UnsafeNumberOfBytesToProtect,
6 IN ULONG NewAccessProtection,
7 OUT PULONG UnsafeOldAccessProtection)
8 {
9 PEPROCESS Process;
10 ULONG OldAccessProtection;
11 ULONG Protection;
12 PEPROCESS CurrentProcess = PsGetCurrentProcess();
13 PVOID BaseAddress = NULL;
14 SIZE_T NumberOfBytesToProtect = 0;
15 KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
16 NTSTATUS Status;
17 BOOLEAN Attached = FALSE;
18 KAPC_STATE ApcState;
19 PAGED_CODE();
20
21 //
22 // Check for valid protection flags
23 //
24 Protection = NewAccessProtection & ~(PAGE_GUARD|PAGE_NOCACHE);
25 if (Protection != PAGE_NOACCESS &&
26 Protection != PAGE_READONLY &&
27 Protection != PAGE_READWRITE &&
28 Protection != PAGE_WRITECOPY &&
29 Protection != PAGE_EXECUTE &&
30 Protection != PAGE_EXECUTE_READ &&
31 Protection != PAGE_EXECUTE_READWRITE &&
32 Protection != PAGE_EXECUTE_WRITECOPY)
33 {
34 //
35 // Fail
36 //
37 return STATUS_INVALID_PAGE_PROTECTION;
38 }
39
40 //
41 // Check if we came from user mode
42 //
43 if (PreviousMode != KernelMode)
44 {
45 //
46 // Enter SEH for probing
47 //
48 _SEH2_TRY
49 {
50 //
51 // Validate all outputs
52 //
53 ProbeForWritePointer(UnsafeBaseAddress);
54 ProbeForWriteSize_t(UnsafeNumberOfBytesToProtect);
55 ProbeForWriteUlong(UnsafeOldAccessProtection);
56
57 //
58 // Capture them
59 //
60 BaseAddress = *UnsafeBaseAddress;
61 NumberOfBytesToProtect = *UnsafeNumberOfBytesToProtect;
62 }
63 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
64 {
65 //
66 // Get exception code
67 //
68 _SEH2_YIELD(return _SEH2_GetExceptionCode());
69 }
70 _SEH2_END;
71 }
72 else
73 {
74 //
75 // Capture directly
76 //
77 BaseAddress = *UnsafeBaseAddress;
78 NumberOfBytesToProtect = *UnsafeNumberOfBytesToProtect;
79 }
80
81 //
82 // Catch illegal base address
83 //
84 if (BaseAddress > MM_HIGHEST_USER_ADDRESS) return STATUS_INVALID_PARAMETER_2;
85
86 //
87 // Catch illegal region size
88 //
89 if ((MmUserProbeAddress - (ULONG_PTR)BaseAddress) < NumberOfBytesToProtect)
90 {
91 //
92 // Fail
93 //
94 return STATUS_INVALID_PARAMETER_3;
95 }
96
97 //
98 // 0 is also illegal
99 //
100 if (!NumberOfBytesToProtect) return STATUS_INVALID_PARAMETER_3;
101
102 //
103 // Get a reference to the process
104 //
105 Status = ObReferenceObjectByHandle(ProcessHandle,
106 PROCESS_VM_OPERATION,
107 PsProcessType,
108 PreviousMode,
109 (PVOID*)(&Process),
110 NULL);
111 if (!NT_SUCCESS(Status)) return Status;
112
113 //
114 // Check if we should attach
115 //
116 if (CurrentProcess != Process)
117 {
118 //
119 // Do it
120 //
121 KeStackAttachProcess(&Process->Pcb, &ApcState);
122 Attached = TRUE;
123 }
124
125 //
126 // Do the actual work
127 //
128 Status = MiProtectVirtualMemory(Process,
129 &BaseAddress,
130 &NumberOfBytesToProtect,
131 NewAccessProtection,
132 &OldAccessProtection);
133
134 //
135 // Detach if needed
136 //
137 if (Attached) KeUnstackDetachProcess(&ApcState);
138
139 //
140 // Release reference
141 //
142 ObDereferenceObject(Process);
143
144 //
145 // Enter SEH to return data
146 //
147 _SEH2_TRY
148 {
149 //
150 // Return data to user
151 //
152 *UnsafeOldAccessProtection = OldAccessProtection;
153 *UnsafeBaseAddress = BaseAddress;
154 *UnsafeNumberOfBytesToProtect = NumberOfBytesToProtect;
155 }
156 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
157 {
158 }
159 _SEH2_END;
160
161 //
162 // Return status
163 //
164 return Status;
165 }
posted on 2011-03-23 10:01
shaker(太子) 阅读(6486)
评论(1) 编辑 收藏 引用 所属分类:
C++