Для любителей натива (часть 2) Игры с драйверами

Дата публикации 9 янв 2018 | Редактировалось 24 янв 2018
Cogitations poenam nemo patitur (лат.)
Никто не несет наказания за мысли
© sysenter 2004

JID: sysenter@jabber.no
Как продолжение 1 части

Динамический запуск и выгрузка драйвера, используя, естественно, только нативные технологии


Для начала получаем привилегии работы с дровами:
Код (C++):
  1. BOOL EnableLoadDriverPrivilege(BOOL fEnable)
  2. {
  3.    BOOL fOk = FALSE;
  4.    HANDLE hToken;
  5.    if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES,&hToken))
  6.    {
  7.       TOKEN_PRIVILEGES tp;
  8.       tp.PrivilegeCount = 1;
  9.       LookupPrivilegeValue(NULL, SE_LOAD_DRIVER_NAME, &tp.Privileges[0].Luid);
  10.       tp.Privileges[0].Attributes = fEnable ? SE_PRIVILEGE_ENABLED : 0;
  11.       AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL);
  12.       fOk = (GetLastError() == ERROR_SUCCESS);
  13.       CloseHandle(hToken);
  14.    }
  15.    return(fOk);
  16. }
Загрузка:
Код (C++):
  1. DWORD WINAPI LoadDriverX(LPVOID lpvParam)
  2. {
  3.         WCHAR* strI=(WCHAR*)lpvParam;
  4.         WCHAR regD[]=L"\\registry\\machine\\SYSTEM\\CurrentControlSet\\Services\\drivername";
  5.         UNICODE_STRING us;
  6.         WCHAR* drivn=wcsrchr(wcDriver,'\\')+1;
  7.         WCHAR* dot=wcsrchr(strI,'.');
  8.         WCHAR serv[MAX_PATH];
  9.         wcscpy(serv,drivn);
  10.         serv[dot-drivn]=0;
  11.         WCHAR regp[MAX_PATH*20]={0};
  12.         wcscpy(regp,regD);
  13.         RtlInitUnicodeString(&us,regp);
  14.         OBJECT_ATTRIBUTES OA;
  15.         UNICODE_STRING ValueName,nPath;
  16.         ULONG Disposition;
  17.         HANDLE KeyHandle;
  18.         RtlInitUnicodeString(&ValueName,regp);
  19.         InitializeObjectAttributes(&OA, &ValueName,OBJ_CASE_INSENSITIVE,NULL,NULL);
  20.         if(NT_SUCCESS(NtCreateKey(&KeyHandle,KEY_ALL_ACCESS,&OA,0,NULL,REG_OPTION_NON_VOLATILE,&Disposition )))
  21.         {
  22.             RtlInitUnicodeString(&ValueName,L"ImagePath");
  23.             RtlDosPathNameToNtPathName_U(strI,&nPath,NULL,NULL);
  24.             if(NT_SUCCESS(NtSetValueKey(KeyHandle,&ValueName,0,REG_EXPAND_SZ,nPath.Buffer,nPath.Length+sizeof(WCHAR))))
  25.             {
  26.                 RtlInitUnicodeString(&ValueName,L"Type");
  27.                 DWORD type=1;
  28.                 if(NT_SUCCESS(NtSetValueKey(KeyHandle,&ValueName,0,REG_DWORD,&type,sizeof(DWORD))))
  29.                 {
  30.                     NTSTATUS st;
  31.                     st=NtLoadDriver(&us);
  32.                     if(NT_SUCCESS(st))
  33.                     {
  34.                         return (DWORD)KeyHandle;
  35.                     }
  36.                     NtClose(KeyHandle);
  37.                     return NULL;
  38.                 }
  39.             }
  40.             NtClose(KeyHandle);
  41.         }
  42. return NULL;
  43. }
Динамическая выгрузка производится через NtUnloadDriver, смотря какое имя вы задали сервису, см выше. Там я поставил "drivername". Тут все вообще просто. Зная имя сервиса, можете попробовать выгрузить динамически любой другой драйвер. НО ― смотря как у драйвера устроен механизм выхода. Возможно приведет к BSOD, если в нем не завершились операции ввода-вывода или сделан через одно место :)
Код (C++):
  1. UNICODE_STRING us;
  2. RtlInitUnicodeString(&us,wcServiceName);
  3. NtUnloadDriver(&us);

2 3.154
RET

RET
Well-Known Member

Регистрация:
5 янв 2008
Публикаций:
17

Комментарии


      1. Fail 13 янв 2018
        А вообще нормальные статейки, пишите исчо. Только не стесняйтесь описывать подробнее:)
      2. Fail 13 янв 2018
        Я када в стародавние времена пейсал дрововый лодырь на нетиве, сразу запиливал функу копирования\удаления дровины в\из drivers. Ну тоесть что бы удобно было - дровина лежит хоть хде, лодырь сам все перемещения делает.