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