1 #include "DriverTester.h" 2 3 static BOOL 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 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 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 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 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 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