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