1*c2c66affSColin Finck #include "DriverTester.h"
2*c2c66affSColin Finck
3*c2c66affSColin Finck static BOOL
SetPrivilege(BOOL bSet)4*c2c66affSColin Finck SetPrivilege(BOOL bSet)
5*c2c66affSColin Finck {
6*c2c66affSColin Finck TOKEN_PRIVILEGES tp;
7*c2c66affSColin Finck HANDLE hToken;
8*c2c66affSColin Finck LUID luid;
9*c2c66affSColin Finck
10*c2c66affSColin Finck if (!OpenProcessToken(GetCurrentProcess(),
11*c2c66affSColin Finck TOKEN_ADJUST_PRIVILEGES,
12*c2c66affSColin Finck &hToken))
13*c2c66affSColin Finck {
14*c2c66affSColin Finck return FALSE;
15*c2c66affSColin Finck }
16*c2c66affSColin Finck
17*c2c66affSColin Finck if(!LookupPrivilegeValue(NULL,
18*c2c66affSColin Finck SE_LOAD_DRIVER_NAME,
19*c2c66affSColin Finck &luid))
20*c2c66affSColin Finck {
21*c2c66affSColin Finck CloseHandle(hToken);
22*c2c66affSColin Finck return FALSE;
23*c2c66affSColin Finck }
24*c2c66affSColin Finck
25*c2c66affSColin Finck tp.PrivilegeCount = 1;
26*c2c66affSColin Finck tp.Privileges[0].Luid = luid;
27*c2c66affSColin Finck
28*c2c66affSColin Finck if (bSet)
29*c2c66affSColin Finck {
30*c2c66affSColin Finck tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
31*c2c66affSColin Finck }
32*c2c66affSColin Finck else
33*c2c66affSColin Finck {
34*c2c66affSColin Finck tp.Privileges[0].Attributes = 0;
35*c2c66affSColin Finck }
36*c2c66affSColin Finck
37*c2c66affSColin Finck AdjustTokenPrivileges(hToken,
38*c2c66affSColin Finck FALSE,
39*c2c66affSColin Finck &tp,
40*c2c66affSColin Finck sizeof(TOKEN_PRIVILEGES),
41*c2c66affSColin Finck NULL,
42*c2c66affSColin Finck NULL);
43*c2c66affSColin Finck if (GetLastError() != ERROR_SUCCESS)
44*c2c66affSColin Finck {
45*c2c66affSColin Finck CloseHandle(hToken);
46*c2c66affSColin Finck return FALSE;
47*c2c66affSColin Finck }
48*c2c66affSColin Finck
49*c2c66affSColin Finck CloseHandle(hToken);
50*c2c66affSColin Finck
51*c2c66affSColin Finck return TRUE;
52*c2c66affSColin Finck }
53*c2c66affSColin Finck
54*c2c66affSColin Finck
55*c2c66affSColin Finck BOOL
ConvertPath(LPCWSTR lpPath,LPWSTR lpDevice)56*c2c66affSColin Finck ConvertPath(LPCWSTR lpPath,
57*c2c66affSColin Finck LPWSTR lpDevice)
58*c2c66affSColin Finck {
59*c2c66affSColin Finck LPWSTR lpFullPath = NULL;
60*c2c66affSColin Finck DWORD size;
61*c2c66affSColin Finck
62*c2c66affSColin Finck if (lpPath)
63*c2c66affSColin Finck {
64*c2c66affSColin Finck size = GetLongPathNameW(lpPath,
65*c2c66affSColin Finck 0,
66*c2c66affSColin Finck 0);
67*c2c66affSColin Finck if (!size)
68*c2c66affSColin Finck return FALSE;
69*c2c66affSColin Finck
70*c2c66affSColin Finck size = (size + 1) * sizeof(WCHAR);
71*c2c66affSColin Finck
72*c2c66affSColin Finck lpFullPath = HeapAlloc(GetProcessHeap(),
73*c2c66affSColin Finck 0,
74*c2c66affSColin Finck size);
75*c2c66affSColin Finck if (!lpFullPath)
76*c2c66affSColin Finck return FALSE;
77*c2c66affSColin Finck
78*c2c66affSColin Finck if (GetLongPathNameW(lpPath,
79*c2c66affSColin Finck lpFullPath,
80*c2c66affSColin Finck size))
81*c2c66affSColin Finck {
82*c2c66affSColin Finck HANDLE hDevice;
83*c2c66affSColin Finck POBJECT_NAME_INFORMATION pObjName;
84*c2c66affSColin Finck NTSTATUS Status;
85*c2c66affSColin Finck DWORD len;
86*c2c66affSColin Finck
87*c2c66affSColin Finck hDevice = CreateFileW(lpFullPath,
88*c2c66affSColin Finck GENERIC_READ | GENERIC_WRITE,
89*c2c66affSColin Finck 0,
90*c2c66affSColin Finck NULL,
91*c2c66affSColin Finck OPEN_EXISTING,
92*c2c66affSColin Finck FILE_ATTRIBUTE_NORMAL,
93*c2c66affSColin Finck NULL);
94*c2c66affSColin Finck
95*c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, lpFullPath);
96*c2c66affSColin Finck
97*c2c66affSColin Finck if(hDevice == INVALID_HANDLE_VALUE)
98*c2c66affSColin Finck {
99*c2c66affSColin Finck wprintf(L"[%x] Failed to open %s\n", GetLastError(), DRIVER_NAME);
100*c2c66affSColin Finck return FALSE;
101*c2c66affSColin Finck }
102*c2c66affSColin Finck
103*c2c66affSColin Finck size = MAX_PATH * sizeof(WCHAR);
104*c2c66affSColin Finck pObjName = HeapAlloc(GetProcessHeap(), 0, size);
105*c2c66affSColin Finck if (!pObjName)
106*c2c66affSColin Finck return FALSE;
107*c2c66affSColin Finck
108*c2c66affSColin Finck Status = NtQueryObject(hDevice,
109*c2c66affSColin Finck ObjectNameInformation,
110*c2c66affSColin Finck pObjName,
111*c2c66affSColin Finck size,
112*c2c66affSColin Finck &size);
113*c2c66affSColin Finck if (Status == STATUS_SUCCESS)
114*c2c66affSColin Finck {
115*c2c66affSColin Finck len = pObjName->Name.Length / sizeof(WCHAR);
116*c2c66affSColin Finck wcsncpy(lpDevice, pObjName->Name.Buffer, len);
117*c2c66affSColin Finck lpDevice[len] = UNICODE_NULL;
118*c2c66affSColin Finck
119*c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, pObjName);
120*c2c66affSColin Finck
121*c2c66affSColin Finck return TRUE;
122*c2c66affSColin Finck }
123*c2c66affSColin Finck
124*c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, pObjName);
125*c2c66affSColin Finck }
126*c2c66affSColin Finck }
127*c2c66affSColin Finck
128*c2c66affSColin Finck return FALSE;
129*c2c66affSColin Finck }
130*c2c66affSColin Finck
131*c2c66affSColin Finck
132*c2c66affSColin Finck BOOL
NtStartDriver(LPCWSTR lpService)133*c2c66affSColin Finck NtStartDriver(LPCWSTR lpService)
134*c2c66affSColin Finck {
135*c2c66affSColin Finck WCHAR szDriverPath[MAX_PATH];
136*c2c66affSColin Finck UNICODE_STRING DriverPath;
137*c2c66affSColin Finck NTSTATUS Status = -1;
138*c2c66affSColin Finck
139*c2c66affSColin Finck wcscpy(szDriverPath,
140*c2c66affSColin Finck L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
141*c2c66affSColin Finck wcscat(szDriverPath,
142*c2c66affSColin Finck lpService);
143*c2c66affSColin Finck
144*c2c66affSColin Finck RtlInitUnicodeString(&DriverPath,
145*c2c66affSColin Finck szDriverPath);
146*c2c66affSColin Finck
147*c2c66affSColin Finck if (SetPrivilege(TRUE))
148*c2c66affSColin Finck {
149*c2c66affSColin Finck Status = NtLoadDriver(&DriverPath);
150*c2c66affSColin Finck if (Status != STATUS_SUCCESS)
151*c2c66affSColin Finck {
152*c2c66affSColin Finck DWORD err = RtlNtStatusToDosError(Status);
153*c2c66affSColin Finck wprintf(L"NtUnloadDriver failed [%lu]\n", err);
154*c2c66affSColin Finck }
155*c2c66affSColin Finck
156*c2c66affSColin Finck SetPrivilege(FALSE);
157*c2c66affSColin Finck }
158*c2c66affSColin Finck
159*c2c66affSColin Finck return (Status == STATUS_SUCCESS);
160*c2c66affSColin Finck }
161*c2c66affSColin Finck
162*c2c66affSColin Finck
163*c2c66affSColin Finck BOOL
NtStopDriver(LPCWSTR lpService)164*c2c66affSColin Finck NtStopDriver(LPCWSTR lpService)
165*c2c66affSColin Finck {
166*c2c66affSColin Finck WCHAR szDriverPath[MAX_PATH];
167*c2c66affSColin Finck UNICODE_STRING DriverPath;
168*c2c66affSColin Finck NTSTATUS Status = -1;
169*c2c66affSColin Finck
170*c2c66affSColin Finck wcscpy(szDriverPath,
171*c2c66affSColin Finck L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
172*c2c66affSColin Finck wcscat(szDriverPath,
173*c2c66affSColin Finck lpService);
174*c2c66affSColin Finck
175*c2c66affSColin Finck RtlInitUnicodeString(&DriverPath,
176*c2c66affSColin Finck szDriverPath);
177*c2c66affSColin Finck
178*c2c66affSColin Finck if (SetPrivilege(TRUE))
179*c2c66affSColin Finck {
180*c2c66affSColin Finck Status = NtUnloadDriver(&DriverPath);
181*c2c66affSColin Finck if (Status != STATUS_SUCCESS)
182*c2c66affSColin Finck {
183*c2c66affSColin Finck DWORD err = RtlNtStatusToDosError(Status);
184*c2c66affSColin Finck wprintf(L"NtUnloadDriver failed [%lu]\n", err);
185*c2c66affSColin Finck }
186*c2c66affSColin Finck
187*c2c66affSColin Finck SetPrivilege(FALSE);
188*c2c66affSColin Finck }
189*c2c66affSColin Finck
190*c2c66affSColin Finck return (Status == STATUS_SUCCESS);
191*c2c66affSColin Finck }
192*c2c66affSColin Finck
193*c2c66affSColin Finck
194*c2c66affSColin Finck //
195*c2c66affSColin Finck // We shouldn't be able to call this from umode.
196*c2c66affSColin Finck // Returns true if
197*c2c66affSColin Finck //
198*c2c66affSColin Finck BOOL
LoadVia_SystemLoadGdiDriverInformation(LPWSTR lpDriverPath)199*c2c66affSColin Finck LoadVia_SystemLoadGdiDriverInformation(LPWSTR lpDriverPath)
200*c2c66affSColin Finck {
201*c2c66affSColin Finck NTSTATUS Status;
202*c2c66affSColin Finck SYSTEM_GDI_DRIVER_INFORMATION Buffer;
203*c2c66affSColin Finck DWORD bufSize;
204*c2c66affSColin Finck
205*c2c66affSColin Finck bufSize = sizeof(SYSTEM_GDI_DRIVER_INFORMATION);
206*c2c66affSColin Finck
207*c2c66affSColin Finck ZeroMemory(&Buffer, bufSize);
208*c2c66affSColin Finck RtlInitUnicodeString(&Buffer.DriverName, lpDriverPath);
209*c2c66affSColin Finck
210*c2c66affSColin Finck if (SetPrivilege(TRUE))
211*c2c66affSColin Finck {
212*c2c66affSColin Finck Status = NtSetSystemInformation(SystemLoadGdiDriverInformation,
213*c2c66affSColin Finck &Buffer,
214*c2c66affSColin Finck bufSize);
215*c2c66affSColin Finck if (Status == STATUS_PRIVILEGE_NOT_HELD)
216*c2c66affSColin Finck {
217*c2c66affSColin Finck wprintf(L"SystemLoadGdiDriverInformation can only be used in kmode.\n");
218*c2c66affSColin Finck }
219*c2c66affSColin Finck else if (Status == STATUS_SUCCESS)
220*c2c66affSColin Finck {
221*c2c66affSColin Finck wprintf(L"SystemLoadGdiDriverInformation incorrectly loaded the driver\n");
222*c2c66affSColin Finck NtUnloadDriver(&Buffer.DriverName);
223*c2c66affSColin Finck
224*c2c66affSColin Finck return TRUE;
225*c2c66affSColin Finck }
226*c2c66affSColin Finck else
227*c2c66affSColin Finck {
228*c2c66affSColin Finck DWORD err = RtlNtStatusToDosError(Status);
229*c2c66affSColin Finck wprintf(L"LoadVia_SystemLoadGdiDriverInformation failed [%lu]\n", err);
230*c2c66affSColin Finck }
231*c2c66affSColin Finck
232*c2c66affSColin Finck SetPrivilege(FALSE);
233*c2c66affSColin Finck }
234*c2c66affSColin Finck
235*c2c66affSColin Finck return FALSE;
236*c2c66affSColin Finck }
237*c2c66affSColin Finck
238*c2c66affSColin Finck
239*c2c66affSColin Finck BOOL
LoadVia_SystemExtendServiceTableInformation(LPWSTR lpDriverPath)240*c2c66affSColin Finck LoadVia_SystemExtendServiceTableInformation(LPWSTR lpDriverPath)
241*c2c66affSColin Finck {
242*c2c66affSColin Finck NTSTATUS Status;
243*c2c66affSColin Finck UNICODE_STRING Buffer;
244*c2c66affSColin Finck DWORD bufSize;
245*c2c66affSColin Finck
246*c2c66affSColin Finck RtlInitUnicodeString(&Buffer, lpDriverPath);
247*c2c66affSColin Finck bufSize = sizeof(UNICODE_STRING);
248*c2c66affSColin Finck
249*c2c66affSColin Finck if (SetPrivilege(TRUE))
250*c2c66affSColin Finck {
251*c2c66affSColin Finck Status = NtSetSystemInformation(SystemExtendServiceTableInformation,
252*c2c66affSColin Finck &Buffer,
253*c2c66affSColin Finck bufSize);
254*c2c66affSColin Finck if (Status == STATUS_PRIVILEGE_NOT_HELD)
255*c2c66affSColin Finck {
256*c2c66affSColin Finck wprintf(L"SystemExtendServiceTableInformation can only be used in kmode.\n");
257*c2c66affSColin Finck }
258*c2c66affSColin Finck else if (Status == STATUS_SUCCESS)
259*c2c66affSColin Finck {
260*c2c66affSColin Finck wprintf(L"SystemExtendServiceTableInformation incorrectly loaded the driver\n");
261*c2c66affSColin Finck NtUnloadDriver(&Buffer);
262*c2c66affSColin Finck
263*c2c66affSColin Finck return TRUE;
264*c2c66affSColin Finck }
265*c2c66affSColin Finck else
266*c2c66affSColin Finck {
267*c2c66affSColin Finck DWORD err = RtlNtStatusToDosError(Status);
268*c2c66affSColin Finck wprintf(L"LoadVia_SystemExtendServiceTableInformation failed [%lu] - 0x%x\n", err, Status);
269*c2c66affSColin Finck }
270*c2c66affSColin Finck
271*c2c66affSColin Finck SetPrivilege(FALSE);
272*c2c66affSColin Finck }
273*c2c66affSColin Finck
274*c2c66affSColin Finck return FALSE;
275*c2c66affSColin Finck }
276*c2c66affSColin Finck
277